Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
3d8c595
starting on turning capacitor ios into a swift package
theproducer Aug 10, 2026
1c748f1
Starting on converting Objective C files to Swift
theproducer Aug 10, 2026
fd83796
Remove CapacitorObjC and CapacitorC targets
theproducer Aug 17, 2026
35dae30
Move more CapacitorCordova sources under ios/Sources for SPM
theproducer Aug 17, 2026
78dd7d9
Move iOS test suite into ios/Tests for SPM, drop Xcode project
theproducer Aug 17, 2026
feec12f
add missing imports, resources, and podspec paths
theproducer Aug 17, 2026
19d9b26
Split CapacitorCordova into separate Cordova and CapacitorCordova SPM…
theproducer Aug 17, 2026
c2e09c8
Move Package.swift to repo root and add explicit target paths
theproducer Aug 17, 2026
90b4fae
Expose Cordova as a separate SPM library product
theproducer Aug 17, 2026
d51f9ea
updating cli to support new spm template
theproducer Aug 18, 2026
15955b8
Merge branch 'next' into feature/source-spm
theproducer Aug 18, 2026
7528a5f
Use Bundle.module for native-bridge.js when built via SPM
theproducer Aug 18, 2026
40abeed
Fix native-bridge.js lookup path for SPM builds
theproducer Aug 18, 2026
0f64694
Merge branch 'next' into feature/source-spm
theproducer Aug 18, 2026
ffb389e
Point SPM package dependency to next branch instead of feature/source…
theproducer Aug 19, 2026
6090548
fixing tests
theproducer Aug 19, 2026
5cbe5a8
fmt
theproducer Aug 19, 2026
9a3f9ff
Update native-bridge.js path for SPM directory layout
theproducer Aug 19, 2026
e00d310
Update swiftlint excluded paths for restructured iOS test dirs
theproducer Aug 20, 2026
3c3abb0
Rename class_ to classRef in UIStatusBarManager swizzle
theproducer Aug 20, 2026
ffb8fa9
Update iOS CI to macos-26-intel runner and Xcode 26.6
theproducer Aug 20, 2026
35c4b20
Update iOS simulator OS version to 26.5 in test script
theproducer Aug 20, 2026
5b02e3b
Switch iOS CI runner from macos-26-intel to macos-26
theproducer Aug 24, 2026
e6cf857
Remove unused Capacitor-Bridging-Header.h
theproducer Aug 25, 2026
c5f1d7d
Update source SPM branch reference from feature/source-spm to next
theproducer Aug 27, 2026
eff8a9e
Cache jsDateFormatter as a stored static property
theproducer Aug 27, 2026
36564ef
Fix notifyListeners to retain events when listener array is empty
theproducer Aug 27, 2026
253b7d3
fmt
theproducer Aug 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ cli/assets
dist
types
android/capacitor/src/main/assets/native-bridge.js
ios/Capacitor/Capacitor/assets/native-bridge.js
ios/Sources/Capacitor/assets/native-bridge.js
ios/Frameworks/Capacitor.xcframework/ios-arm64_x86_64-simulator/Capacitor.framework/native-bridge.js
ios/Frameworks/Capacitor.xcframework/ios-arm64/Capacitor.framework/native-bridge.js
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -89,15 +89,15 @@ jobs:
- run: npm test
working-directory: ./core
test-ios:
runs-on: macos-15
runs-on: macos-26
timeout-minutes: 30
needs:
- setup
- lint
strategy:
matrix:
xcode:
- /Applications/Xcode_26.0.app
- /Applications/Xcode_26.6.app
steps:
- run: sudo xcode-select --switch ${{ matrix.xcode }}
- run: xcrun simctl list > /dev/null
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Pods/
Podfile.lock
Build/*
build/
.build
Index/
.*.sw*
android-template.iml
Expand Down
2 changes: 1 addition & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ core/types
cli/assets
dist
android/capacitor/src/main/assets/native-bridge.js
ios/Capacitor/Capacitor/assets/native-bridge.js
ios/Sources/Capacitor/assets/native-bridge.js
ios/Frameworks/Capacitor.xcframework/ios-arm64_x86_64-simulator/Capacitor.framework/native-bridge.js
ios/Frameworks/Capacitor.xcframework/ios-arm64/Capacitor.framework/native-bridge.js
62 changes: 62 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// swift-tools-version: 6.3
import PackageDescription

let package = Package(
name: "Capacitor",
platforms: [.iOS(.v16)],
products: [
.library(
name: "Capacitor",
targets: ["Capacitor"]
),
.library(
name: "Cordova",
targets: ["Cordova"]
),
.library(
name: "CapacitorCordova",
targets: ["Cordova", "CapacitorCordova"]
)
],
targets: [
.target(
name: "Capacitor",
path: "ios/Sources/Capacitor",
resources: [.copy("assets")],
swiftSettings: [
.swiftLanguageMode(.v5)
],

),
.target(
name: "Cordova",
path: "ios/Sources/Cordova",
publicHeadersPath: "include",
cSettings: [
.headerSearchPath("include"),
],
linkerSettings: [
.linkedFramework("UIKit"),
.linkedFramework("WebKit"),
.linkedFramework("MobileCoreServices"),
.linkedFramework("CFNetwork")
]
),
.target(
name: "CapacitorCordova",
dependencies: ["Capacitor", "Cordova"],
path: "ios/Sources/CapacitorCordova",
),
.testTarget(
name: "CapacitorTests",
dependencies: [
"Capacitor"
],
path: "ios/Tests/CapacitorTests",
resources: [
.copy("Resources/configurations")
]
)
],
swiftLanguageModes: [.v5]
)
7 changes: 6 additions & 1 deletion cli/src/ios/update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,18 @@ async function updatePluginFiles(config: Config, plugins: Plugin[], deployment:
await Promise.all(
validSPMPackages.map(async (plugin) => {
const iosPlatformVersion = await getCapacitorPackageVersion(config, config.ios.name);
const majorCapVersion = major(iosPlatformVersion);
if (majorCapVersion >= 9) {
// Capacitor 9+ uses a branch-based dependency, so there's no version to reconcile.
return;
}

const packageSwiftPath = join(plugin.rootPath, 'Package.swift');
let content = await readFile(packageSwiftPath, { encoding: 'utf-8' });
const regex = new RegExp(
'url:\\s*"https://github.com/ionic-team/capacitor-swift-pm\\.git",\\s*from:\\s*"([^"]+)"',
);
const version = content.match(regex)?.[1];
const majorCapVersion = major(iosPlatformVersion);
if (version && major(version) != majorCapVersion) {
const preCapVersion = prerelease(iosPlatformVersion);
const forceVersion = preCapVersion ? iosPlatformVersion : `${majorCapVersion}.0.0`;
Expand Down
25 changes: 16 additions & 9 deletions cli/src/util/cordova-ios.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { copy, readFile, writeFile, remove } from 'fs-extra';
import { join } from 'path';
import { major } from 'semver';

import { getCapacitorPackageVersion } from '../common';
import { needsStaticPod } from '../cordova';
Expand Down Expand Up @@ -353,18 +354,24 @@ export async function generateCordovaPackageFile(p: Plugin, config: Config): Pro
publicHeadersPath: "."`;
}

const useSourceSPM = major(iosPlatformVersion) >= 9;
const capacitorPackageName = useSourceSPM ? 'capacitor' : 'capacitor-swift-pm';
const capacitorPackageUrl = useSourceSPM
? 'https://github.com/ionic-team/capacitor'
: 'https://github.com/ionic-team/capacitor-swift-pm.git';
const capacitorPackageVersionSuffix = useSourceSPM ? ` branch: "next"` : ` from: "${iosPlatformVersion}"`;

const platformTag = getPluginPlatform(p, platform);

if (platformTag.$?.package) {
const packageSwiftPath = join(p.rootPath, 'Package.swift');
let content = await readFile(packageSwiftPath, { encoding: 'utf-8' });
content = content.replace(`apache`, `ionic-team`).replaceAll(`cordova-ios`, `capacitor-swift-pm`);
content = setAllStringIn(
content,
`url: "https://github.com/ionic-team/capacitor-swift-pm.git",`,
`)`,
` from: "${iosPlatformVersion}"`,
);
content = content.replace(`apache`, `ionic-team`);
// The source repo is referenced as "cordova-ios.git" in URLs; source-SPM's package has no .git suffix.
content = useSourceSPM
? content.replaceAll(`cordova-ios.git`, capacitorPackageName).replaceAll(`cordova-ios`, capacitorPackageName)
: content.replaceAll(`cordova-ios`, capacitorPackageName);
content = setAllStringIn(content, `url: "${capacitorPackageUrl}",`, `)`, capacitorPackageVersionSuffix);
await writeFile(packageSwiftPath, content);
} else {
const content = `// swift-tools-version: 5.9
Expand All @@ -381,13 +388,13 @@ let package = Package(
)
],
dependencies: [
.package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", from: "${iosPlatformVersion}")
.package(url: "${capacitorPackageUrl}",${capacitorPackageVersionSuffix})
],
targets: [
.target(
name: "${p.name}",
dependencies: [
.product(name: "Cordova", package: "capacitor-swift-pm")
.product(name: "Cordova", package: "${capacitorPackageName}")
],
path: "."${headersText}
)
Expand Down
14 changes: 10 additions & 4 deletions cli/src/util/spm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { tmpdir } from 'os';
import { join, relative, resolve } from 'path';
import type { PlistObject } from 'plist';
import { build, parse } from 'plist';
import { major } from 'semver';
import { extract } from 'tar';

import { getCapacitorPackageVersion } from '../common';
Expand Down Expand Up @@ -105,7 +106,12 @@ export async function generatePackageText(config: Config, plugins: Plugin[]): Pr
const enableCordova = cordovaPlugins.length > 0;
const packageTraits = config.app.extConfig.experimental?.ios?.spm?.packageTraits ?? {};
const packageOptions = config.app.extConfig.experimental?.ios?.spm?.packageOptions ?? {};
const swiftToolsVersion = config.app.extConfig.experimental?.ios?.spm?.swiftToolsVersion ?? '5.9';
const swiftToolsVersion = config.app.extConfig.experimental?.ios?.spm?.swiftToolsVersion ?? '6.3';
const useSourceSPM = major(iosPlatformVersion) >= 9;
const capacitorPackageName = useSourceSPM ? 'capacitor' : 'capacitor-swift-pm';
const capacitorPackageDependency = useSourceSPM
? `.package(url: "https://github.com/ionic-team/capacitor", branch: "next")`
: `.package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", exact: "${iosPlatformVersion}")`;

let packageSwiftText = `// swift-tools-version: ${swiftToolsVersion}
import PackageDescription
Expand All @@ -120,7 +126,7 @@ let package = Package(
targets: ["CapApp-SPM"])
],
dependencies: [
.package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", exact: "${iosPlatformVersion}")`;
${capacitorPackageDependency}`;

for (const plugin of plugins) {
if (getPluginType(plugin, config.ios.name) === PluginType.Cordova) {
Expand Down Expand Up @@ -165,10 +171,10 @@ let package = Package(
.target(
name: "CapApp-SPM",
dependencies: [
.product(name: "Capacitor", package: "capacitor-swift-pm")`;
.product(name: "Capacitor", package: "${capacitorPackageName}")`;

if (enableCordova) {
packageSwiftText += `,\n .product(name: "Cordova", package: "capacitor-swift-pm")`;
packageSwiftText += `,\n .product(name: "Cordova", package: "${capacitorPackageName}")`;
}

for (const plugin of plugins) {
Expand Down
2 changes: 1 addition & 1 deletion core/rollup.bridge.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export default {
sourcemap: false,
},
{
file: '../ios/Capacitor/Capacitor/assets/native-bridge.js',
file: '../ios/Sources/Capacitor/assets/native-bridge.js',
format: 'iife',
name: 'nativeBridge',
preferConst: true,
Expand Down
8 changes: 4 additions & 4 deletions ios-spm-template/App/CapApp-SPM/Package.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// swift-tools-version: 5.9
// swift-tools-version: 6.3
import PackageDescription

// DO NOT MODIFY THIS FILE - managed by Capacitor CLI commands
Expand All @@ -11,14 +11,14 @@ let package = Package(
targets: ["CapApp-SPM"])
],
dependencies: [
.package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", from: "8.0.0")
.package(url: "https://github.com/ionic-team/capacitor", branch: "next")
],
targets: [
.target(
name: "CapApp-SPM",
dependencies: [
.product(name: "Capacitor", package: "capacitor-swift-pm"),
.product(name: "Cordova", package: "capacitor-swift-pm")
.product(name: "Capacitor", package: "capacitor"),
.product(name: "Cordova", package: "capacitor")
]
)
]
Expand Down
7 changes: 3 additions & 4 deletions ios/Capacitor.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@ Pod::Spec.new do |s|
s.ios.deployment_target = '16.0'
s.authors = { 'Ionic Team' => 'hi@ionicframework.com' }
s.source = { git: 'https://github.com/ionic-team/capacitor.git', tag: package['version'] }
s.source_files = "#{prefix}Capacitor/Capacitor/**/*.{swift,h,m}"
s.module_map = "#{prefix}Capacitor/Capacitor/Capacitor.modulemap"
s.resources = ["#{prefix}Capacitor/Capacitor/assets/native-bridge.js"]
s.resource_bundles = { 'Capacitor' => ["#{prefix}Capacitor/Capacitor/PrivacyInfo.xcprivacy"] }
s.source_files = "#{prefix}Sources/Capacitor/**/*.{swift,h,m}"
s.resources = ["#{prefix}Sources/Capacitor/assets/native-bridge.js"]
s.resource_bundles = { 'Capacitor' => ["#{prefix}Sources/Capacitor/PrivacyInfo.xcprivacy"] }
s.swift_version = '5.1'
end
Loading
Loading