diff --git a/.changeset/twenty-rabbits-admire.md b/.changeset/twenty-rabbits-admire.md new file mode 100644 index 00000000..89cc5dfb --- /dev/null +++ b/.changeset/twenty-rabbits-admire.md @@ -0,0 +1,5 @@ +--- +"@capacitor/background-runner": minor +--- + +iOS: Adding support for Swift Package Manager diff --git a/.github/workflows/reusable_unit-tests.yml b/.github/workflows/reusable_unit-tests.yml index d3c9236b..84326d82 100644 --- a/.github/workflows/reusable_unit-tests.yml +++ b/.github/workflows/reusable_unit-tests.yml @@ -15,12 +15,18 @@ jobs: with: fetch-depth: 0 token: ${{ secrets.CAP_GH_RELEASE_TOKEN || github.token }} + - name: Install PNPM + uses: pnpm/action-setup@v4 + id: pnpm-install + with: + version: 10 + run_install: false - name: List available Xcode versions run: ls /Applications | grep Xcode - - name: Select Xcode - run: sudo xcode-select -switch /Applications/Xcode_16.2.0.app && /usr/bin/xcodebuild -version - name: Run ios-engine unit tests - run: cd ./packages/ios-engine && swift package clean && swift test + run: | + cd ./packages/capacitor-plugin + pnpm run verify:ios unit-test-android: runs-on: macos-13 diff --git a/apps/example-app-spm/.gitignore b/apps/example-app-spm/.gitignore new file mode 100644 index 00000000..e36333d8 --- /dev/null +++ b/apps/example-app-spm/.gitignore @@ -0,0 +1,28 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# production +/build + +# misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local +.vscode +.idea + +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Optional eslint cache +.eslintcache diff --git a/apps/example-app-spm/CHANGELOG.md b/apps/example-app-spm/CHANGELOG.md new file mode 100644 index 00000000..607a2ab8 --- /dev/null +++ b/apps/example-app-spm/CHANGELOG.md @@ -0,0 +1,84 @@ +# Change Log + +## 1.0.9 + +### Patch Changes + +- Updated dependencies [2eda1d1] +- Updated dependencies [b76dbd4] +- Updated dependencies [a484f9f] +- Updated dependencies [ef998c1] +- Updated dependencies [8ef1ca0] + - @capacitor/background-runner@2.2.0 + +## 1.0.8 + +### Patch Changes + +- Updated dependencies [0e13e79] + - @capacitor/background-runner@2.1.0 + +## 1.0.7 + +### Patch Changes + +- Updated dependencies [4cc44dd] +- Updated dependencies [7adb608] +- Updated dependencies [36d9a61] +- Updated dependencies [4957271] +- Updated dependencies [3194a7d] + - @capacitor/background-runner@2.0.0 + +## 1.0.6 + +### Patch Changes + +- Updated dependencies [174f2fe] +- Updated dependencies [11124d2] +- Updated dependencies [142e96d] +- Updated dependencies [18f72b6] +- Updated dependencies [d6511b2] +- Updated dependencies [b09f30e] + - @capacitor/background-runner@1.1.0 + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [1.0.5](https://github.com/ionic-team/capacitor-background-runner/compare/1.0.4...1.0.5) (2023-08-17) + +**Note:** Version bump only for package example-app + +## [1.0.4](https://github.com/ionic-team/capacitor-background-runner/compare/1.0.3...1.0.4) (2023-08-10) + +**Note:** Version bump only for package example-app + +## [1.0.3](https://github.com/ionic-team/capacitor-background-runner/compare/1.0.2...1.0.3) (2023-08-10) + +**Note:** Version bump only for package example-app + +## [1.0.2](https://github.com/ionic-team/capacitor-background-runner/compare/1.0.1...1.0.2) (2023-08-10) + +**Note:** Version bump only for package example-app + +## [1.0.1](https://github.com/ionic-team/capacitor-background-runner/compare/1.0.0...1.0.1) (2023-08-09) + +### Bug Fixes + +- setting JavaVersion to 17 ([#14](https://github.com/ionic-team/capacitor-background-runner/issues/14)) ([5844d0c](https://github.com/ionic-team/capacitor-background-runner/commit/5844d0c814378b9c4ebafe752c297d7110e8c2ba)) +- Supporting post install script on Windows ([#12](https://github.com/ionic-team/capacitor-background-runner/issues/12)) ([75b4ed0](https://github.com/ionic-team/capacitor-background-runner/commit/75b4ed0cdb44c4caa506c9969b7fdbbe2e122779)) + +# 1.0.0 (2023-07-18) + +### Features + +- Android JS Engine / Plugin ([#6](https://github.com/ionic-team/enterprise-background-runner/issues/6)) ([1f52918](https://github.com/ionic-team/enterprise-background-runner/commit/1f52918784d91558a3e7798d5449887d7fb5cd32)) +- Capacitor Plugin ([#3](https://github.com/ionic-team/enterprise-background-runner/issues/3)) ([ffac505](https://github.com/ionic-team/enterprise-background-runner/commit/ffac505560c144d2478ed6de49dc7d0c5130b15c)) +- **iOS:** Adding Capacitor Web APIs ([#4](https://github.com/ionic-team/enterprise-background-runner/issues/4)) ([7daa335](https://github.com/ionic-team/enterprise-background-runner/commit/7daa3350335989e8caf20c7258074a6dfa5d2cfe)) + +# 1.0.0-rc.1 (2023-07-18) + +### Features + +- Android JS Engine / Plugin ([#6](https://github.com/ionic-team/capacitor-background-runner/issues/6)) ([1f52918](https://github.com/ionic-team/capacitor-background-runner/commit/1f52918784d91558a3e7798d5449887d7fb5cd32)) +- Capacitor Plugin ([#3](https://github.com/ionic-team/capacitor-background-runner/issues/3)) ([ffac505](https://github.com/ionic-team/capacitor-background-runner/commit/ffac505560c144d2478ed6de49dc7d0c5130b15c)) +- **iOS:** Adding Capacitor Web APIs ([#4](https://github.com/ionic-team/capacitor-background-runner/issues/4)) ([7daa335](https://github.com/ionic-team/capacitor-background-runner/commit/7daa3350335989e8caf20c7258074a6dfa5d2cfe)) diff --git a/apps/example-app-spm/capacitor.config.ts b/apps/example-app-spm/capacitor.config.ts new file mode 100644 index 00000000..c3a241aa --- /dev/null +++ b/apps/example-app-spm/capacitor.config.ts @@ -0,0 +1,22 @@ +/// + +import { CapacitorConfig } from "@capacitor/cli"; + +const config: CapacitorConfig = { + appId: "io.ionic.starter", + appName: "example-app", + webDir: "build", + bundledWebRuntime: false, + plugins: { + BackgroundRunner: { + label: "com.example.background.task", + src: "background.js", + event: "monitorLocation", + repeat: true, + interval: 2, + autoStart: false, + }, + }, +}; + +export default config; diff --git a/apps/example-app-spm/ionic.config.json b/apps/example-app-spm/ionic.config.json new file mode 100644 index 00000000..95507d29 --- /dev/null +++ b/apps/example-app-spm/ionic.config.json @@ -0,0 +1,7 @@ +{ + "name": "example-app", + "integrations": { + "capacitor": {} + }, + "type": "react" +} diff --git a/apps/example-app-spm/ios/.gitignore b/apps/example-app-spm/ios/.gitignore new file mode 100644 index 00000000..f4702997 --- /dev/null +++ b/apps/example-app-spm/ios/.gitignore @@ -0,0 +1,13 @@ +App/build +App/Pods +App/output +App/App/public +DerivedData +xcuserdata + +# Cordova plugins for Capacitor +capacitor-cordova-ios-plugins + +# Generated Config files +App/App/capacitor.config.json +App/App/config.xml diff --git a/apps/example-app-spm/ios/App/App.xcodeproj/project.pbxproj b/apps/example-app-spm/ios/App/App.xcodeproj/project.pbxproj new file mode 100644 index 00000000..1475d702 --- /dev/null +++ b/apps/example-app-spm/ios/App/App.xcodeproj/project.pbxproj @@ -0,0 +1,376 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 60; + objects = { + +/* Begin PBXBuildFile section */ + 2FAD9763203C412B000D30F8 /* config.xml in Resources */ = {isa = PBXBuildFile; fileRef = 2FAD9762203C412B000D30F8 /* config.xml */; }; + 4D22ABE92AF431CB00220026 /* CapApp-SPM in Frameworks */ = {isa = PBXBuildFile; productRef = 4D22ABE82AF431CB00220026 /* CapApp-SPM */; }; + 50379B232058CBB4000EE86E /* capacitor.config.json in Resources */ = {isa = PBXBuildFile; fileRef = 50379B222058CBB4000EE86E /* capacitor.config.json */; }; + 504EC3081FED79650016851F /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 504EC3071FED79650016851F /* AppDelegate.swift */; }; + 504EC30D1FED79650016851F /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 504EC30B1FED79650016851F /* Main.storyboard */; }; + 504EC30F1FED79650016851F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 504EC30E1FED79650016851F /* Assets.xcassets */; }; + 504EC3121FED79650016851F /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 504EC3101FED79650016851F /* LaunchScreen.storyboard */; }; + 50B271D11FEDC1A000F3C39B /* public in Resources */ = {isa = PBXBuildFile; fileRef = 50B271D01FEDC1A000F3C39B /* public */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 2FAD9762203C412B000D30F8 /* config.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = config.xml; sourceTree = ""; }; + 50379B222058CBB4000EE86E /* capacitor.config.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = capacitor.config.json; sourceTree = ""; }; + 504EC3041FED79650016851F /* App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = App.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 504EC3071FED79650016851F /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 504EC30C1FED79650016851F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 504EC30E1FED79650016851F /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 504EC3111FED79650016851F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 504EC3131FED79650016851F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 50B271D01FEDC1A000F3C39B /* public */ = {isa = PBXFileReference; lastKnownFileType = folder; path = public; sourceTree = ""; }; + 958DCC722DB07C7200EA8C5F /* debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = debug.xcconfig; path = ../debug.xcconfig; sourceTree = SOURCE_ROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 504EC3011FED79650016851F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4D22ABE92AF431CB00220026 /* CapApp-SPM in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 504EC2FB1FED79650016851F = { + isa = PBXGroup; + children = ( + 958DCC722DB07C7200EA8C5F /* debug.xcconfig */, + 504EC3061FED79650016851F /* App */, + 504EC3051FED79650016851F /* Products */, + ); + sourceTree = ""; + }; + 504EC3051FED79650016851F /* Products */ = { + isa = PBXGroup; + children = ( + 504EC3041FED79650016851F /* App.app */, + ); + name = Products; + sourceTree = ""; + }; + 504EC3061FED79650016851F /* App */ = { + isa = PBXGroup; + children = ( + 50379B222058CBB4000EE86E /* capacitor.config.json */, + 504EC3071FED79650016851F /* AppDelegate.swift */, + 504EC30B1FED79650016851F /* Main.storyboard */, + 504EC30E1FED79650016851F /* Assets.xcassets */, + 504EC3101FED79650016851F /* LaunchScreen.storyboard */, + 504EC3131FED79650016851F /* Info.plist */, + 2FAD9762203C412B000D30F8 /* config.xml */, + 50B271D01FEDC1A000F3C39B /* public */, + ); + path = App; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 504EC3031FED79650016851F /* App */ = { + isa = PBXNativeTarget; + buildConfigurationList = 504EC3161FED79650016851F /* Build configuration list for PBXNativeTarget "App" */; + buildPhases = ( + 504EC3001FED79650016851F /* Sources */, + 504EC3011FED79650016851F /* Frameworks */, + 504EC3021FED79650016851F /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = App; + packageProductDependencies = ( + 4D22ABE82AF431CB00220026 /* CapApp-SPM */, + ); + productName = App; + productReference = 504EC3041FED79650016851F /* App.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 504EC2FC1FED79650016851F /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0920; + LastUpgradeCheck = 0920; + TargetAttributes = { + 504EC3031FED79650016851F = { + CreatedOnToolsVersion = 9.2; + LastSwiftMigration = 1100; + ProvisioningStyle = Automatic; + }; + }; + }; + buildConfigurationList = 504EC2FF1FED79650016851F /* Build configuration list for PBXProject "App" */; + compatibilityVersion = "Xcode 8.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 504EC2FB1FED79650016851F; + packageReferences = ( + D4C12C0A2AAA248700AAC8A2 /* XCLocalSwiftPackageReference "CapApp-SPM" */, + ); + productRefGroup = 504EC3051FED79650016851F /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 504EC3031FED79650016851F /* App */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 504EC3021FED79650016851F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 504EC3121FED79650016851F /* LaunchScreen.storyboard in Resources */, + 50B271D11FEDC1A000F3C39B /* public in Resources */, + 504EC30F1FED79650016851F /* Assets.xcassets in Resources */, + 50379B232058CBB4000EE86E /* capacitor.config.json in Resources */, + 504EC30D1FED79650016851F /* Main.storyboard in Resources */, + 2FAD9763203C412B000D30F8 /* config.xml in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 504EC3001FED79650016851F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 504EC3081FED79650016851F /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 504EC30B1FED79650016851F /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 504EC30C1FED79650016851F /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 504EC3101FED79650016851F /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 504EC3111FED79650016851F /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 504EC3141FED79650016851F /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 958DCC722DB07C7200EA8C5F /* debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 504EC3151FED79650016851F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 504EC3171FED79650016851F /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 958DCC722DB07C7200EA8C5F /* debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + INFOPLIST_FILE = App/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\""; + PRODUCT_BUNDLE_IDENTIFIER = io.ionic.starter; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 504EC3181FED79650016851F /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + INFOPLIST_FILE = App/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = io.ionic.starter; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = ""; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 504EC2FF1FED79650016851F /* Build configuration list for PBXProject "App" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 504EC3141FED79650016851F /* Debug */, + 504EC3151FED79650016851F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 504EC3161FED79650016851F /* Build configuration list for PBXNativeTarget "App" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 504EC3171FED79650016851F /* Debug */, + 504EC3181FED79650016851F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + +/* Begin XCLocalSwiftPackageReference section */ + D4C12C0A2AAA248700AAC8A2 /* XCLocalSwiftPackageReference "CapApp-SPM" */ = { + isa = XCLocalSwiftPackageReference; + relativePath = "CapApp-SPM"; + }; +/* End XCLocalSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + 4D22ABE82AF431CB00220026 /* CapApp-SPM */ = { + isa = XCSwiftPackageProductDependency; + package = D4C12C0A2AAA248700AAC8A2 /* XCLocalSwiftPackageReference "CapApp-SPM" */; + productName = "CapApp-SPM"; + }; +/* End XCSwiftPackageProductDependency section */ + }; + rootObject = 504EC2FC1FED79650016851F /* Project object */; +} diff --git a/packages/capacitor-plugin/ios/Plugin.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/apps/example-app-spm/ios/App/App.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from packages/capacitor-plugin/ios/Plugin.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to apps/example-app-spm/ios/App/App.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/apps/example-app-spm/ios/App/App.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/apps/example-app-spm/ios/App/App.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 00000000..c57eae2a --- /dev/null +++ b/apps/example-app-spm/ios/App/App.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,15 @@ +{ + "originHash" : "cced83d6d979b4feabdde112bf90a587946dc5819231f7aa487539ce13becc3d", + "pins" : [ + { + "identity" : "capacitor-swift-pm", + "kind" : "remoteSourceControl", + "location" : "https://github.com/ionic-team/capacitor-swift-pm.git", + "state" : { + "revision" : "145cf37b8e3b240efef3d2d8a7262e621f08bb6f", + "version" : "7.4.4" + } + } + ], + "version" : 3 +} diff --git a/apps/example-app-spm/ios/App/App/AppDelegate.swift b/apps/example-app-spm/ios/App/App/AppDelegate.swift new file mode 100644 index 00000000..c3cd83b5 --- /dev/null +++ b/apps/example-app-spm/ios/App/App/AppDelegate.swift @@ -0,0 +1,49 @@ +import UIKit +import Capacitor + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillResignActive(_ application: UIApplication) { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. + } + + func applicationDidEnterBackground(_ application: UIApplication) { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + } + + func applicationWillEnterForeground(_ application: UIApplication) { + // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. + } + + func applicationDidBecomeActive(_ application: UIApplication) { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool { + // Called when the app was launched with a url. Feel free to add additional processing here, + // but if you want the App API to support tracking app url opens, make sure to keep this call + return ApplicationDelegateProxy.shared.application(app, open: url, options: options) + } + + func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool { + // Called when the app was launched with an activity, including Universal Links. + // Feel free to add additional processing here, but if you want the App API to support + // tracking app url opens, make sure to keep this call + return ApplicationDelegateProxy.shared.application(application, continue: userActivity, restorationHandler: restorationHandler) + } + +} diff --git a/apps/example-app-spm/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png b/apps/example-app-spm/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png new file mode 100644 index 00000000..adf6ba01 Binary files /dev/null and b/apps/example-app-spm/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png differ diff --git a/apps/example-app-spm/ios/App/App/Assets.xcassets/AppIcon.appiconset/Contents.json b/apps/example-app-spm/ios/App/App/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..9b7d382d --- /dev/null +++ b/apps/example-app-spm/ios/App/App/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,14 @@ +{ + "images" : [ + { + "filename" : "AppIcon-512@2x.png", + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/apps/example-app-spm/ios/App/App/Assets.xcassets/Contents.json b/apps/example-app-spm/ios/App/App/Assets.xcassets/Contents.json new file mode 100644 index 00000000..da4a164c --- /dev/null +++ b/apps/example-app-spm/ios/App/App/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/apps/example-app-spm/ios/App/App/Assets.xcassets/Splash.imageset/Contents.json b/apps/example-app-spm/ios/App/App/Assets.xcassets/Splash.imageset/Contents.json new file mode 100644 index 00000000..d7d96a67 --- /dev/null +++ b/apps/example-app-spm/ios/App/App/Assets.xcassets/Splash.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "splash-2732x2732-2.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "splash-2732x2732-1.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "splash-2732x2732.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/apps/example-app-spm/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-1.png b/apps/example-app-spm/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-1.png new file mode 100644 index 00000000..33ea6c97 Binary files /dev/null and b/apps/example-app-spm/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-1.png differ diff --git a/apps/example-app-spm/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-2.png b/apps/example-app-spm/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-2.png new file mode 100644 index 00000000..33ea6c97 Binary files /dev/null and b/apps/example-app-spm/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-2.png differ diff --git a/apps/example-app-spm/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732.png b/apps/example-app-spm/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732.png new file mode 100644 index 00000000..33ea6c97 Binary files /dev/null and b/apps/example-app-spm/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732.png differ diff --git a/apps/example-app-spm/ios/App/App/Base.lproj/LaunchScreen.storyboard b/apps/example-app-spm/ios/App/App/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..e7ae5d78 --- /dev/null +++ b/apps/example-app-spm/ios/App/App/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/example-app-spm/ios/App/App/Base.lproj/Main.storyboard b/apps/example-app-spm/ios/App/App/Base.lproj/Main.storyboard new file mode 100644 index 00000000..b44df7be --- /dev/null +++ b/apps/example-app-spm/ios/App/App/Base.lproj/Main.storyboard @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/apps/example-app-spm/ios/App/App/Info.plist b/apps/example-app-spm/ios/App/App/Info.plist new file mode 100644 index 00000000..2706c2dc --- /dev/null +++ b/apps/example-app-spm/ios/App/App/Info.plist @@ -0,0 +1,66 @@ + + + + + BGTaskSchedulerPermittedIdentifiers + + com.example.background.task + + CAPACITOR_DEBUG + $(CAPACITOR_DEBUG) + CFBundleDevelopmentRegion + en + CFBundleDisplayName + example-app + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + $(MARKETING_VERSION) + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + LSRequiresIPhoneOS + + NSLocationAlwaysAndWhenInUseUsageDescription + Access location while using the app and while in the background + NSLocationWhenInUseUsageDescription + Access location while app is in the foreground + UIBackgroundModes + + fetch + location + processing + remote-notification + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/apps/example-app-spm/ios/App/CapApp-SPM/.gitignore b/apps/example-app-spm/ios/App/CapApp-SPM/.gitignore new file mode 100644 index 00000000..3b298120 --- /dev/null +++ b/apps/example-app-spm/ios/App/CapApp-SPM/.gitignore @@ -0,0 +1,9 @@ +.DS_Store +/.build +/Packages +/*.xcodeproj +xcuserdata/ +DerivedData/ +.swiftpm/config/registries.json +.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata +.netrc diff --git a/apps/example-app-spm/ios/App/CapApp-SPM/Package.swift b/apps/example-app-spm/ios/App/CapApp-SPM/Package.swift new file mode 100644 index 00000000..95506a5e --- /dev/null +++ b/apps/example-app-spm/ios/App/CapApp-SPM/Package.swift @@ -0,0 +1,35 @@ +// swift-tools-version: 5.9 +import PackageDescription + +// DO NOT MODIFY THIS FILE - managed by Capacitor CLI commands +let package = Package( + name: "CapApp-SPM", + platforms: [.iOS(.v15)], + products: [ + .library( + name: "CapApp-SPM", + targets: ["CapApp-SPM"]) + ], + dependencies: [ + .package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", exact: "7.4.4"), + .package(name: "CapacitorApp", path: "../../../../../node_modules/.pnpm/@capacitor+app@7.1.0_@capacitor+core@7.4.4/node_modules/@capacitor/app"), + .package(name: "CapacitorBackgroundRunner", path: "../../../../../packages/capacitor-plugin"), + .package(name: "CapacitorHaptics", path: "../../../../../node_modules/.pnpm/@capacitor+haptics@7.0.2_@capacitor+core@7.4.4/node_modules/@capacitor/haptics"), + .package(name: "CapacitorKeyboard", path: "../../../../../node_modules/.pnpm/@capacitor+keyboard@7.0.3_@capacitor+core@7.4.4/node_modules/@capacitor/keyboard"), + .package(name: "CapacitorStatusBar", path: "../../../../../node_modules/.pnpm/@capacitor+status-bar@7.0.3_@capacitor+core@7.4.4/node_modules/@capacitor/status-bar") + ], + targets: [ + .target( + name: "CapApp-SPM", + dependencies: [ + .product(name: "Capacitor", package: "capacitor-swift-pm"), + .product(name: "Cordova", package: "capacitor-swift-pm"), + .product(name: "CapacitorApp", package: "CapacitorApp"), + .product(name: "CapacitorBackgroundRunner", package: "CapacitorBackgroundRunner"), + .product(name: "CapacitorHaptics", package: "CapacitorHaptics"), + .product(name: "CapacitorKeyboard", package: "CapacitorKeyboard"), + .product(name: "CapacitorStatusBar", package: "CapacitorStatusBar") + ] + ) + ] +) diff --git a/apps/example-app-spm/ios/App/CapApp-SPM/README.md b/apps/example-app-spm/ios/App/CapApp-SPM/README.md new file mode 100644 index 00000000..5e22a2f8 --- /dev/null +++ b/apps/example-app-spm/ios/App/CapApp-SPM/README.md @@ -0,0 +1,5 @@ +# CapApp-SPM + +This SPM is used to host SPM dependencies for you Capacitor project + +Do not modify the contents of it or there may be unintended consequences. diff --git a/apps/example-app-spm/ios/App/CapApp-SPM/Sources/CapApp-SPM/CapApp-SPM.swift b/apps/example-app-spm/ios/App/CapApp-SPM/Sources/CapApp-SPM/CapApp-SPM.swift new file mode 100644 index 00000000..945afec8 --- /dev/null +++ b/apps/example-app-spm/ios/App/CapApp-SPM/Sources/CapApp-SPM/CapApp-SPM.swift @@ -0,0 +1 @@ +public let isCapacitorApp = true diff --git a/apps/example-app-spm/ios/debug.xcconfig b/apps/example-app-spm/ios/debug.xcconfig new file mode 100644 index 00000000..53ce18de --- /dev/null +++ b/apps/example-app-spm/ios/debug.xcconfig @@ -0,0 +1 @@ +CAPACITOR_DEBUG = true diff --git a/apps/example-app-spm/package.json b/apps/example-app-spm/package.json new file mode 100644 index 00000000..7820a7f7 --- /dev/null +++ b/apps/example-app-spm/package.json @@ -0,0 +1,76 @@ +{ + "name": "example-app-spm", + "version": "1.0.9", + "private": true, + "dependencies": { + "@babel/plugin-syntax-flow": "^7.26.0", + "@babel/plugin-transform-react-jsx": "^7.25.9", + "@capacitor/app": "^7.1.0", + "@capacitor/background-runner": "workspace:^", + "@capacitor/core": "^7.4.4", + "@capacitor/haptics": "^7.0.2", + "@capacitor/ios": "^7.4.4", + "@capacitor/keyboard": "^7.0.3", + "@capacitor/status-bar": "^7.0.3", + "@ionic/react": "^6.7.5", + "@ionic/react-router": "^6.7.5", + "@testing-library/dom": "^9.3.4", + "@testing-library/jest-dom": "^5.17.0", + "@testing-library/react": "^11.2.7", + "@testing-library/user-event": "^12.8.3", + "@types/jest": "^26.0.24", + "@types/node": "^12.20.55", + "@types/react": "^16.14.62", + "@types/react-dom": "^16.9.25", + "@types/react-router": "^5.1.20", + "@types/react-router-dom": "^5.3.3", + "ionicons": "^5.5.4", + "react": "^17.0.2", + "react-dom": "^17.0.2", + "react-router": "^5.3.4", + "react-router-dom": "^5.3.4", + "react-scripts": "^5.0.1", + "typescript": "^4.9.5", + "web-vitals": "^0.2.4", + "workbox-background-sync": "^5.1.4", + "workbox-broadcast-update": "^5.1.4", + "workbox-cacheable-response": "^5.1.4", + "workbox-core": "^5.1.4", + "workbox-expiration": "^5.1.4", + "workbox-google-analytics": "^5.1.4", + "workbox-navigation-preload": "^5.1.4", + "workbox-precaching": "^5.1.4", + "workbox-range-requests": "^5.1.4", + "workbox-routing": "^5.1.4", + "workbox-strategies": "^5.1.4", + "workbox-streams": "^5.1.4" + }, + "scripts": { + "start": "react-scripts start", + "build": "react-scripts build && cp src/background.js build/background.js", + "test": "react-scripts test --transformIgnorePatterns 'node_modules/(?!(@ionic/react|@ionic/react-router|@ionic/core|@stencil/core|ionicons)/)'", + "eject": "react-scripts eject" + }, + "eslintConfig": { + "extends": [ + "react-app", + "react-app/jest" + ] + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + }, + "devDependencies": { + "@capacitor/cli": "^7.4.4" + }, + "description": "An Ionic project" +} diff --git a/apps/example-app-spm/public/assets/icon/favicon.png b/apps/example-app-spm/public/assets/icon/favicon.png new file mode 100644 index 00000000..51888a7b Binary files /dev/null and b/apps/example-app-spm/public/assets/icon/favicon.png differ diff --git a/apps/example-app-spm/public/assets/icon/icon.png b/apps/example-app-spm/public/assets/icon/icon.png new file mode 100644 index 00000000..a7f63748 Binary files /dev/null and b/apps/example-app-spm/public/assets/icon/icon.png differ diff --git a/apps/example-app-spm/public/assets/shapes.svg b/apps/example-app-spm/public/assets/shapes.svg new file mode 100644 index 00000000..d370b4dc --- /dev/null +++ b/apps/example-app-spm/public/assets/shapes.svg @@ -0,0 +1 @@ + diff --git a/apps/example-app-spm/public/index.html b/apps/example-app-spm/public/index.html new file mode 100644 index 00000000..25b753b0 --- /dev/null +++ b/apps/example-app-spm/public/index.html @@ -0,0 +1,31 @@ + + + + + Ionic App + + + + + + + + + + + + + + + + + + + +
+ + + diff --git a/apps/example-app-spm/public/manifest.json b/apps/example-app-spm/public/manifest.json new file mode 100644 index 00000000..58087054 --- /dev/null +++ b/apps/example-app-spm/public/manifest.json @@ -0,0 +1,21 @@ +{ + "short_name": "Ionic App", + "name": "My Ionic App", + "icons": [ + { + "src": "assets/icon/favicon.png", + "sizes": "64x64 32x32 24x24 16x16", + "type": "image/x-icon" + }, + { + "src": "assets/icon/icon.png", + "type": "image/png", + "sizes": "512x512", + "purpose": "maskable" + } + ], + "start_url": ".", + "display": "standalone", + "theme_color": "#ffffff", + "background_color": "#ffffff" +} diff --git a/apps/example-app-spm/scripts/send_apn.sh b/apps/example-app-spm/scripts/send_apn.sh new file mode 100755 index 00000000..0ec0316a --- /dev/null +++ b/apps/example-app-spm/scripts/send_apn.sh @@ -0,0 +1,17 @@ +TEAM_ID=9YN2HU59K8 +TOKEN_KEY_FILE_NAME=/Users/jpender/Downloads/AuthKey_U939TFQ2G4.p8 +AUTH_KEY_ID=U939TFQ2G4 +TOPIC=io.ionic.backgroundrunner.example +DEVICE_TOKEN=c04b70d63712aebd7e6c6d96e5e820cff9c9671d72b0ba04ccc03ba8790cf025 +APNS_HOST_NAME=api.sandbox.push.apple.com + +openssl s_client -connect "${APNS_HOST_NAME}":443 + +JWT_ISSUE_TIME=$(date +%s) +JWT_HEADER=$(printf '{ "alg": "ES256", "kid": "%s" }' "${AUTH_KEY_ID}" | openssl base64 -e -A | tr -- '+/' '-_' | tr -d =) +JWT_CLAIMS=$(printf '{ "iss": "%s", "iat": %d }' "${TEAM_ID}" "${JWT_ISSUE_TIME}" | openssl base64 -e -A | tr -- '+/' '-_' | tr -d =) +JWT_HEADER_CLAIMS="${JWT_HEADER}.${JWT_CLAIMS}" +JWT_SIGNED_HEADER_CLAIMS=$(printf "${JWT_HEADER_CLAIMS}" | openssl dgst -binary -sha256 -sign "${TOKEN_KEY_FILE_NAME}" | openssl base64 -e -A | tr -- '+/' '-_' | tr -d =) +AUTHENTICATION_TOKEN="${JWT_HEADER}.${JWT_CLAIMS}.${JWT_SIGNED_HEADER_CLAIMS}" + +curl -v --header "apns-topic: $TOPIC" --header "apns-push-type: background" --header "apns-priority: 5" --header "authorization: bearer $AUTHENTICATION_TOKEN" --data '{"aps":{"content-available":1},"acme1":"bar","acme2":42}' --http2 https://${APNS_HOST_NAME}/3/device/${DEVICE_TOKEN} diff --git a/apps/example-app-spm/src/App.test.tsx b/apps/example-app-spm/src/App.test.tsx new file mode 100644 index 00000000..8c927a8d --- /dev/null +++ b/apps/example-app-spm/src/App.test.tsx @@ -0,0 +1,8 @@ +import React from 'react'; +import { render } from '@testing-library/react'; +import App from './App'; + +test('renders without crashing', () => { + const { baseElement } = render(); + expect(baseElement).toBeDefined(); +}); diff --git a/apps/example-app-spm/src/App.tsx b/apps/example-app-spm/src/App.tsx new file mode 100644 index 00000000..8a0ffb05 --- /dev/null +++ b/apps/example-app-spm/src/App.tsx @@ -0,0 +1,76 @@ +import { Redirect, Route } from 'react-router-dom'; +import { + IonApp, + IonIcon, + IonLabel, + IonRouterOutlet, + IonTabBar, + IonTabButton, + IonTabs, + setupIonicReact +} from '@ionic/react'; +import { IonReactRouter } from '@ionic/react-router'; +import { ellipse, square, triangle } from 'ionicons/icons'; +import Tab1 from './pages/Tab1'; +import Tab2 from './pages/Tab2'; +import Tab3 from './pages/Tab3'; + +/* Core CSS required for Ionic components to work properly */ +import '@ionic/react/css/core.css'; + +/* Basic CSS for apps built with Ionic */ +import '@ionic/react/css/normalize.css'; +import '@ionic/react/css/structure.css'; +import '@ionic/react/css/typography.css'; + +/* Optional CSS utils that can be commented out */ +import '@ionic/react/css/padding.css'; +import '@ionic/react/css/float-elements.css'; +import '@ionic/react/css/text-alignment.css'; +import '@ionic/react/css/text-transformation.css'; +import '@ionic/react/css/flex-utils.css'; +import '@ionic/react/css/display.css'; + +/* Theme variables */ +import './theme/variables.css'; + +setupIonicReact(); + +const App: React.FC = () => ( + + + + + + + + + + + + + + + + + + + + + Cap APIs + + + + Core + + + + Wearable + + + + + +); + +export default App; diff --git a/apps/example-app-spm/src/background.js b/apps/example-app-spm/src/background.js new file mode 100644 index 00000000..0c7df9fd --- /dev/null +++ b/apps/example-app-spm/src/background.js @@ -0,0 +1,308 @@ +// basic functionality + +addEventListener("syncTest", (resolve, reject, args) => { + console.log("calling sync test"); + setTimeout(() => { + console.log("tick"); + resolve(); + }, 3000); +}); + +addEventListener("asyncTest", async (resolve, reject, args) => { + console.log("calling async test"); + await new Promise((res) => { + setTimeout(() => { + console.log("tick"); + res(); + }, 3000); + }); + console.log("returning async result"); + resolve(); +}); + +addEventListener("argsTest", async (resolve, reject, args) => { + try { + console.log("accepted these args: " + JSON.stringify(args)); + const updatedUser = args.user; + updatedUser.firstName = updatedUser.firstName + " HELLO"; + updatedUser.lastName = updatedUser.lastName + " WORLD"; + + resolve(updatedUser); + } catch (err) { + console.error(err); + reject(err); + } +}); + +addEventListener("errorTest", async (resolve, reject, args) => { + try { + const undefinedObject = args.myUndefinedObject; + undefinedObject.fakeFunc(); + } catch (err) { + console.error(err); + reject(err); + } +}); + +addEventListener("fetchTest", async (resolve, reject, args) => { + try { + const res = await fetch("https://jsonplaceholder.typicode.com/todos/1"); + + if (!res.ok) { + throw new Error("Fetch GET request failed"); + } + + const todo = await res.json(); + resolve(todo); + } catch (err) { + console.error(err); + reject(err); + } +}); + +// capacitor APIs +addEventListener("testCapKVSet", async (resolve, reject, args) => { + try { + CapacitorKV.set("testValue", args.value); + resolve(); + } catch (err) { + console.error(err); + reject(err); + } +}); + +addEventListener("testCapKVGet", async (resolve, reject, args) => { + try { + const result = CapacitorKV.get("testValue"); + console.log(result); + console.log(JSON.stringify(result)); + resolve(result); + } catch (err) { + console.error(err); + reject(err); + } +}); + +addEventListener("testCapKVRemove", async (resolve, reject, args) => { + try { + CapacitorKV.remove("testValue"); + resolve(); + } catch (err) { + console.error(err); + reject(err); + } +}); + +addEventListener("testCapNotification", async (resolve, reject, args) => { + try { + let scheduleDate = new Date(); + scheduleDate.setSeconds(scheduleDate.getSeconds() + 60); + + CapacitorNotifications.schedule([ + { + id: 100, + title: "Enterprise Background Runner", + body: "A test message from the Enterprise Background Runner", + scheduleAt: scheduleDate, + }, + ]); + + resolve(); + } catch (err) { + console.error(err); + reject(err); + } +}); + +addEventListener("testCapacitorGeolocation", async (resolve, reject, args) => { + try { + const location = await CapacitorGeolocation.getCurrentPosition(); + console.log("current location: " + JSON.stringify(location)); + resolve(location); + } catch (err) { + console.error(err); + reject(err); + } +}); + +addEventListener( + "testCapacitorDeviceBatteryStatus", + (resolve, reject, args) => { + try { + const info = CapacitorDevice.getBatteryStatus(); + console.log(JSON.stringify(info)); + resolve(info); + } catch (err) { + console.error(err); + reject(err); + } + } +); + +addEventListener( + "testCapacitorDeviceNetworkStatus", + (resolve, reject, args) => { + try { + const info = CapacitorDevice.getNetworkStatus(); + console.log(JSON.stringify(info)); + resolve(info); + } catch (err) { + console.error(err); + reject(err); + } + } +); + +addEventListener("testCapacitorAppGetBadge", (resolve, reject, args) => { + try { + const value = CapacitorNotifications.getBadge(); + console.log(JSON.stringify(value)); + resolve(value); + } catch (err) { + console.error(err); + reject(err); + } +}); + +addEventListener("testCapacitorAppSetBadge", (resolve, reject, args) => { + try { + CapacitorNotifications.setBadge({ + count: 55, + notificationTitle: "You have new messages", + notificationSubtitle: "testing, testing, 1, 2, 3", + }); + resolve(); + } catch (err) { + console.error(err); + reject(err); + } +}); + +addEventListener("testCapacitorAppClearBadge", (resolve, reject, args) => { + try { + CapacitorNotifications.clearBadge(); + resolve(); + } catch (err) { + console.error(err); + reject(err); + } +}); + +addEventListener("testCapacitorAppGetInfo", (resolve, reject, args) => { + try { + const info = CapacitorApp.getInfo(); + console.log(JSON.stringify(info)); + resolve(info); + } catch (err) { + console.error(err); + reject(err); + } +}); + +addEventListener("testCapacitorAppGetState", (resolve, reject, args) => { + try { + const state = CapacitorApp.getState(); + console.log(JSON.stringify(state)); + resolve(state); + } catch (err) { + console.error(err); + reject(err); + } +}); + +addEventListener("remoteNotification", (resolve, reject, args) => { + console.log("received silent push notification"); + + CapacitorNotifications.schedule([ + { + id: 1000, + title: "Enterprise Background Runner", + body: "Received silent push notification", + }, + ]); + + console.log(`details: ${JSON.stringify(args)}`); + + resolve(); +}); + +addEventListener("checkWatchReachability", (resolve, reject, args) => { + const reachable = CapacitorWatch.isReachable(); + try { + resolve({ + reachable: reachable, + }); + } catch (err) { + console.error(err); + reject(err); + } +}); + +addEventListener("sendMessageToWatch", (resolve, reject, args) => { + console.log("sending message to watch..."); + + CapacitorWatch.send({ + msg: "Hello World", + }); + + try { + resolve(); + } catch (err) { + console.error(err); + reject(err); + } +}); + +addEventListener( + "WatchConnectivity_activationDidCompleteWith", + (resolve, reject, args) => { + console.log("watch paired completed"); + resolve(); + } +); + +addEventListener( + "WatchConnectivity_sessionDidBecomeInactive", + (resolve, reject, args) => { + console.log("watch session is inactive"); + resolve(); + } +); + +addEventListener( + "WatchConnectivity_sessionDidDeactivate", + (resolve, reject, args) => { + console.log("watch session is deactivated"); + resolve(); + } +); + +addEventListener( + "WatchConnectivity_didReceiveUserInfo", + (resolve, reject, args) => { + console.log(`watch sent user info: ${JSON.stringify(args)}`); + resolve(); + } +); + +addEventListener( + "WatchConnectivity_didReceiveMessage", + (resolve, reject, args) => { + try { + const msg = args.message.result; + + CapacitorNotifications.schedule([ + { + title: "Enterprise Background Runner", + body: msg, + }, + ]); + + console.log(`watch sent data: ${JSON.stringify(args)}`); + resolve(); + } catch (err) { + console.error(err); + reject(err); + } + } +); diff --git a/apps/example-app-spm/src/index.tsx b/apps/example-app-spm/src/index.tsx new file mode 100644 index 00000000..c421f457 --- /dev/null +++ b/apps/example-app-spm/src/index.tsx @@ -0,0 +1,22 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import App from './App'; +import * as serviceWorkerRegistration from './serviceWorkerRegistration'; +import reportWebVitals from './reportWebVitals'; + +ReactDOM.render( + + + , + document.getElementById('root') +); + +// If you want your app to work offline and load faster, you can change +// unregister() to register() below. Note this comes with some pitfalls. +// Learn more about service workers: https://cra.link/PWA +serviceWorkerRegistration.unregister(); + +// If you want to start measuring performance in your app, pass a function +// to log results (for example: reportWebVitals(console.log)) +// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals +reportWebVitals(); diff --git a/apps/example-app-spm/src/pages/Tab1.css b/apps/example-app-spm/src/pages/Tab1.css new file mode 100644 index 00000000..e69de29b diff --git a/apps/example-app-spm/src/pages/Tab1.tsx b/apps/example-app-spm/src/pages/Tab1.tsx new file mode 100644 index 00000000..bb006264 --- /dev/null +++ b/apps/example-app-spm/src/pages/Tab1.tsx @@ -0,0 +1,267 @@ +import { useState } from "react"; +import { + IonButton, + IonContent, + IonHeader, + IonPage, + IonTextarea, + IonTitle, + IonToolbar, +} from "@ionic/react"; +import { BackgroundRunner } from "@capacitor/background-runner"; +import "./Tab1.css"; + +const Tab1: React.FC = () => { + const [commandOutput, setCommandOutput] = useState(""); + + const onCheckPermissions = async () => { + setCommandOutput(""); + try { + const permissions = await BackgroundRunner.checkPermissions(); + setCommandOutput(`permissions: ${JSON.stringify(permissions)}`); + } catch (err) { + setCommandOutput(`ERROR: ${err}`); + } + }; + + const onRequestPermissions = async () => { + setCommandOutput(""); + try { + const permissions = await BackgroundRunner.requestPermissions({ + apis: ["geolocation", "notifications"], + }); + setCommandOutput(`permissions: ${JSON.stringify(permissions)}`); + } catch (err) { + setCommandOutput(`ERROR: ${err}`); + } + }; + + const onTestCapKVSet = async () => { + setCommandOutput(""); + try { + await BackgroundRunner.dispatchEvent({ + label: "com.example.background.task", + event: "testCapKVSet", + details: { + value: "Hello World", + }, + }); + setCommandOutput(`success: stored value 'Hello World'`); + } catch (err) { + setCommandOutput(`ERROR: ${err}`); + } + }; + + const onTestCapKVGet = async () => { + setCommandOutput(""); + try { + const response = await BackgroundRunner.dispatchEvent({ + label: "com.example.background.task", + event: "testCapKVGet", + details: {}, + }); + setCommandOutput(`success: retrieved ${JSON.stringify(response)}`); + } catch (err) { + setCommandOutput(`ERROR: ${err}`); + } + }; + + const onTestCapKVRemove = async () => { + setCommandOutput(""); + try { + await BackgroundRunner.dispatchEvent({ + label: "com.example.background.task", + event: "testCapKVRemove", + details: {}, + }); + setCommandOutput(`success: value removed`); + } catch (err) { + setCommandOutput(`ERROR: ${err}`); + } + }; + + const onTestCapNotification = async () => { + setCommandOutput(""); + try { + await BackgroundRunner.dispatchEvent({ + label: "com.example.background.task", + event: "testCapNotification", + details: {}, + }); + setCommandOutput(`success: notification scheduled`); + } catch (err) { + setCommandOutput(`ERROR: ${err}`); + } + }; + + const onTestCapLocation = async () => { + setCommandOutput(""); + try { + const response = await BackgroundRunner.dispatchEvent({ + label: "com.example.background.task", + event: "testCapacitorGeolocation", + details: {}, + }); + setCommandOutput(`success: ${JSON.stringify(response)}`); + } catch (err) { + setCommandOutput(`ERROR: ${err}`); + } + }; + + const onTestCapDeviceBattery = async () => { + setCommandOutput(""); + try { + const response = await BackgroundRunner.dispatchEvent({ + label: "com.example.background.task", + event: "testCapacitorDeviceBatteryStatus", + details: {}, + }); + setCommandOutput(`success: ${JSON.stringify(response)}`); + } catch (err) { + setCommandOutput(`ERROR: ${err}`); + } + }; + + const onTestCapDeviceNetwork = async () => { + setCommandOutput(""); + try { + const response = await BackgroundRunner.dispatchEvent({ + label: "com.example.background.task", + event: "testCapacitorDeviceNetworkStatus", + details: {}, + }); + setCommandOutput(`success: ${JSON.stringify(response)}`); + } catch (err) { + setCommandOutput(`ERROR: ${err}`); + } + }; + + const onTestCapAppSetBadge = async () => { + setCommandOutput(""); + try { + await BackgroundRunner.dispatchEvent({ + label: "com.example.background.task", + event: "testCapacitorAppSetBadge", + details: {}, + }); + setCommandOutput(`success`); + } catch (err) { + setCommandOutput(`ERROR: ${err}`); + } + }; + + const onTestCapAppClearBadge = async () => { + setCommandOutput(""); + try { + await BackgroundRunner.dispatchEvent({ + label: "com.example.background.task", + event: "testCapacitorAppClearBadge", + details: {}, + }); + setCommandOutput(`success`); + } catch (err) { + setCommandOutput(`ERROR: ${err}`); + } + }; + + const onTestCapAppGetInfo = async () => { + setCommandOutput(""); + try { + const response = await BackgroundRunner.dispatchEvent({ + label: "com.example.background.task", + event: "testCapacitorAppGetInfo", + details: {}, + }); + setCommandOutput(`success: ${JSON.stringify(response)}`); + } catch (err) { + setCommandOutput(`ERROR: ${err}`); + } + }; + + const onTestCapAppGetState = async () => { + setCommandOutput(""); + try { + const response = await BackgroundRunner.dispatchEvent({ + label: "com.example.background.task", + event: "testCapacitorAppGetState", + details: {}, + }); + setCommandOutput(`success: ${JSON.stringify(response)}`); + } catch (err) { + setCommandOutput(`ERROR: ${err}`); + } + }; + + return ( + + + + Capacitor APIs + + + + + + Capacitor APIs + + +
+ +
+ + Check API Permissions + + + Request API Permissions + + + Capacitor KV - Set + + + Capacitor KV - Get + + + Capacitor KV - Delete + + + Test Capacitor Notif.- Schedule Notification + + + Test Capacitor Notif. - Set Badge + + + Test Capacitor Notif. - Clear Badge + + + Test Capacitor Geolocation + + + Test Capacitor Device - Battery + + + Test Capacitor Device - Network + + + Test Capacitor App - Get App Info + + + Test Capacitor App - Get App State + +
+
+ ); +}; + +export default Tab1; diff --git a/apps/example-app-spm/src/pages/Tab2.css b/apps/example-app-spm/src/pages/Tab2.css new file mode 100644 index 00000000..e69de29b diff --git a/apps/example-app-spm/src/pages/Tab2.tsx b/apps/example-app-spm/src/pages/Tab2.tsx new file mode 100644 index 00000000..cf376fed --- /dev/null +++ b/apps/example-app-spm/src/pages/Tab2.tsx @@ -0,0 +1,121 @@ +import { useState } from "react"; +import { + IonButton, + IonContent, + IonHeader, + IonPage, + IonTextarea, + IonTitle, + IonToolbar, +} from "@ionic/react"; +import { BackgroundRunner } from "@capacitor/background-runner"; +import "./Tab2.css"; + +const Tab2: React.FC = () => { + const [commandOutput, setCommandOutput] = useState(""); + const onTestSync = async () => { + setCommandOutput(""); + try { + await BackgroundRunner.dispatchEvent({ + label: "com.example.background.task", + event: "syncTest", + details: {}, + }); + setCommandOutput("success"); + } catch (err) { + setCommandOutput(`ERROR: ${err}`); + } + }; + + const onTestAsync = async () => { + setCommandOutput(""); + try { + await BackgroundRunner.dispatchEvent({ + label: "com.example.background.task", + event: "asyncTest", + details: {}, + }); + setCommandOutput("success"); + } catch (err) { + setCommandOutput(`ERROR: ${err}`); + } + }; + + const onTestArgs = async () => { + setCommandOutput(""); + try { + const response = await BackgroundRunner.dispatchEvent({ + label: "com.example.background.task", + event: "argsTest", + details: { + user: { + firstName: "John", + lastName: "Doe", + }, + }, + }); + setCommandOutput(`success: ${JSON.stringify(response)}`); + } catch (err) { + setCommandOutput(`ERROR: ${err}`); + } + }; + + const onTestErrors = async () => { + setCommandOutput(""); + try { + await BackgroundRunner.dispatchEvent({ + label: "com.example.background.task", + event: "errorTest", + details: {}, + }); + setCommandOutput('success'); + } catch (err) { + setCommandOutput(`ERROR: ${err}`); + } + }; + + const onTestFetch = async () => { + setCommandOutput(""); + try { + const response = await BackgroundRunner.dispatchEvent({ + label: "com.example.background.task", + event: "fetchTest", + details: {}, + }); + setCommandOutput(`success: ${JSON.stringify(response)}`); + } catch (err) { + setCommandOutput(`ERROR: ${err}`); + } + }; + + return ( + + + + Core Functions + + + + + + Core Functions + + +
+ +
+ Test Synchronous Handler + Test Asynchronous Handler + Test Handler with Args + Test Handler with Errors + Test Handler with Fetch +
+
+ ); +}; + +export default Tab2; diff --git a/apps/example-app-spm/src/pages/Tab3.css b/apps/example-app-spm/src/pages/Tab3.css new file mode 100644 index 00000000..e69de29b diff --git a/apps/example-app-spm/src/pages/Tab3.tsx b/apps/example-app-spm/src/pages/Tab3.tsx new file mode 100644 index 00000000..35fe3c21 --- /dev/null +++ b/apps/example-app-spm/src/pages/Tab3.tsx @@ -0,0 +1,77 @@ +import { useState } from "react"; +import { + IonButton, + IonContent, + IonHeader, + IonPage, + IonTextarea, + IonTitle, + IonToolbar, +} from "@ionic/react"; +import { BackgroundRunner } from "@capacitor/background-runner"; +import "./Tab3.css"; + +const Tab3: React.FC = () => { + const [commandOutput, setCommandOutput] = useState(""); + + const onCheckWatchReachable = async () => { + setCommandOutput(""); + try { + const result = (await BackgroundRunner.dispatchEvent({ + label: "com.example.background.task", + event: "checkWatchReachability", + details: {}, + })) as any; + + setCommandOutput(`success: ${JSON.stringify(result)}`); + } catch (err) { + setCommandOutput(`ERROR: ${err}`); + } + }; + + const onSendWearableMsg = async () => { + setCommandOutput(""); + try { + (await BackgroundRunner.dispatchEvent({ + label: "com.example.background.task", + event: "sendMessageToWearable", + details: {}, + })) as any; + setCommandOutput("success: message sent"); + } catch (err) { + setCommandOutput(`ERROR: ${err}`); + } + }; + + return ( + + + + Tab 3 + + + + + + Tab 3 + + +
+ +
+ + Check Watch Status + + + Send Message to Watch + +
+
+ ); +}; + +export default Tab3; diff --git a/apps/example-app-spm/src/react-app-env.d.ts b/apps/example-app-spm/src/react-app-env.d.ts new file mode 100644 index 00000000..6431bc5f --- /dev/null +++ b/apps/example-app-spm/src/react-app-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/apps/example-app-spm/src/reportWebVitals.ts b/apps/example-app-spm/src/reportWebVitals.ts new file mode 100644 index 00000000..49a2a16e --- /dev/null +++ b/apps/example-app-spm/src/reportWebVitals.ts @@ -0,0 +1,15 @@ +import { ReportHandler } from 'web-vitals'; + +const reportWebVitals = (onPerfEntry?: ReportHandler) => { + if (onPerfEntry && onPerfEntry instanceof Function) { + import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { + getCLS(onPerfEntry); + getFID(onPerfEntry); + getFCP(onPerfEntry); + getLCP(onPerfEntry); + getTTFB(onPerfEntry); + }); + } +}; + +export default reportWebVitals; diff --git a/apps/example-app-spm/src/service-worker.ts b/apps/example-app-spm/src/service-worker.ts new file mode 100644 index 00000000..652a8a4a --- /dev/null +++ b/apps/example-app-spm/src/service-worker.ts @@ -0,0 +1,80 @@ +/// +/* eslint-disable no-restricted-globals */ + +// This service worker can be customized! +// See https://developers.google.com/web/tools/workbox/modules +// for the list of available Workbox modules, or add any other +// code you'd like. +// You can also remove this file if you'd prefer not to use a +// service worker, and the Workbox build step will be skipped. + +import { clientsClaim } from 'workbox-core'; +import { ExpirationPlugin } from 'workbox-expiration'; +import { precacheAndRoute, createHandlerBoundToURL } from 'workbox-precaching'; +import { registerRoute } from 'workbox-routing'; +import { StaleWhileRevalidate } from 'workbox-strategies'; + +declare const self: ServiceWorkerGlobalScope; + +clientsClaim(); + +// Precache all of the assets generated by your build process. +// Their URLs are injected into the manifest variable below. +// This variable must be present somewhere in your service worker file, +// even if you decide not to use precaching. See https://cra.link/PWA +precacheAndRoute(self.__WB_MANIFEST); + +// Set up App Shell-style routing, so that all navigation requests +// are fulfilled with your index.html shell. Learn more at +// https://developers.google.com/web/fundamentals/architecture/app-shell +const fileExtensionRegexp = new RegExp('/[^/?]+\\.[^/]+$'); +registerRoute( + // Return false to exempt requests from being fulfilled by index.html. + ({ request, url }: { request: Request; url: URL }) => { + // If this isn't a navigation, skip. + if (request.mode !== 'navigate') { + return false; + } + + // If this is a URL that starts with /_, skip. + if (url.pathname.startsWith('/_')) { + return false; + } + + // If this looks like a URL for a resource, because it contains + // a file extension, skip. + if (url.pathname.match(fileExtensionRegexp)) { + return false; + } + + // Return true to signal that we want to use the handler. + return true; + }, + createHandlerBoundToURL(process.env.PUBLIC_URL + '/index.html') +); + +// An example runtime caching route for requests that aren't handled by the +// precache, in this case same-origin .png requests like those from in public/ +registerRoute( + // Add in any other file extensions or routing criteria as needed. + ({ url }) => url.origin === self.location.origin && url.pathname.endsWith('.png'), + // Customize this strategy as needed, e.g., by changing to CacheFirst. + new StaleWhileRevalidate({ + cacheName: 'images', + plugins: [ + // Ensure that once this runtime cache reaches a maximum size the + // least-recently used images are removed. + new ExpirationPlugin({ maxEntries: 50 }), + ], + }) +); + +// This allows the web app to trigger skipWaiting via +// registration.waiting.postMessage({type: 'SKIP_WAITING'}) +self.addEventListener('message', (event) => { + if (event.data && event.data.type === 'SKIP_WAITING') { + self.skipWaiting(); + } +}); + +// Any other custom service worker logic can go here. diff --git a/apps/example-app-spm/src/serviceWorkerRegistration.ts b/apps/example-app-spm/src/serviceWorkerRegistration.ts new file mode 100644 index 00000000..efbf2ac4 --- /dev/null +++ b/apps/example-app-spm/src/serviceWorkerRegistration.ts @@ -0,0 +1,142 @@ +// This optional code is used to register a service worker. +// register() is not called by default. + +// This lets the app load faster on subsequent visits in production, and gives +// it offline capabilities. However, it also means that developers (and users) +// will only see deployed updates on subsequent visits to a page, after all the +// existing tabs open on the page have been closed, since previously cached +// resources are updated in the background. + +// To learn more about the benefits of this model and instructions on how to +// opt-in, read https://cra.link/PWA + +const isLocalhost = Boolean( + window.location.hostname === 'localhost' || + // [::1] is the IPv6 localhost address. + window.location.hostname === '[::1]' || + // 127.0.0.0/8 are considered localhost for IPv4. + window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/) +); + +type Config = { + onSuccess?: (registration: ServiceWorkerRegistration) => void; + onUpdate?: (registration: ServiceWorkerRegistration) => void; +}; + +export function register(config?: Config) { + if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { + // The URL constructor is available in all browsers that support SW. + const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href); + if (publicUrl.origin !== window.location.origin) { + // Our service worker won't work if PUBLIC_URL is on a different origin + // from what our page is served on. This might happen if a CDN is used to + // serve assets; see https://github.com/facebook/create-react-app/issues/2374 + return; + } + + window.addEventListener('load', () => { + const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; + + if (isLocalhost) { + // This is running on localhost. Let's check if a service worker still exists or not. + checkValidServiceWorker(swUrl, config); + + // Add some additional logging to localhost, pointing developers to the + // service worker/PWA documentation. + navigator.serviceWorker.ready.then(() => { + console.log( + 'This web app is being served cache-first by a service ' + + 'worker. To learn more, visit https://cra.link/PWA' + ); + }); + } else { + // Is not localhost. Just register service worker + registerValidSW(swUrl, config); + } + }); + } +} + +function registerValidSW(swUrl: string, config?: Config) { + navigator.serviceWorker + .register(swUrl) + .then((registration) => { + registration.onupdatefound = () => { + const installingWorker = registration.installing; + if (installingWorker == null) { + return; + } + installingWorker.onstatechange = () => { + if (installingWorker.state === 'installed') { + if (navigator.serviceWorker.controller) { + // At this point, the updated precached content has been fetched, + // but the previous service worker will still serve the older + // content until all client tabs are closed. + console.log( + 'New content is available and will be used when all ' + + 'tabs for this page are closed. See https://cra.link/PWA.' + ); + + // Execute callback + if (config && config.onUpdate) { + config.onUpdate(registration); + } + } else { + // At this point, everything has been precached. + // It's the perfect time to display a + // "Content is cached for offline use." message. + console.log('Content is cached for offline use.'); + + // Execute callback + if (config && config.onSuccess) { + config.onSuccess(registration); + } + } + } + }; + }; + }) + .catch((error) => { + console.error('Error during service worker registration:', error); + }); +} + +function checkValidServiceWorker(swUrl: string, config?: Config) { + // Check if the service worker can be found. If it can't reload the page. + fetch(swUrl, { + headers: { 'Service-Worker': 'script' }, + }) + .then((response) => { + // Ensure service worker exists, and that we really are getting a JS file. + const contentType = response.headers.get('content-type'); + if ( + response.status === 404 || + (contentType != null && contentType.indexOf('javascript') === -1) + ) { + // No service worker found. Probably a different app. Reload the page. + navigator.serviceWorker.ready.then((registration) => { + registration.unregister().then(() => { + window.location.reload(); + }); + }); + } else { + // Service worker found. Proceed as normal. + registerValidSW(swUrl, config); + } + }) + .catch(() => { + console.log('No internet connection found. App is running in offline mode.'); + }); +} + +export function unregister() { + if ('serviceWorker' in navigator) { + navigator.serviceWorker.ready + .then((registration) => { + registration.unregister(); + }) + .catch((error) => { + console.error(error.message); + }); + } +} diff --git a/apps/example-app-spm/src/setupTests.ts b/apps/example-app-spm/src/setupTests.ts new file mode 100644 index 00000000..87988d6b --- /dev/null +++ b/apps/example-app-spm/src/setupTests.ts @@ -0,0 +1,14 @@ +// jest-dom adds custom jest matchers for asserting on DOM nodes. +// allows you to do things like: +// expect(element).toHaveTextContent(/react/i) +// learn more: https://github.com/testing-library/jest-dom +import '@testing-library/jest-dom/extend-expect'; + +// Mock matchmedia +window.matchMedia = window.matchMedia || function() { + return { + matches: false, + addListener: function() {}, + removeListener: function() {} + }; +}; diff --git a/apps/example-app-spm/src/theme/variables.css b/apps/example-app-spm/src/theme/variables.css new file mode 100644 index 00000000..a44fcdd0 --- /dev/null +++ b/apps/example-app-spm/src/theme/variables.css @@ -0,0 +1,236 @@ +/* Ionic Variables and Theming. For more info, please see: +http://ionicframework.com/docs/theming/ */ + +/** Ionic CSS Variables **/ +:root { + /** primary **/ + --ion-color-primary: #3880ff; + --ion-color-primary-rgb: 56, 128, 255; + --ion-color-primary-contrast: #ffffff; + --ion-color-primary-contrast-rgb: 255, 255, 255; + --ion-color-primary-shade: #3171e0; + --ion-color-primary-tint: #4c8dff; + + /** secondary **/ + --ion-color-secondary: #3dc2ff; + --ion-color-secondary-rgb: 61, 194, 255; + --ion-color-secondary-contrast: #ffffff; + --ion-color-secondary-contrast-rgb: 255, 255, 255; + --ion-color-secondary-shade: #36abe0; + --ion-color-secondary-tint: #50c8ff; + + /** tertiary **/ + --ion-color-tertiary: #5260ff; + --ion-color-tertiary-rgb: 82, 96, 255; + --ion-color-tertiary-contrast: #ffffff; + --ion-color-tertiary-contrast-rgb: 255, 255, 255; + --ion-color-tertiary-shade: #4854e0; + --ion-color-tertiary-tint: #6370ff; + + /** success **/ + --ion-color-success: #2dd36f; + --ion-color-success-rgb: 45, 211, 111; + --ion-color-success-contrast: #ffffff; + --ion-color-success-contrast-rgb: 255, 255, 255; + --ion-color-success-shade: #28ba62; + --ion-color-success-tint: #42d77d; + + /** warning **/ + --ion-color-warning: #ffc409; + --ion-color-warning-rgb: 255, 196, 9; + --ion-color-warning-contrast: #000000; + --ion-color-warning-contrast-rgb: 0, 0, 0; + --ion-color-warning-shade: #e0ac08; + --ion-color-warning-tint: #ffca22; + + /** danger **/ + --ion-color-danger: #eb445a; + --ion-color-danger-rgb: 235, 68, 90; + --ion-color-danger-contrast: #ffffff; + --ion-color-danger-contrast-rgb: 255, 255, 255; + --ion-color-danger-shade: #cf3c4f; + --ion-color-danger-tint: #ed576b; + + /** dark **/ + --ion-color-dark: #222428; + --ion-color-dark-rgb: 34, 36, 40; + --ion-color-dark-contrast: #ffffff; + --ion-color-dark-contrast-rgb: 255, 255, 255; + --ion-color-dark-shade: #1e2023; + --ion-color-dark-tint: #383a3e; + + /** medium **/ + --ion-color-medium: #92949c; + --ion-color-medium-rgb: 146, 148, 156; + --ion-color-medium-contrast: #ffffff; + --ion-color-medium-contrast-rgb: 255, 255, 255; + --ion-color-medium-shade: #808289; + --ion-color-medium-tint: #9d9fa6; + + /** light **/ + --ion-color-light: #f4f5f8; + --ion-color-light-rgb: 244, 245, 248; + --ion-color-light-contrast: #000000; + --ion-color-light-contrast-rgb: 0, 0, 0; + --ion-color-light-shade: #d7d8da; + --ion-color-light-tint: #f5f6f9; +} + +@media (prefers-color-scheme: dark) { + /* + * Dark Colors + * ------------------------------------------- + */ + + body { + --ion-color-primary: #428cff; + --ion-color-primary-rgb: 66,140,255; + --ion-color-primary-contrast: #ffffff; + --ion-color-primary-contrast-rgb: 255,255,255; + --ion-color-primary-shade: #3a7be0; + --ion-color-primary-tint: #5598ff; + + --ion-color-secondary: #50c8ff; + --ion-color-secondary-rgb: 80,200,255; + --ion-color-secondary-contrast: #ffffff; + --ion-color-secondary-contrast-rgb: 255,255,255; + --ion-color-secondary-shade: #46b0e0; + --ion-color-secondary-tint: #62ceff; + + --ion-color-tertiary: #6a64ff; + --ion-color-tertiary-rgb: 106,100,255; + --ion-color-tertiary-contrast: #ffffff; + --ion-color-tertiary-contrast-rgb: 255,255,255; + --ion-color-tertiary-shade: #5d58e0; + --ion-color-tertiary-tint: #7974ff; + + --ion-color-success: #2fdf75; + --ion-color-success-rgb: 47,223,117; + --ion-color-success-contrast: #000000; + --ion-color-success-contrast-rgb: 0,0,0; + --ion-color-success-shade: #29c467; + --ion-color-success-tint: #44e283; + + --ion-color-warning: #ffd534; + --ion-color-warning-rgb: 255,213,52; + --ion-color-warning-contrast: #000000; + --ion-color-warning-contrast-rgb: 0,0,0; + --ion-color-warning-shade: #e0bb2e; + --ion-color-warning-tint: #ffd948; + + --ion-color-danger: #ff4961; + --ion-color-danger-rgb: 255,73,97; + --ion-color-danger-contrast: #ffffff; + --ion-color-danger-contrast-rgb: 255,255,255; + --ion-color-danger-shade: #e04055; + --ion-color-danger-tint: #ff5b71; + + --ion-color-dark: #f4f5f8; + --ion-color-dark-rgb: 244,245,248; + --ion-color-dark-contrast: #000000; + --ion-color-dark-contrast-rgb: 0,0,0; + --ion-color-dark-shade: #d7d8da; + --ion-color-dark-tint: #f5f6f9; + + --ion-color-medium: #989aa2; + --ion-color-medium-rgb: 152,154,162; + --ion-color-medium-contrast: #000000; + --ion-color-medium-contrast-rgb: 0,0,0; + --ion-color-medium-shade: #86888f; + --ion-color-medium-tint: #a2a4ab; + + --ion-color-light: #222428; + --ion-color-light-rgb: 34,36,40; + --ion-color-light-contrast: #ffffff; + --ion-color-light-contrast-rgb: 255,255,255; + --ion-color-light-shade: #1e2023; + --ion-color-light-tint: #383a3e; + } + + /* + * iOS Dark Theme + * ------------------------------------------- + */ + + .ios body { + --ion-background-color: #000000; + --ion-background-color-rgb: 0,0,0; + + --ion-text-color: #ffffff; + --ion-text-color-rgb: 255,255,255; + + --ion-color-step-50: #0d0d0d; + --ion-color-step-100: #1a1a1a; + --ion-color-step-150: #262626; + --ion-color-step-200: #333333; + --ion-color-step-250: #404040; + --ion-color-step-300: #4d4d4d; + --ion-color-step-350: #595959; + --ion-color-step-400: #666666; + --ion-color-step-450: #737373; + --ion-color-step-500: #808080; + --ion-color-step-550: #8c8c8c; + --ion-color-step-600: #999999; + --ion-color-step-650: #a6a6a6; + --ion-color-step-700: #b3b3b3; + --ion-color-step-750: #bfbfbf; + --ion-color-step-800: #cccccc; + --ion-color-step-850: #d9d9d9; + --ion-color-step-900: #e6e6e6; + --ion-color-step-950: #f2f2f2; + + --ion-item-background: #000000; + + --ion-card-background: #1c1c1d; + } + + .ios ion-modal { + --ion-background-color: var(--ion-color-step-100); + --ion-toolbar-background: var(--ion-color-step-150); + --ion-toolbar-border-color: var(--ion-color-step-250); + } + + + /* + * Material Design Dark Theme + * ------------------------------------------- + */ + + .md body { + --ion-background-color: #121212; + --ion-background-color-rgb: 18,18,18; + + --ion-text-color: #ffffff; + --ion-text-color-rgb: 255,255,255; + + --ion-border-color: #222222; + + --ion-color-step-50: #1e1e1e; + --ion-color-step-100: #2a2a2a; + --ion-color-step-150: #363636; + --ion-color-step-200: #414141; + --ion-color-step-250: #4d4d4d; + --ion-color-step-300: #595959; + --ion-color-step-350: #656565; + --ion-color-step-400: #717171; + --ion-color-step-450: #7d7d7d; + --ion-color-step-500: #898989; + --ion-color-step-550: #949494; + --ion-color-step-600: #a0a0a0; + --ion-color-step-650: #acacac; + --ion-color-step-700: #b8b8b8; + --ion-color-step-750: #c4c4c4; + --ion-color-step-800: #d0d0d0; + --ion-color-step-850: #dbdbdb; + --ion-color-step-900: #e7e7e7; + --ion-color-step-950: #f3f3f3; + + --ion-item-background: #1e1e1e; + + --ion-toolbar-background: #1f1f1f; + + --ion-tab-bar-background: #1f1f1f; + + --ion-card-background: #1e1e1e; + } +} diff --git a/apps/example-app-spm/tsconfig.json b/apps/example-app-spm/tsconfig.json new file mode 100644 index 00000000..a273b0cf --- /dev/null +++ b/apps/example-app-spm/tsconfig.json @@ -0,0 +1,26 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], + "allowJs": true, + "skipLibCheck": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "noFallthroughCasesInSwitch": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx" + }, + "include": [ + "src" + ] +} diff --git a/apps/example-app/android/capacitor.settings.gradle b/apps/example-app/android/capacitor.settings.gradle index 5fae84ae..86220a6c 100644 --- a/apps/example-app/android/capacitor.settings.gradle +++ b/apps/example-app/android/capacitor.settings.gradle @@ -1,18 +1,18 @@ // DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN include ':capacitor-android' -project(':capacitor-android').projectDir = new File('../../../node_modules/.pnpm/@capacitor+android@7.0.0_@capacitor+core@7.0.0/node_modules/@capacitor/android/capacitor') +project(':capacitor-android').projectDir = new File('../../../node_modules/.pnpm/@capacitor+android@7.4.4_@capacitor+core@7.4.4/node_modules/@capacitor/android/capacitor') include ':capacitor-app' -project(':capacitor-app').projectDir = new File('../../../node_modules/.pnpm/@capacitor+app@7.0.0_@capacitor+core@7.0.0/node_modules/@capacitor/app/android') +project(':capacitor-app').projectDir = new File('../../../node_modules/.pnpm/@capacitor+app@7.1.0_@capacitor+core@7.4.4/node_modules/@capacitor/app/android') include ':capacitor-background-runner' project(':capacitor-background-runner').projectDir = new File('../../../packages/capacitor-plugin/android') include ':capacitor-haptics' -project(':capacitor-haptics').projectDir = new File('../../../node_modules/.pnpm/@capacitor+haptics@7.0.0_@capacitor+core@7.0.0/node_modules/@capacitor/haptics/android') +project(':capacitor-haptics').projectDir = new File('../../../node_modules/.pnpm/@capacitor+haptics@7.0.2_@capacitor+core@7.4.4/node_modules/@capacitor/haptics/android') include ':capacitor-keyboard' -project(':capacitor-keyboard').projectDir = new File('../../../node_modules/.pnpm/@capacitor+keyboard@7.0.0_@capacitor+core@7.0.0/node_modules/@capacitor/keyboard/android') +project(':capacitor-keyboard').projectDir = new File('../../../node_modules/.pnpm/@capacitor+keyboard@7.0.3_@capacitor+core@7.4.4/node_modules/@capacitor/keyboard/android') include ':capacitor-status-bar' -project(':capacitor-status-bar').projectDir = new File('../../../node_modules/.pnpm/@capacitor+status-bar@7.0.0_@capacitor+core@7.0.0/node_modules/@capacitor/status-bar/android') +project(':capacitor-status-bar').projectDir = new File('../../../node_modules/.pnpm/@capacitor+status-bar@7.0.3_@capacitor+core@7.4.4/node_modules/@capacitor/status-bar/android') diff --git a/apps/example-app/ios/App/App.xcodeproj/project.pbxproj b/apps/example-app/ios/App/App.xcodeproj/project.pbxproj index 901d2af1..4d996c01 100644 --- a/apps/example-app/ios/App/App.xcodeproj/project.pbxproj +++ b/apps/example-app/ios/App/App.xcodeproj/project.pbxproj @@ -536,7 +536,7 @@ CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = 9YN2HU59K8; INFOPLIST_FILE = App/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 14.0; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; MARKETING_VERSION = 1.0; OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\""; @@ -559,7 +559,7 @@ CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = 9YN2HU59K8; INFOPLIST_FILE = App/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 14.0; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = io.ionic.backgroundrunner.example; diff --git a/apps/example-app/ios/App/Podfile b/apps/example-app/ios/App/Podfile index e2201c9e..b0c02505 100644 --- a/apps/example-app/ios/App/Podfile +++ b/apps/example-app/ios/App/Podfile @@ -1,4 +1,4 @@ -require_relative '../../../../node_modules/.pnpm/@capacitor+ios@7.0.0_@capacitor+core@7.0.0/node_modules/@capacitor/ios/scripts/pods_helpers' +require_relative '../../../../node_modules/.pnpm/@capacitor+ios@7.4.4_@capacitor+core@7.4.4/node_modules/@capacitor/ios/scripts/pods_helpers' platform :ios, '14.0' use_frameworks! @@ -9,13 +9,13 @@ use_frameworks! install! 'cocoapods', :disable_input_output_paths => true def capacitor_pods - pod 'Capacitor', :path => '../../../../node_modules/.pnpm/@capacitor+ios@7.0.0_@capacitor+core@7.0.0/node_modules/@capacitor/ios' - pod 'CapacitorCordova', :path => '../../../../node_modules/.pnpm/@capacitor+ios@7.0.0_@capacitor+core@7.0.0/node_modules/@capacitor/ios' - pod 'CapacitorApp', :path => '../../../../node_modules/.pnpm/@capacitor+app@7.0.0_@capacitor+core@7.0.0/node_modules/@capacitor/app' + pod 'Capacitor', :path => '../../../../node_modules/.pnpm/@capacitor+ios@7.4.4_@capacitor+core@7.4.4/node_modules/@capacitor/ios' + pod 'CapacitorCordova', :path => '../../../../node_modules/.pnpm/@capacitor+ios@7.4.4_@capacitor+core@7.4.4/node_modules/@capacitor/ios' + pod 'CapacitorApp', :path => '../../../../node_modules/.pnpm/@capacitor+app@7.1.0_@capacitor+core@7.4.4/node_modules/@capacitor/app' pod 'CapacitorBackgroundRunner', :path => '../../../../packages/capacitor-plugin' - pod 'CapacitorHaptics', :path => '../../../../node_modules/.pnpm/@capacitor+haptics@7.0.0_@capacitor+core@7.0.0/node_modules/@capacitor/haptics' - pod 'CapacitorKeyboard', :path => '../../../../node_modules/.pnpm/@capacitor+keyboard@7.0.0_@capacitor+core@7.0.0/node_modules/@capacitor/keyboard' - pod 'CapacitorStatusBar', :path => '../../../../node_modules/.pnpm/@capacitor+status-bar@7.0.0_@capacitor+core@7.0.0/node_modules/@capacitor/status-bar' + pod 'CapacitorHaptics', :path => '../../../../node_modules/.pnpm/@capacitor+haptics@7.0.2_@capacitor+core@7.4.4/node_modules/@capacitor/haptics' + pod 'CapacitorKeyboard', :path => '../../../../node_modules/.pnpm/@capacitor+keyboard@7.0.3_@capacitor+core@7.4.4/node_modules/@capacitor/keyboard' + pod 'CapacitorStatusBar', :path => '../../../../node_modules/.pnpm/@capacitor+status-bar@7.0.3_@capacitor+core@7.4.4/node_modules/@capacitor/status-bar' end target 'App' do diff --git a/apps/example-app/ios/App/Podfile.lock b/apps/example-app/ios/App/Podfile.lock index c9103819..ec3740ba 100644 --- a/apps/example-app/ios/App/Podfile.lock +++ b/apps/example-app/ios/App/Podfile.lock @@ -1,52 +1,52 @@ PODS: - - Capacitor (7.0.0): + - Capacitor (7.4.4): - CapacitorCordova - - CapacitorApp (7.0.0): + - CapacitorApp (7.1.0): - Capacitor - - CapacitorBackgroundRunner (1.1.0): + - CapacitorBackgroundRunner (2.2.0): - Capacitor - - CapacitorCordova (7.0.0) - - CapacitorHaptics (7.0.0): + - CapacitorCordova (7.4.4) + - CapacitorHaptics (7.0.2): - Capacitor - - CapacitorKeyboard (7.0.0): + - CapacitorKeyboard (7.0.3): - Capacitor - - CapacitorStatusBar (7.0.0): + - CapacitorStatusBar (7.0.3): - Capacitor DEPENDENCIES: - - "Capacitor (from `../../../../node_modules/.pnpm/@capacitor+ios@7.0.0_@capacitor+core@7.0.0/node_modules/@capacitor/ios`)" - - "CapacitorApp (from `../../../../node_modules/.pnpm/@capacitor+app@7.0.0_@capacitor+core@7.0.0/node_modules/@capacitor/app`)" + - "Capacitor (from `../../../../node_modules/.pnpm/@capacitor+ios@7.4.4_@capacitor+core@7.4.4/node_modules/@capacitor/ios`)" + - "CapacitorApp (from `../../../../node_modules/.pnpm/@capacitor+app@7.1.0_@capacitor+core@7.4.4/node_modules/@capacitor/app`)" - CapacitorBackgroundRunner (from `../../../../packages/capacitor-plugin`) - - "CapacitorCordova (from `../../../../node_modules/.pnpm/@capacitor+ios@7.0.0_@capacitor+core@7.0.0/node_modules/@capacitor/ios`)" - - "CapacitorHaptics (from `../../../../node_modules/.pnpm/@capacitor+haptics@7.0.0_@capacitor+core@7.0.0/node_modules/@capacitor/haptics`)" - - "CapacitorKeyboard (from `../../../../node_modules/.pnpm/@capacitor+keyboard@7.0.0_@capacitor+core@7.0.0/node_modules/@capacitor/keyboard`)" - - "CapacitorStatusBar (from `../../../../node_modules/.pnpm/@capacitor+status-bar@7.0.0_@capacitor+core@7.0.0/node_modules/@capacitor/status-bar`)" + - "CapacitorCordova (from `../../../../node_modules/.pnpm/@capacitor+ios@7.4.4_@capacitor+core@7.4.4/node_modules/@capacitor/ios`)" + - "CapacitorHaptics (from `../../../../node_modules/.pnpm/@capacitor+haptics@7.0.2_@capacitor+core@7.4.4/node_modules/@capacitor/haptics`)" + - "CapacitorKeyboard (from `../../../../node_modules/.pnpm/@capacitor+keyboard@7.0.3_@capacitor+core@7.4.4/node_modules/@capacitor/keyboard`)" + - "CapacitorStatusBar (from `../../../../node_modules/.pnpm/@capacitor+status-bar@7.0.3_@capacitor+core@7.4.4/node_modules/@capacitor/status-bar`)" EXTERNAL SOURCES: Capacitor: - :path: "../../../../node_modules/.pnpm/@capacitor+ios@7.0.0_@capacitor+core@7.0.0/node_modules/@capacitor/ios" + :path: "../../../../node_modules/.pnpm/@capacitor+ios@7.4.4_@capacitor+core@7.4.4/node_modules/@capacitor/ios" CapacitorApp: - :path: "../../../../node_modules/.pnpm/@capacitor+app@7.0.0_@capacitor+core@7.0.0/node_modules/@capacitor/app" + :path: "../../../../node_modules/.pnpm/@capacitor+app@7.1.0_@capacitor+core@7.4.4/node_modules/@capacitor/app" CapacitorBackgroundRunner: :path: "../../../../packages/capacitor-plugin" CapacitorCordova: - :path: "../../../../node_modules/.pnpm/@capacitor+ios@7.0.0_@capacitor+core@7.0.0/node_modules/@capacitor/ios" + :path: "../../../../node_modules/.pnpm/@capacitor+ios@7.4.4_@capacitor+core@7.4.4/node_modules/@capacitor/ios" CapacitorHaptics: - :path: "../../../../node_modules/.pnpm/@capacitor+haptics@7.0.0_@capacitor+core@7.0.0/node_modules/@capacitor/haptics" + :path: "../../../../node_modules/.pnpm/@capacitor+haptics@7.0.2_@capacitor+core@7.4.4/node_modules/@capacitor/haptics" CapacitorKeyboard: - :path: "../../../../node_modules/.pnpm/@capacitor+keyboard@7.0.0_@capacitor+core@7.0.0/node_modules/@capacitor/keyboard" + :path: "../../../../node_modules/.pnpm/@capacitor+keyboard@7.0.3_@capacitor+core@7.4.4/node_modules/@capacitor/keyboard" CapacitorStatusBar: - :path: "../../../../node_modules/.pnpm/@capacitor+status-bar@7.0.0_@capacitor+core@7.0.0/node_modules/@capacitor/status-bar" + :path: "../../../../node_modules/.pnpm/@capacitor+status-bar@7.0.3_@capacitor+core@7.4.4/node_modules/@capacitor/status-bar" SPEC CHECKSUMS: - Capacitor: fcbee427ff437f414bbb3bc2d39364ad9bd2b8a5 - CapacitorApp: 45cb7cbef4aa380b9236fd6980033eb5cde6fcd2 - CapacitorBackgroundRunner: 5261bba9fa5376b419159f6885397dda1c637a53 - CapacitorCordova: 345f93b7edd121db98e4ec20ac94d6d7bcaf7e48 - CapacitorHaptics: 1fba3e460e7614349c6d5f868b1fccdc5c87b66d - CapacitorKeyboard: 2c26c6fccde35023c579fc37d4cae6326d5e6343 - CapacitorStatusBar: 438e90beeeefa8276b24e6c5991cb02dd13e51bf + Capacitor: 358dd1c3fdd71d969547b17e159fd8a7736cb45f + CapacitorApp: 26587c2ce485d88ddb39adb21cac64f8e481afe3 + CapacitorBackgroundRunner: de9f99ef9c6c9ed0373e879ea48acb93bd9eda15 + CapacitorCordova: bf648a636f3c153f652d312ae145fb508b6ffced + CapacitorHaptics: b3fb2869e72c4466e18ce9ccbeb60a3d8723b3d4 + CapacitorKeyboard: 62f36104f26d53d8b3a2a43f2a69fe714f1777d5 + CapacitorStatusBar: 0659ddc7b1713764a05831463d215b177a15d054 -PODFILE CHECKSUM: a7c5bc22cf6375f7253c90a0be7688d0473ac36a +PODFILE CHECKSUM: 465e517c9e30d2bab8c1788597dcef6141ee6edf -COCOAPODS: 1.15.2 +COCOAPODS: 1.16.2 diff --git a/apps/example-app/package.json b/apps/example-app/package.json index 5d3aa122..0ecdd72a 100644 --- a/apps/example-app/package.json +++ b/apps/example-app/package.json @@ -5,14 +5,14 @@ "dependencies": { "@babel/plugin-syntax-flow": "^7.26.0", "@babel/plugin-transform-react-jsx": "^7.25.9", - "@capacitor/android": "^7.0.0", - "@capacitor/app": "^7.0.0", + "@capacitor/android": "^7.4.4", + "@capacitor/app": "^7.1.0", "@capacitor/background-runner": "workspace:^", - "@capacitor/core": "^7.0.0", - "@capacitor/haptics": "^7.0.0", - "@capacitor/ios": "^7.0.0", - "@capacitor/keyboard": "^7.0.0", - "@capacitor/status-bar": "^7.0.0", + "@capacitor/core": "^7.4.4", + "@capacitor/haptics": "^7.0.2", + "@capacitor/ios": "^7.4.4", + "@capacitor/keyboard": "^7.0.3", + "@capacitor/status-bar": "^7.0.3", "@ionic/react": "^6.7.5", "@ionic/react-router": "^6.7.5", "@testing-library/dom": "^9.3.4", @@ -71,7 +71,7 @@ ] }, "devDependencies": { - "@capacitor/cli": "next" + "@capacitor/cli": "^7.4.4" }, "description": "An Ionic project" } diff --git a/packages/capacitor-plugin/.gitignore b/packages/capacitor-plugin/.gitignore index e776d37f..992c2edc 100644 --- a/packages/capacitor-plugin/.gitignore +++ b/packages/capacitor-plugin/.gitignore @@ -1,12 +1,21 @@ # node files dist node_modules +.nx # iOS files Pods Podfile.lock +Package.resolved Build xcuserdata +/.build +/Packages +xcuserdata/ +DerivedData/ +.swiftpm/configuration/registries.json +.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata +.netrc # macOS files .DS_Store diff --git a/packages/capacitor-plugin/CapacitorBackgroundRunner.podspec b/packages/capacitor-plugin/CapacitorBackgroundRunner.podspec index b1b27cc9..c6579f5d 100644 --- a/packages/capacitor-plugin/CapacitorBackgroundRunner.podspec +++ b/packages/capacitor-plugin/CapacitorBackgroundRunner.podspec @@ -10,7 +10,7 @@ Pod::Spec.new do |s| s.homepage = package['repository']['url'] s.author = package['author'] s.source = { :git => package['repository']['url'], :tag => s.version.to_s } - s.source_files = 'ios/Plugin/**/*.{swift,h,m,c,cc,mm,cpp}', 'packages/capacitor-plugin/ios/Plugin/**/*.{swift,h,m,c,cc,mm,cpp}', 'packages/ios-engine/Sources/RunnerEngine/*.swift' + s.source_files = 'ios/Sources/**/*.{swift,h,m,c,cc,mm,cpp}' s.ios.deployment_target = '14.0' s.dependency 'Capacitor' s.swift_version = '5.1' diff --git a/packages/capacitor-plugin/Package.swift b/packages/capacitor-plugin/Package.swift new file mode 100644 index 00000000..8c135ca0 --- /dev/null +++ b/packages/capacitor-plugin/Package.swift @@ -0,0 +1,45 @@ +// swift-tools-version: 5.7 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "CapacitorBackgroundRunner", + platforms: [.iOS(.v14), .macOS(.v13)], + products: [ + // Products define the executables and libraries a package produces, making them visible to other packages. + .library( + name: "CapacitorBackgroundRunner", + targets: ["CapacitorBackgroundRunner"] + ) + ], + dependencies: [ + .package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", from: "7.0.0") + ], + targets: [ + // Targets are the basic building blocks of a package, defining a module or a test suite. + // Targets can depend on other targets in this package and products from dependencies. + .target( + name: "CapacitorBackgroundRunner", + dependencies: [ + .product(name: "Capacitor", package: "capacitor-swift-pm"), + .product(name: "Cordova", package: "capacitor-swift-pm"), + "RunnerEngine", + ], + path: "ios/Sources/CapacitorBackgroundRunner" + ), + .target( + name: "RunnerEngine", + dependencies: [], + path: "ios/Sources/RunnerEngine"), + .testTarget( + name: "RunnerEngineTests", + dependencies: ["RunnerEngine"], + path: "ios/Tests/RunnerEngineTests"), + .testTarget( + name: "CapacitorBackgroundRunnerTests", + dependencies: ["CapacitorBackgroundRunner"], + path: "ios/Tests/CapacitorBackgroundRunnerTests" + ), + ] +) diff --git a/packages/capacitor-plugin/android/src/main/java/io/ionic/backgroundrunner/plugin/BackgroundRunnerPlugin.kt b/packages/capacitor-plugin/android/src/main/java/io/ionic/backgroundrunner/plugin/BackgroundRunnerPlugin.kt index 5abf6734..9c7b75b4 100644 --- a/packages/capacitor-plugin/android/src/main/java/io/ionic/backgroundrunner/plugin/BackgroundRunnerPlugin.kt +++ b/packages/capacitor-plugin/android/src/main/java/io/ionic/backgroundrunner/plugin/BackgroundRunnerPlugin.kt @@ -19,7 +19,7 @@ import com.getcapacitor.Bridge @CapacitorPlugin( - name = "BackgroundRunner", + name = "CapacitorBackgroundRunner", permissions = [ Permission( strings = [Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION], diff --git a/packages/capacitor-plugin/android/src/main/libs/android-js-engine-release.aar b/packages/capacitor-plugin/android/src/main/libs/android-js-engine-release.aar index 5d11ee11..107fc387 100644 Binary files a/packages/capacitor-plugin/android/src/main/libs/android-js-engine-release.aar and b/packages/capacitor-plugin/android/src/main/libs/android-js-engine-release.aar differ diff --git a/packages/capacitor-plugin/ios/.gitignore b/packages/capacitor-plugin/ios/.gitignore new file mode 100644 index 00000000..0023a534 --- /dev/null +++ b/packages/capacitor-plugin/ios/.gitignore @@ -0,0 +1,8 @@ +.DS_Store +/.build +/Packages +xcuserdata/ +DerivedData/ +.swiftpm/configuration/registries.json +.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata +.netrc diff --git a/packages/capacitor-plugin/ios/Plugin.xcodeproj/project.pbxproj b/packages/capacitor-plugin/ios/Plugin.xcodeproj/project.pbxproj deleted file mode 100644 index 9f084fd0..00000000 --- a/packages/capacitor-plugin/ios/Plugin.xcodeproj/project.pbxproj +++ /dev/null @@ -1,669 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 48; - objects = { - -/* Begin PBXBuildFile section */ - 022BF06B29F18D7900485B84 /* RunnerConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 022BF06A29F18D7900485B84 /* RunnerConfig.swift */; }; - 022BF06D29F18E5D00485B84 /* BackgroundRunnerErrors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 022BF06C29F18E5D00485B84 /* BackgroundRunnerErrors.swift */; }; - 0237234D29FC33A9009B91C9 /* WatchConnectivtySessionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0237234C29FC33A9009B91C9 /* WatchConnectivtySessionDelegate.swift */; }; - 023723632A002600009B91C9 /* Context+CapacitorAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 023723622A002600009B91C9 /* Context+CapacitorAPI.swift */; }; - 023723712A003F5C009B91C9 /* JSTextEncoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0237236A2A003F5C009B91C9 /* JSTextEncoder.swift */; }; - 023723722A003F5C009B91C9 /* JSConsole.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0237236B2A003F5C009B91C9 /* JSConsole.swift */; }; - 023723732A003F5C009B91C9 /* JSCrypto.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0237236C2A003F5C009B91C9 /* JSCrypto.swift */; }; - 023723742A003F5C009B91C9 /* JSTextDecoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0237236D2A003F5C009B91C9 /* JSTextDecoder.swift */; }; - 023723752A003F5C009B91C9 /* Errors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0237236E2A003F5C009B91C9 /* Errors.swift */; }; - 023723762A003F5C009B91C9 /* Runner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0237236F2A003F5C009B91C9 /* Runner.swift */; }; - 023723772A003F5C009B91C9 /* Context.swift in Sources */ = {isa = PBXBuildFile; fileRef = 023723702A003F5C009B91C9 /* Context.swift */; }; - 0237237B2A004051009B91C9 /* KV.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0237237A2A004051009B91C9 /* KV.swift */; }; - 0237237D2A0041B2009B91C9 /* Geolocation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0237237C2A0041B2009B91C9 /* Geolocation.swift */; }; - 0237237F2A00431F009B91C9 /* Watch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0237237E2A00431F009B91C9 /* Watch.swift */; }; - 027BCF202A16ABA8009884A0 /* BackgroundRunner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 027BCF1F2A16ABA8009884A0 /* BackgroundRunner.swift */; }; - 027BCF232A17DE2C009884A0 /* JSResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 027BCF212A17DE2C009884A0 /* JSResponse.swift */; }; - 027BCF242A17DE2C009884A0 /* JSFetch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 027BCF222A17DE2C009884A0 /* JSFetch.swift */; }; - 0296D4B02A45FCE500FCD31A /* Device.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0296D4AE2A45FCE500FCD31A /* Device.swift */; }; - 0296D4B12A45FCE500FCD31A /* Reachability.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0296D4AF2A45FCE500FCD31A /* Reachability.swift */; }; - 02D65FBF2A141B7D007A46A2 /* Notifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02D65FBE2A141B7D007A46A2 /* Notifications.swift */; }; - 03FC29A292ACC40490383A1F /* Pods_Plugin.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B2A61DA5A1F2DD4F959604D /* Pods_Plugin.framework */; }; - 20C0B05DCFC8E3958A738AF2 /* Pods_PluginTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6753A823D3815DB436415E3 /* Pods_PluginTests.framework */; }; - 50ADFF92201F53D600D50D53 /* Plugin.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 50ADFF88201F53D600D50D53 /* Plugin.framework */; }; - 50ADFF97201F53D600D50D53 /* BackgroundRunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50ADFF96201F53D600D50D53 /* BackgroundRunnerTests.swift */; }; - 50ADFF99201F53D600D50D53 /* BackgroundRunnerPlugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 50ADFF8B201F53D600D50D53 /* BackgroundRunnerPlugin.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 50ADFFA42020D75100D50D53 /* Capacitor.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 50ADFFA52020D75100D50D53 /* Capacitor.framework */; }; - 50ADFFA82020EE4F00D50D53 /* BackgroundRunnerPlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = 50ADFFA72020EE4F00D50D53 /* BackgroundRunnerPlugin.m */; }; - 50E1A94820377CB70090CE1A /* BackgroundRunnerPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50E1A94720377CB70090CE1A /* BackgroundRunnerPlugin.swift */; }; - D400A45E2A853E05003DAA2F /* JSError.swift in Sources */ = {isa = PBXBuildFile; fileRef = D400A45D2A853E05003DAA2F /* JSError.swift */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 50ADFF93201F53D600D50D53 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 50ADFF7F201F53D600D50D53 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 50ADFF87201F53D600D50D53; - remoteInfo = Plugin; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXFileReference section */ - 022BF06A29F18D7900485B84 /* RunnerConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerConfig.swift; sourceTree = ""; }; - 022BF06C29F18E5D00485B84 /* BackgroundRunnerErrors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundRunnerErrors.swift; sourceTree = ""; }; - 0237234C29FC33A9009B91C9 /* WatchConnectivtySessionDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchConnectivtySessionDelegate.swift; sourceTree = ""; }; - 023723622A002600009B91C9 /* Context+CapacitorAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Context+CapacitorAPI.swift"; sourceTree = ""; }; - 0237236A2A003F5C009B91C9 /* JSTextEncoder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSTextEncoder.swift; sourceTree = ""; }; - 0237236B2A003F5C009B91C9 /* JSConsole.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSConsole.swift; sourceTree = ""; }; - 0237236C2A003F5C009B91C9 /* JSCrypto.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSCrypto.swift; sourceTree = ""; }; - 0237236D2A003F5C009B91C9 /* JSTextDecoder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSTextDecoder.swift; sourceTree = ""; }; - 0237236E2A003F5C009B91C9 /* Errors.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Errors.swift; sourceTree = ""; }; - 0237236F2A003F5C009B91C9 /* Runner.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Runner.swift; sourceTree = ""; }; - 023723702A003F5C009B91C9 /* Context.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Context.swift; sourceTree = ""; }; - 0237237A2A004051009B91C9 /* KV.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KV.swift; sourceTree = ""; }; - 0237237C2A0041B2009B91C9 /* Geolocation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Geolocation.swift; sourceTree = ""; }; - 0237237E2A00431F009B91C9 /* Watch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Watch.swift; sourceTree = ""; }; - 027BCF1F2A16ABA8009884A0 /* BackgroundRunner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundRunner.swift; sourceTree = ""; }; - 027BCF212A17DE2C009884A0 /* JSResponse.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSResponse.swift; sourceTree = ""; }; - 027BCF222A17DE2C009884A0 /* JSFetch.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSFetch.swift; sourceTree = ""; }; - 0296D4AE2A45FCE500FCD31A /* Device.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Device.swift; sourceTree = ""; }; - 0296D4AF2A45FCE500FCD31A /* Reachability.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Reachability.swift; sourceTree = ""; }; - 02D65FBE2A141B7D007A46A2 /* Notifications.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Notifications.swift; sourceTree = ""; }; - 3B2A61DA5A1F2DD4F959604D /* Pods_Plugin.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Plugin.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 50ADFF88201F53D600D50D53 /* Plugin.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Plugin.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 50ADFF8B201F53D600D50D53 /* BackgroundRunnerPlugin.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BackgroundRunnerPlugin.h; sourceTree = ""; }; - 50ADFF8C201F53D600D50D53 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 50ADFF91201F53D600D50D53 /* PluginTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PluginTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 50ADFF96201F53D600D50D53 /* BackgroundRunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundRunnerTests.swift; sourceTree = ""; }; - 50ADFF98201F53D600D50D53 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 50ADFFA52020D75100D50D53 /* Capacitor.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Capacitor.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 50ADFFA72020EE4F00D50D53 /* BackgroundRunnerPlugin.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BackgroundRunnerPlugin.m; sourceTree = ""; }; - 50E1A94720377CB70090CE1A /* BackgroundRunnerPlugin.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BackgroundRunnerPlugin.swift; sourceTree = ""; }; - 5E23F77F099397094342571A /* Pods-Plugin.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Plugin.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Plugin/Pods-Plugin.debug.xcconfig"; sourceTree = ""; }; - 91781294A431A2A7CC6EB714 /* Pods-Plugin.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Plugin.release.xcconfig"; path = "Pods/Target Support Files/Pods-Plugin/Pods-Plugin.release.xcconfig"; sourceTree = ""; }; - 96ED1B6440D6672E406C8D19 /* Pods-PluginTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PluginTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests.debug.xcconfig"; sourceTree = ""; }; - D400A45B2A853BCE003DAA2F /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; - D400A45D2A853E05003DAA2F /* JSError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSError.swift; sourceTree = ""; }; - F65BB2953ECE002E1EF3E424 /* Pods-PluginTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PluginTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests.release.xcconfig"; sourceTree = ""; }; - F6753A823D3815DB436415E3 /* Pods_PluginTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PluginTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 50ADFF84201F53D600D50D53 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 50ADFFA42020D75100D50D53 /* Capacitor.framework in Frameworks */, - 03FC29A292ACC40490383A1F /* Pods_Plugin.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 50ADFF8E201F53D600D50D53 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 50ADFF92201F53D600D50D53 /* Plugin.framework in Frameworks */, - 20C0B05DCFC8E3958A738AF2 /* Pods_PluginTests.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 023723692A003F3E009B91C9 /* RunnerEngine */ = { - isa = PBXGroup; - children = ( - 027BCF222A17DE2C009884A0 /* JSFetch.swift */, - 027BCF212A17DE2C009884A0 /* JSResponse.swift */, - 023723702A003F5C009B91C9 /* Context.swift */, - 0237236E2A003F5C009B91C9 /* Errors.swift */, - 0237236B2A003F5C009B91C9 /* JSConsole.swift */, - 0237236C2A003F5C009B91C9 /* JSCrypto.swift */, - D400A45D2A853E05003DAA2F /* JSError.swift */, - 0237236D2A003F5C009B91C9 /* JSTextDecoder.swift */, - 0237236A2A003F5C009B91C9 /* JSTextEncoder.swift */, - 0237236F2A003F5C009B91C9 /* Runner.swift */, - ); - path = RunnerEngine; - sourceTree = ""; - }; - 023723792A004039009B91C9 /* CapacitorAPI */ = { - isa = PBXGroup; - children = ( - 0296D4AE2A45FCE500FCD31A /* Device.swift */, - 0237237C2A0041B2009B91C9 /* Geolocation.swift */, - 0237237A2A004051009B91C9 /* KV.swift */, - 02D65FBE2A141B7D007A46A2 /* Notifications.swift */, - 0296D4AF2A45FCE500FCD31A /* Reachability.swift */, - 0237237E2A00431F009B91C9 /* Watch.swift */, - ); - path = CapacitorAPI; - sourceTree = ""; - }; - 50ADFF7E201F53D600D50D53 = { - isa = PBXGroup; - children = ( - 50ADFF8A201F53D600D50D53 /* Plugin */, - 50ADFF95201F53D600D50D53 /* PluginTests */, - 50ADFF89201F53D600D50D53 /* Products */, - 8C8E7744173064A9F6D438E3 /* Pods */, - A797B9EFA3DCEFEA1FBB66A9 /* Frameworks */, - ); - sourceTree = ""; - }; - 50ADFF89201F53D600D50D53 /* Products */ = { - isa = PBXGroup; - children = ( - 50ADFF88201F53D600D50D53 /* Plugin.framework */, - 50ADFF91201F53D600D50D53 /* PluginTests.xctest */, - ); - name = Products; - sourceTree = ""; - }; - 50ADFF8A201F53D600D50D53 /* Plugin */ = { - isa = PBXGroup; - children = ( - 023723792A004039009B91C9 /* CapacitorAPI */, - 023723692A003F3E009B91C9 /* RunnerEngine */, - 50E1A94720377CB70090CE1A /* BackgroundRunnerPlugin.swift */, - 50ADFF8B201F53D600D50D53 /* BackgroundRunnerPlugin.h */, - 50ADFFA72020EE4F00D50D53 /* BackgroundRunnerPlugin.m */, - 50ADFF8C201F53D600D50D53 /* Info.plist */, - 022BF06A29F18D7900485B84 /* RunnerConfig.swift */, - 022BF06C29F18E5D00485B84 /* BackgroundRunnerErrors.swift */, - 0237234C29FC33A9009B91C9 /* WatchConnectivtySessionDelegate.swift */, - 023723622A002600009B91C9 /* Context+CapacitorAPI.swift */, - 027BCF1F2A16ABA8009884A0 /* BackgroundRunner.swift */, - ); - path = Plugin; - sourceTree = ""; - }; - 50ADFF95201F53D600D50D53 /* PluginTests */ = { - isa = PBXGroup; - children = ( - 50ADFF96201F53D600D50D53 /* BackgroundRunnerTests.swift */, - 50ADFF98201F53D600D50D53 /* Info.plist */, - ); - path = PluginTests; - sourceTree = ""; - }; - 8C8E7744173064A9F6D438E3 /* Pods */ = { - isa = PBXGroup; - children = ( - 5E23F77F099397094342571A /* Pods-Plugin.debug.xcconfig */, - 91781294A431A2A7CC6EB714 /* Pods-Plugin.release.xcconfig */, - 96ED1B6440D6672E406C8D19 /* Pods-PluginTests.debug.xcconfig */, - F65BB2953ECE002E1EF3E424 /* Pods-PluginTests.release.xcconfig */, - ); - name = Pods; - sourceTree = ""; - }; - A797B9EFA3DCEFEA1FBB66A9 /* Frameworks */ = { - isa = PBXGroup; - children = ( - D400A45B2A853BCE003DAA2F /* JavaScriptCore.framework */, - 50ADFFA52020D75100D50D53 /* Capacitor.framework */, - 3B2A61DA5A1F2DD4F959604D /* Pods_Plugin.framework */, - F6753A823D3815DB436415E3 /* Pods_PluginTests.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXHeadersBuildPhase section */ - 50ADFF85201F53D600D50D53 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 50ADFF99201F53D600D50D53 /* BackgroundRunnerPlugin.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXHeadersBuildPhase section */ - -/* Begin PBXNativeTarget section */ - 50ADFF87201F53D600D50D53 /* Plugin */ = { - isa = PBXNativeTarget; - buildConfigurationList = 50ADFF9C201F53D600D50D53 /* Build configuration list for PBXNativeTarget "Plugin" */; - buildPhases = ( - AB5B3E54B4E897F32C2279DA /* [CP] Check Pods Manifest.lock */, - 50ADFF83201F53D600D50D53 /* Sources */, - 50ADFF84201F53D600D50D53 /* Frameworks */, - 50ADFF85201F53D600D50D53 /* Headers */, - 50ADFF86201F53D600D50D53 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = Plugin; - productName = Plugin; - productReference = 50ADFF88201F53D600D50D53 /* Plugin.framework */; - productType = "com.apple.product-type.framework"; - }; - 50ADFF90201F53D600D50D53 /* PluginTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 50ADFF9F201F53D600D50D53 /* Build configuration list for PBXNativeTarget "PluginTests" */; - buildPhases = ( - 0596884F929ED6F1DE134961 /* [CP] Check Pods Manifest.lock */, - 50ADFF8D201F53D600D50D53 /* Sources */, - 50ADFF8E201F53D600D50D53 /* Frameworks */, - 50ADFF8F201F53D600D50D53 /* Resources */, - 8E97F58B69A94C6503FC9C85 /* [CP] Embed Pods Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 50ADFF94201F53D600D50D53 /* PBXTargetDependency */, - ); - name = PluginTests; - productName = PluginTests; - productReference = 50ADFF91201F53D600D50D53 /* PluginTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 50ADFF7F201F53D600D50D53 /* Project object */ = { - isa = PBXProject; - attributes = { - LastSwiftUpdateCheck = 0920; - LastUpgradeCheck = 1160; - ORGANIZATIONNAME = "Max Lynch"; - TargetAttributes = { - 50ADFF87201F53D600D50D53 = { - CreatedOnToolsVersion = 9.2; - LastSwiftMigration = 1100; - ProvisioningStyle = Automatic; - }; - 50ADFF90201F53D600D50D53 = { - CreatedOnToolsVersion = 9.2; - LastSwiftMigration = 1100; - ProvisioningStyle = Automatic; - }; - }; - }; - buildConfigurationList = 50ADFF82201F53D600D50D53 /* Build configuration list for PBXProject "Plugin" */; - compatibilityVersion = "Xcode 8.0"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 50ADFF7E201F53D600D50D53; - productRefGroup = 50ADFF89201F53D600D50D53 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 50ADFF87201F53D600D50D53 /* Plugin */, - 50ADFF90201F53D600D50D53 /* PluginTests */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 50ADFF86201F53D600D50D53 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 50ADFF8F201F53D600D50D53 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 0596884F929ED6F1DE134961 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-PluginTests-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; - 8E97F58B69A94C6503FC9C85 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-PluginTests/Pods-PluginTests-frameworks.sh", - "${BUILT_PRODUCTS_DIR}/Capacitor/Capacitor.framework", - "${BUILT_PRODUCTS_DIR}/CapacitorCordova/Cordova.framework", - ); - name = "[CP] Embed Pods Frameworks"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Capacitor.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Cordova.framework", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-PluginTests/Pods-PluginTests-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - AB5B3E54B4E897F32C2279DA /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Plugin-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 50ADFF83201F53D600D50D53 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 023723742A003F5C009B91C9 /* JSTextDecoder.swift in Sources */, - 0237237D2A0041B2009B91C9 /* Geolocation.swift in Sources */, - 50E1A94820377CB70090CE1A /* BackgroundRunnerPlugin.swift in Sources */, - 027BCF232A17DE2C009884A0 /* JSResponse.swift in Sources */, - 023723632A002600009B91C9 /* Context+CapacitorAPI.swift in Sources */, - 023723772A003F5C009B91C9 /* Context.swift in Sources */, - D400A45E2A853E05003DAA2F /* JSError.swift in Sources */, - 0237237B2A004051009B91C9 /* KV.swift in Sources */, - 023723722A003F5C009B91C9 /* JSConsole.swift in Sources */, - 027BCF202A16ABA8009884A0 /* BackgroundRunner.swift in Sources */, - 022BF06B29F18D7900485B84 /* RunnerConfig.swift in Sources */, - 50ADFFA82020EE4F00D50D53 /* BackgroundRunnerPlugin.m in Sources */, - 022BF06D29F18E5D00485B84 /* BackgroundRunnerErrors.swift in Sources */, - 0296D4B02A45FCE500FCD31A /* Device.swift in Sources */, - 023723752A003F5C009B91C9 /* Errors.swift in Sources */, - 0237234D29FC33A9009B91C9 /* WatchConnectivtySessionDelegate.swift in Sources */, - 0237237F2A00431F009B91C9 /* Watch.swift in Sources */, - 02D65FBF2A141B7D007A46A2 /* Notifications.swift in Sources */, - 023723762A003F5C009B91C9 /* Runner.swift in Sources */, - 0296D4B12A45FCE500FCD31A /* Reachability.swift in Sources */, - 023723712A003F5C009B91C9 /* JSTextEncoder.swift in Sources */, - 023723732A003F5C009B91C9 /* JSCrypto.swift in Sources */, - 027BCF242A17DE2C009884A0 /* JSFetch.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 50ADFF8D201F53D600D50D53 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 50ADFF97201F53D600D50D53 /* BackgroundRunnerTests.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 50ADFF94201F53D600D50D53 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 50ADFF87201F53D600D50D53 /* Plugin */; - targetProxy = 50ADFF93201F53D600D50D53 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin XCBuildConfiguration section */ - 50ADFF9A201F53D600D50D53 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - FRAMEWORK_SEARCH_PATHS = ( - "\"${BUILT_PRODUCTS_DIR}/Capacitor\"", - "\"${BUILT_PRODUCTS_DIR}/CapacitorCordova\"", - ); - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Debug; - }; - 50ADFF9B201F53D600D50D53 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - FRAMEWORK_SEARCH_PATHS = ( - "\"${BUILT_PRODUCTS_DIR}/Capacitor\"", - "\"${BUILT_PRODUCTS_DIR}/CapacitorCordova\"", - ); - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 13.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - VALIDATE_PRODUCT = YES; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Release; - }; - 50ADFF9D201F53D600D50D53 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 5E23F77F099397094342571A /* Pods-Plugin.debug.xcconfig */; - buildSettings = { - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = ""; - CODE_SIGN_STYLE = Automatic; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = Plugin/Info.plist; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 14.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks $(FRAMEWORK_SEARCH_PATHS)\n$(FRAMEWORK_SEARCH_PATHS)\n$(FRAMEWORK_SEARCH_PATHS)"; - ONLY_ACTIVE_ARCH = YES; - PRODUCT_BUNDLE_IDENTIFIER = com.getcapacitor.Plugin; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; - SKIP_INSTALL = YES; - SUPPORTS_MACCATALYST = NO; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 50ADFF9E201F53D600D50D53 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 91781294A431A2A7CC6EB714 /* Pods-Plugin.release.xcconfig */; - buildSettings = { - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = ""; - CODE_SIGN_STYLE = Automatic; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = Plugin/Info.plist; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 14.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks $(FRAMEWORK_SEARCH_PATHS)"; - ONLY_ACTIVE_ARCH = NO; - PRODUCT_BUNDLE_IDENTIFIER = com.getcapacitor.Plugin; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; - SKIP_INSTALL = YES; - SUPPORTS_MACCATALYST = NO; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Release; - }; - 50ADFFA0201F53D600D50D53 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 96ED1B6440D6672E406C8D19 /* Pods-PluginTests.debug.xcconfig */; - buildSettings = { - CODE_SIGN_STYLE = Automatic; - INFOPLIST_FILE = PluginTests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.getcapacitor.PluginTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 50ADFFA1201F53D600D50D53 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = F65BB2953ECE002E1EF3E424 /* Pods-PluginTests.release.xcconfig */; - buildSettings = { - CODE_SIGN_STYLE = Automatic; - INFOPLIST_FILE = PluginTests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.getcapacitor.PluginTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 50ADFF82201F53D600D50D53 /* Build configuration list for PBXProject "Plugin" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 50ADFF9A201F53D600D50D53 /* Debug */, - 50ADFF9B201F53D600D50D53 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 50ADFF9C201F53D600D50D53 /* Build configuration list for PBXNativeTarget "Plugin" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 50ADFF9D201F53D600D50D53 /* Debug */, - 50ADFF9E201F53D600D50D53 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 50ADFF9F201F53D600D50D53 /* Build configuration list for PBXNativeTarget "PluginTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 50ADFFA0201F53D600D50D53 /* Debug */, - 50ADFFA1201F53D600D50D53 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 50ADFF7F201F53D600D50D53 /* Project object */; -} diff --git a/packages/capacitor-plugin/ios/Plugin.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/packages/capacitor-plugin/ios/Plugin.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 919434a6..00000000 --- a/packages/capacitor-plugin/ios/Plugin.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/packages/capacitor-plugin/ios/Plugin.xcodeproj/xcshareddata/xcschemes/Plugin.xcscheme b/packages/capacitor-plugin/ios/Plugin.xcodeproj/xcshareddata/xcschemes/Plugin.xcscheme deleted file mode 100644 index 303f2621..00000000 --- a/packages/capacitor-plugin/ios/Plugin.xcodeproj/xcshareddata/xcschemes/Plugin.xcscheme +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/capacitor-plugin/ios/Plugin.xcodeproj/xcshareddata/xcschemes/PluginTests.xcscheme b/packages/capacitor-plugin/ios/Plugin.xcodeproj/xcshareddata/xcschemes/PluginTests.xcscheme deleted file mode 100644 index 3d8c88d2..00000000 --- a/packages/capacitor-plugin/ios/Plugin.xcodeproj/xcshareddata/xcschemes/PluginTests.xcscheme +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/capacitor-plugin/ios/Plugin.xcworkspace/contents.xcworkspacedata b/packages/capacitor-plugin/ios/Plugin.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index afad624e..00000000 --- a/packages/capacitor-plugin/ios/Plugin.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - diff --git a/packages/capacitor-plugin/ios/Plugin.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/capacitor-plugin/ios/Plugin.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d98100..00000000 --- a/packages/capacitor-plugin/ios/Plugin.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/packages/capacitor-plugin/ios/Plugin/BackgroundRunner.swift b/packages/capacitor-plugin/ios/Plugin/BackgroundRunner.swift deleted file mode 100644 index d2f7d1fe..00000000 --- a/packages/capacitor-plugin/ios/Plugin/BackgroundRunner.swift +++ /dev/null @@ -1,212 +0,0 @@ -import Foundation -import Capacitor -import BackgroundTasks -import JavaScriptCore - -public class BackgroundRunner { - public static let shared = BackgroundRunner() - public var config: RunnerConfig? - - private var runner = Runner() - - public init() { - do { - config = try self.loadRunnerConfig() - } catch { - print("could not initialize BackgroundRunner: \(error)") - } - } - - public func scheduleBackgroundTasks() throws { - guard let config = config else { - throw BackgroundRunnerPluginError.noRunnerConfig - } - - if !config.autoSchedule { - return - } - - guard let interval = config.interval else { - throw BackgroundRunnerPluginError.invalidRunnerConfig(reason: "cannot register background task without a configured interval") - } - - let request = BGAppRefreshTaskRequest(identifier: config.label) - request.earliestBeginDate = Date(timeIntervalSinceNow: Double(interval) * 60) - - print("Scheduling \(config.label)") - - try BGTaskScheduler.shared.submit(request) - } - - public func registerBackgroundTask() throws { - guard let config = config else { - throw BackgroundRunnerPluginError.noRunnerConfig - } - - BGTaskScheduler.shared.register(forTaskWithIdentifier: config.label, using: nil) { task in - do { - task.expirationHandler = { - print("task timed out") - } - - _ = try BackgroundRunner.shared.execute(config: config) - - task.setTaskCompleted(success: true) - - if config.repeats { - try self.scheduleBackgroundTasks() - } - } catch { - print("background task error: \(error)") - task.setTaskCompleted(success: false) - } - } - } - - // swiftlint:disable:next cyclomatic_complexity function_body_length - public func execute(config: RunnerConfig, inputArgs: [String: Any]? = nil, callbackId: String? = nil) throws -> [String: Any]? { - do { - let context = try initContext(config: config, callbackId: callbackId) - - let waitGroup = DispatchGroup() - - var result: [String: Any]? - var rejectionErr: JSError? - - let resolveFunc: @convention(block)(JavaScriptCore.JSValue) -> Void = { returnObj in - if !returnObj.isUndefined && !returnObj.isNull { - var dict: [String: Any] = [:] - - returnObj.toDictionary().forEach { key, value in - dict[String(describing: key)] = value - } - - result = dict - } - - waitGroup.leave() - return - } - - let rejectFunc: @convention(block)(JavaScriptCore.JSValue) -> Void = { rejectObj in - var rejectionTitle = "Error" - var rejectionMessage = "" - - if !rejectObj.isUndefined && !rejectObj.isNull { - if let errStr = rejectObj.toString() { - let split = errStr.split(separator: ":", maxSplits: 1) - if split.count == 0 { - rejectionMessage = String(split.first ?? "") - } else { - rejectionTitle = String(split.first ?? "Error") - rejectionMessage = String(split.last ?? "") - } - } - - if rejectObj.isObject, let errDict = rejectObj.toDictionary() { - if let errTitle = errDict["name"] as? String { - rejectionTitle = errTitle - } - - if let errMsg = errDict["message"] as? String { - rejectionMessage = errMsg - } - } - } - - rejectionErr = JSError(message: "\(rejectionTitle): \(rejectionMessage)") - - waitGroup.leave() - return - } - - var args: [String: Any] = [:] - - var callbacks: [String: Any] = [:] - callbacks["__cbr::resolve"] = resolveFunc - callbacks["__cbr::reject"] = rejectFunc - - args["callbacks"] = callbacks - args["dataArgs"] = inputArgs - - waitGroup.enter() - - try context.dispatchEvent(event: config.event, details: args) - - waitGroup.wait() - - if let rejection = rejectionErr { - throw EngineError.jsException(details: rejection.message) - } - - return result - } catch { - print("error executing task: \(error)") - throw error - } - } - - public func dispatchEvent(event: String, inputArgs: [String: Any]?, callbackId: String? = nil) throws { - if let config = config { - let waitGroup = DispatchGroup() - waitGroup.enter() - - var err: Error? - - // swiftlint:disable:next unowned_variable_capture - DispatchQueue.global(qos: .userInitiated).async { [unowned self] in - do { - _ = try self.execute(config: config, inputArgs: inputArgs, callbackId: callbackId) - } catch { - err = error - print("[\(config.label)]: \(error)") - } - - waitGroup.leave() - } - - waitGroup.wait() - - if let err = err { - throw err - } - } - } - - private func loadRunnerConfig() throws -> RunnerConfig? { - guard let capacitorConfigFileURL = Bundle.main.url(forResource: "capacitor.config.json", withExtension: nil) else { - throw BackgroundRunnerPluginError.runnerError(reason: "capacitor.config.json file not found") - } - - let capacitorConfigFileData = try Data(contentsOf: capacitorConfigFileURL) - - if let capConfig = JSTypes.coerceDictionaryToJSObject(try JSONSerialization.jsonObject(with: capacitorConfigFileData) as? [String: Any]) { - if let jsonConfig = capConfig[keyPath: "plugins.BackgroundRunner"] as? JSObject { - return try RunnerConfig(from: jsonConfig) - } - } - - return nil - } - - private func initContext(config: RunnerConfig, callbackId: String?) throws -> Context { - guard let srcFileURL = Bundle.main.url(forResource: config.src, withExtension: nil, subdirectory: "public") else { - throw BackgroundRunnerPluginError.runnerError(reason: "source file not found") - } - - var contextName = config.label - if let callbackId = callbackId { - contextName = "\(contextName)-\(callbackId)" - } - - let srcFile = try String(contentsOf: srcFileURL) - - let context = try runner.createContext(name: contextName) - - context.setupCapacitorAPI() - - _ = try context.execute(code: srcFile) - - return context - } -} diff --git a/packages/capacitor-plugin/ios/Plugin/BackgroundRunnerPlugin.h b/packages/capacitor-plugin/ios/Plugin/BackgroundRunnerPlugin.h deleted file mode 100644 index f2bd9e0b..00000000 --- a/packages/capacitor-plugin/ios/Plugin/BackgroundRunnerPlugin.h +++ /dev/null @@ -1,10 +0,0 @@ -#import - -//! Project version number for Plugin. -FOUNDATION_EXPORT double PluginVersionNumber; - -//! Project version string for Plugin. -FOUNDATION_EXPORT const unsigned char PluginVersionString[]; - -// In this header, you should import all the public headers of your framework using statements like #import - diff --git a/packages/capacitor-plugin/ios/Plugin/BackgroundRunnerPlugin.m b/packages/capacitor-plugin/ios/Plugin/BackgroundRunnerPlugin.m deleted file mode 100644 index 97845223..00000000 --- a/packages/capacitor-plugin/ios/Plugin/BackgroundRunnerPlugin.m +++ /dev/null @@ -1,12 +0,0 @@ -#import -#import - -// Define the plugin using the CAP_PLUGIN Macro, and -// each method the plugin supports using the CAP_PLUGIN_METHOD macro. -CAP_PLUGIN(BackgroundRunnerPlugin, "BackgroundRunner", - CAP_PLUGIN_METHOD(dispatchEvent, CAPPluginReturnPromise); - CAP_PLUGIN_METHOD(registerBackgroundTask, CAPPluginReturnPromise); - CAP_PLUGIN_METHOD(checkPermissions, CAPPluginReturnPromise); - CAP_PLUGIN_METHOD(requestPermissions, CAPPluginReturnPromise); - CAP_PLUGIN_METHOD(removeNotificationListeners, CAPPluginReturnPromise); -) diff --git a/packages/capacitor-plugin/ios/Plugin/CapacitorAPI/Geolocation.swift b/packages/capacitor-plugin/ios/Plugin/CapacitorAPI/Geolocation.swift deleted file mode 100644 index c302c9a6..00000000 --- a/packages/capacitor-plugin/ios/Plugin/CapacitorAPI/Geolocation.swift +++ /dev/null @@ -1,190 +0,0 @@ -import Foundation -import JavaScriptCore -import CoreLocation - -@objc protocol CapacitorGeolocationExports: JSExport { - var isWatchingPosition: Bool { get } - func startWatchingPosition(_ highAccuracy: Bool) - func stopWatchingPosition() - func getCurrentPosition() -> [String: Any]? -} - -enum CapacitorGeolocationErrors: Error, Equatable { - case unauthorized -} - -class CapacitorGeolocation: NSObject, CapacitorGeolocationExports, CLLocationManagerDelegate { - private weak var context: Context? - private var pendingCurrentLocationCalls: [Int: (Result) -> Void] = [:] - private var isWatchingLocation: Bool = false - private let locationManager: CLLocationManager - - private var permissionContinuation: CheckedContinuation? - - var isWatchingPosition: Bool { - return isWatchingLocation - } - - init(context: Context? = nil) { - self.locationManager = CLLocationManager() - super.init() - - self.context = context - self.locationManager.delegate = self - - self.locationManager.allowsBackgroundLocationUpdates = true - self.locationManager.desiredAccuracy = kCLLocationAccuracyKilometer - self.locationManager.pausesLocationUpdatesAutomatically = false - } - - static func getCurrentKnownLocation() -> CLLocation? { - return CLLocationManager().location - } - - static func checkPermission() -> String { - if !CLLocationManager.locationServicesEnabled() { - return "denied" - } - - var permission: String = "prompt" - - switch CLLocationManager.authorizationStatus() { - case .authorized, .authorizedWhenInUse, .authorizedAlways: - permission = "granted" - case .notDetermined: - permission = "prompt" - case .denied, .restricted: - permission = "denied" - default: - permission = "prompt" - } - - return permission - } - - func requestPermission() async throws { - if !CLLocationManager.locationServicesEnabled() { - return - } - - if CLLocationManager.authorizationStatus() != .notDetermined { - return - } - - return try await withCheckedThrowingContinuation({ (continuation: CheckedContinuation) in - permissionContinuation = continuation - - DispatchQueue.main.async { - self.locationManager.requestAlwaysAuthorization() - } - }) - } - - func startWatchingPosition(_ highAccuracy: Bool) { - do { - if CapacitorGeolocation.checkPermission() != "granted" { - throw CapacitorGeolocationErrors.unauthorized - } - - DispatchQueue.main.sync { - if highAccuracy { - self.locationManager.startUpdatingLocation() - } else { - self.locationManager.startMonitoringSignificantLocationChanges() - } - } - - self.isWatchingLocation = true - } catch { - JSContext.current().exception = JSValue(newErrorFromMessage: "\(error)", in: JSContext.current()) - } - } - - func stopWatchingPosition() { - DispatchQueue.main.sync { - self.locationManager.stopUpdatingLocation() - self.locationManager.stopMonitoringSignificantLocationChanges() - } - - self.isWatchingLocation = false - } - - func getCurrentPosition() -> [String: Any]? { - do { - if CapacitorGeolocation.checkPermission() != "granted" { - throw CapacitorGeolocationErrors.unauthorized - } - - guard let lastLocation = self.locationManager.location else { - return nil - } - - return buildLocationDict(location: lastLocation) - } catch { - JSContext.current().exception = JSValue(newErrorFromMessage: "\(error)", in: JSContext.current()) - - return nil - } - } - - func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { - if let context = self.context, self.isWatchingLocation { - let locations: [[String: Any]] = locations.map { location in - return buildLocationDict(location: location) - } - - var details: [String: Any] = [:] - details["locations"] = locations - - try? context.dispatchEvent(event: "currentLocation", details: details) - } - - pendingCurrentLocationCalls.forEach { (callId: Int, callback: (Result) -> Void) in - pendingCurrentLocationCalls.removeValue(forKey: callId) - callback(.success(locations.last)) - } - - if let location = locations.last { - print("\(location.coordinate.latitude),\(location.coordinate.longitude)") - } - } - - func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { - if let continuation = permissionContinuation { - continuation.resume(throwing: error) - permissionContinuation = nil - } - - if let context = context, self.isWatchingLocation { - var details: [String: Any] = [:] - details["error"] = error - - try? context.dispatchEvent(event: "currentLocation", details: details) - } - - pendingCurrentLocationCalls.forEach { (callId: Int, callback: (Result) -> Void) in - pendingCurrentLocationCalls.removeValue(forKey: callId) - callback(.failure(error)) - } - } - - func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) { - if let continuation = permissionContinuation { - continuation.resume() - permissionContinuation = nil - } - } - - private func buildLocationDict(location: CLLocation) -> [String: Any] { - var coords: [String: Any] = [:] - coords["latitude"] = location.coordinate.latitude - coords["longitude"] = location.coordinate.longitude - coords["accuracy"] = location.horizontalAccuracy - coords["altitude"] = location.altitude - coords["altitudeAccuracy"] = location.verticalAccuracy - coords["speed"] = location.speed - coords["heading"] = location.course - - return coords - } -} diff --git a/packages/capacitor-plugin/ios/Plugin/Context+CapacitorAPI.swift b/packages/capacitor-plugin/ios/Plugin/Context+CapacitorAPI.swift deleted file mode 100644 index 0c4e9911..00000000 --- a/packages/capacitor-plugin/ios/Plugin/Context+CapacitorAPI.swift +++ /dev/null @@ -1,12 +0,0 @@ -import Foundation - -extension Context { - public func setupCapacitorAPI() { - jsContext.setObject(CapacitorKVStore.self, forKeyedSubscript: "CapacitorKV" as NSString) - jsContext.setObject(CapacitorGeolocation(context: self), forKeyedSubscript: "CapacitorGeolocation" as NSString) - jsContext.setObject(CapacitorWatch(), forKeyedSubscript: "CapacitorWatch" as NSString) - jsContext.setObject(CapacitorNotifications.self, forKeyedSubscript: "CapacitorNotifications" as NSString) - jsContext.setObject(CapacitorDevice(), forKeyedSubscript: "CapacitorDevice" as NSString) - jsContext.setObject(CapacitorApp.self, forKeyedSubscript: "CapacitorApp" as NSString) - } -} diff --git a/packages/capacitor-plugin/ios/Plugin/Info.plist b/packages/capacitor-plugin/ios/Plugin/Info.plist deleted file mode 100644 index 1007fd9d..00000000 --- a/packages/capacitor-plugin/ios/Plugin/Info.plist +++ /dev/null @@ -1,24 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - FMWK - CFBundleShortVersionString - 1.0 - CFBundleVersion - $(CURRENT_PROJECT_VERSION) - NSPrincipalClass - - - diff --git a/packages/capacitor-plugin/ios/PluginTests/BackgroundRunnerTests.swift b/packages/capacitor-plugin/ios/PluginTests/BackgroundRunnerTests.swift deleted file mode 100644 index 67f05586..00000000 --- a/packages/capacitor-plugin/ios/PluginTests/BackgroundRunnerTests.swift +++ /dev/null @@ -1,23 +0,0 @@ -import XCTest -@testable import Plugin - -class BackgroundRunnerTests: XCTestCase { - func testKeyValueAPI() throws { - let runner = Runner() - let context = try runner.createContext(name: "io.backgroundrunner.testkv") - context.setupCapacitorAPI() - - _ = try context.execute(code: "CapacitorKV.set('test', 'hello world');") - - let value = try context.execute(code: "CapacitorKV.get('test');") - - XCTAssertEqual(value?.toString(), "hello world") - - _ = try context.execute(code: "CapacitorKV.remove('test');") - - let nullValue = try context.execute(code: "CapacitorKV.get('test');") - - XCTAssertTrue(nullValue?.isUndefined ?? false) - - } -} diff --git a/packages/capacitor-plugin/ios/PluginTests/Info.plist b/packages/capacitor-plugin/ios/PluginTests/Info.plist deleted file mode 100644 index 6c40a6cd..00000000 --- a/packages/capacitor-plugin/ios/PluginTests/Info.plist +++ /dev/null @@ -1,22 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - BNDL - CFBundleShortVersionString - 1.0 - CFBundleVersion - 1 - - diff --git a/packages/capacitor-plugin/ios/Podfile b/packages/capacitor-plugin/ios/Podfile deleted file mode 100644 index 0a77c49b..00000000 --- a/packages/capacitor-plugin/ios/Podfile +++ /dev/null @@ -1,16 +0,0 @@ -platform :ios, '14.0' - -def capacitor_pods - # Comment the next line if you're not using Swift and don't want to use dynamic frameworks - use_frameworks! - pod 'Capacitor', :path => '../node_modules/@capacitor/ios' - pod 'CapacitorCordova', :path => '../node_modules/@capacitor/ios' -end - -target 'Plugin' do - capacitor_pods -end - -target 'PluginTests' do - capacitor_pods -end diff --git a/packages/capacitor-plugin/ios/Sources/CapacitorBackgroundRunner/BackgroundRunner.swift b/packages/capacitor-plugin/ios/Sources/CapacitorBackgroundRunner/BackgroundRunner.swift new file mode 100644 index 00000000..51f37258 --- /dev/null +++ b/packages/capacitor-plugin/ios/Sources/CapacitorBackgroundRunner/BackgroundRunner.swift @@ -0,0 +1,229 @@ +import BackgroundTasks +import Capacitor +import Foundation +import JavaScriptCore + +#if canImport(RunnerEngine) + import RunnerEngine +#endif + +public class BackgroundRunner { + public static let shared = BackgroundRunner() + public var config: RunnerConfig? + + private var runner = Runner() + + public init() { + do { + config = try self.loadRunnerConfig() + } catch { + print("could not initialize BackgroundRunner: \(error)") + } + } + + public func scheduleBackgroundTasks() throws { + guard let config = config else { + throw BackgroundRunnerPluginError.noRunnerConfig + } + + if !config.autoSchedule { + return + } + + guard let interval = config.interval else { + throw BackgroundRunnerPluginError.invalidRunnerConfig( + reason: "cannot register background task without a configured interval") + } + + let request = BGAppRefreshTaskRequest(identifier: config.label) + request.earliestBeginDate = Date(timeIntervalSinceNow: Double(interval) * 60) + + print("Scheduling \(config.label)") + + try BGTaskScheduler.shared.submit(request) + } + + public func registerBackgroundTask() throws { + guard let config = config else { + throw BackgroundRunnerPluginError.noRunnerConfig + } + + BGTaskScheduler.shared.register(forTaskWithIdentifier: config.label, using: nil) { task in + do { + task.expirationHandler = { + print("task timed out") + } + + _ = try BackgroundRunner.shared.execute(config: config) + + task.setTaskCompleted(success: true) + + if config.repeats { + try self.scheduleBackgroundTasks() + } + } catch { + print("background task error: \(error)") + task.setTaskCompleted(success: false) + } + } + } + + // swiftlint:disable:next cyclomatic_complexity function_body_length + public func execute( + config: RunnerConfig, inputArgs: [String: Any]? = nil, callbackId: String? = nil + ) throws -> [String: Any]? { + do { + let context = try initContext(config: config, callbackId: callbackId) + + let waitGroup = DispatchGroup() + + var result: [String: Any]? + var rejectionErr: JSError? + + let resolveFunc: @convention(block) (JavaScriptCore.JSValue) -> Void = { returnObj in + if !returnObj.isUndefined && !returnObj.isNull { + var dict: [String: Any] = [:] + + returnObj.toDictionary().forEach { key, value in + dict[String(describing: key)] = value + } + + result = dict + } + + waitGroup.leave() + return + } + + let rejectFunc: @convention(block) (JavaScriptCore.JSValue) -> Void = { rejectObj in + var rejectionTitle = "Error" + var rejectionMessage = "" + + if !rejectObj.isUndefined && !rejectObj.isNull { + if let errStr = rejectObj.toString() { + let split = errStr.split(separator: ":", maxSplits: 1) + if split.count == 0 { + rejectionMessage = String(split.first ?? "") + } else { + rejectionTitle = String(split.first ?? "Error") + rejectionMessage = String(split.last ?? "") + } + } + + if rejectObj.isObject, let errDict = rejectObj.toDictionary() { + if let errTitle = errDict["name"] as? String { + rejectionTitle = errTitle + } + + if let errMsg = errDict["message"] as? String { + rejectionMessage = errMsg + } + } + } + + rejectionErr = JSError(message: "\(rejectionTitle): \(rejectionMessage)") + + waitGroup.leave() + return + } + + var args: [String: Any] = [:] + + var callbacks: [String: Any] = [:] + callbacks["__cbr::resolve"] = resolveFunc + callbacks["__cbr::reject"] = rejectFunc + + args["callbacks"] = callbacks + args["dataArgs"] = inputArgs + + waitGroup.enter() + + try context.dispatchEvent(event: config.event, details: args) + + waitGroup.wait() + + if let rejection = rejectionErr { + throw EngineError.jsException(details: rejection.toString()) + } + + return result + } catch { + print("error executing task: \(error)") + throw error + } + } + + public func dispatchEvent(event: String, inputArgs: [String: Any]?, callbackId: String? = nil) + throws + { + if let config = config { + let waitGroup = DispatchGroup() + waitGroup.enter() + + var err: Error? + + // swiftlint:disable:next unowned_variable_capture + DispatchQueue.global(qos: .userInitiated).async { [unowned self] in + do { + _ = try self.execute(config: config, inputArgs: inputArgs, callbackId: callbackId) + } catch { + err = error + print("[\(config.label)]: \(error)") + } + + waitGroup.leave() + } + + waitGroup.wait() + + if let err = err { + throw err + } + } + } + + private func loadRunnerConfig() throws -> RunnerConfig? { + guard + let capacitorConfigFileURL = Bundle.main.url( + forResource: "capacitor.config.json", withExtension: nil) + else { + throw BackgroundRunnerPluginError.runnerError(reason: "capacitor.config.json file not found") + } + + let capacitorConfigFileData = try Data(contentsOf: capacitorConfigFileURL) + + if let capConfig = JSTypes.coerceDictionaryToJSObject( + try JSONSerialization.jsonObject(with: capacitorConfigFileData) as? [String: Any]) + { + if let jsonConfig = capConfig[keyPath: "plugins.BackgroundRunner"] as? JSObject { + return try RunnerConfig(from: jsonConfig) + } + } + + return nil + } + + private func initContext(config: RunnerConfig, callbackId: String?) throws -> Context { + guard + let srcFileURL = Bundle.main.url( + forResource: config.src, withExtension: nil, subdirectory: "public") + else { + throw BackgroundRunnerPluginError.runnerError(reason: "source file not found") + } + + var contextName = config.label + if let callbackId = callbackId { + contextName = "\(contextName)-\(callbackId)" + } + + let srcFile = try String(contentsOf: srcFileURL) + + let context = try runner.createContext(name: contextName) + + context.setupCapacitorAPI() + + _ = try context.execute(code: srcFile) + + return context + } +} diff --git a/packages/capacitor-plugin/ios/Plugin/BackgroundRunnerErrors.swift b/packages/capacitor-plugin/ios/Sources/CapacitorBackgroundRunner/BackgroundRunnerPluginError.swift similarity index 100% rename from packages/capacitor-plugin/ios/Plugin/BackgroundRunnerErrors.swift rename to packages/capacitor-plugin/ios/Sources/CapacitorBackgroundRunner/BackgroundRunnerPluginError.swift diff --git a/packages/capacitor-plugin/ios/Plugin/CapacitorAPI/App.swift b/packages/capacitor-plugin/ios/Sources/CapacitorBackgroundRunner/CapacitorAPI/App.swift similarity index 100% rename from packages/capacitor-plugin/ios/Plugin/CapacitorAPI/App.swift rename to packages/capacitor-plugin/ios/Sources/CapacitorBackgroundRunner/CapacitorAPI/App.swift diff --git a/packages/capacitor-plugin/ios/Plugin/CapacitorAPI/Device.swift b/packages/capacitor-plugin/ios/Sources/CapacitorBackgroundRunner/CapacitorAPI/Device.swift similarity index 100% rename from packages/capacitor-plugin/ios/Plugin/CapacitorAPI/Device.swift rename to packages/capacitor-plugin/ios/Sources/CapacitorBackgroundRunner/CapacitorAPI/Device.swift diff --git a/packages/capacitor-plugin/ios/Sources/CapacitorBackgroundRunner/CapacitorAPI/Geolocation.swift b/packages/capacitor-plugin/ios/Sources/CapacitorBackgroundRunner/CapacitorAPI/Geolocation.swift new file mode 100644 index 00000000..18c84052 --- /dev/null +++ b/packages/capacitor-plugin/ios/Sources/CapacitorBackgroundRunner/CapacitorAPI/Geolocation.swift @@ -0,0 +1,203 @@ +import CoreLocation +import Foundation +import JavaScriptCore + +#if canImport(RunnerEngine) + import RunnerEngine +#endif + +@objc protocol CapacitorGeolocationExports: JSExport { + var isWatchingPosition: Bool { get } + func startWatchingPosition(_ highAccuracy: Bool) + func stopWatchingPosition() + func getCurrentPosition() -> [String: Any]? +} + +enum CapacitorGeolocationErrors: Error, Equatable { + case unauthorized +} + +class CapacitorGeolocation: NSObject, CapacitorGeolocationExports, CLLocationManagerDelegate { + private weak var context: Context? + private var pendingCurrentLocationCalls: [Int: (Result) -> Void] = [:] + private var isWatchingLocation: Bool = false + private let locationManager: CLLocationManager + + private var permissionContinuation: CheckedContinuation? + + var isWatchingPosition: Bool { + return isWatchingLocation + } + + init(context: Context? = nil) { + self.locationManager = CLLocationManager() + super.init() + + self.context = context + self.locationManager.delegate = self + + if CLLocationManager.authorizationStatus() == .authorizedAlways { + self.locationManager.allowsBackgroundLocationUpdates = true + self.locationManager.desiredAccuracy = kCLLocationAccuracyKilometer + self.locationManager.pausesLocationUpdatesAutomatically = false + } + + + } + + static func getCurrentKnownLocation() -> CLLocation? { + return CLLocationManager().location + } + + static func checkPermission() -> String { + if !CLLocationManager.locationServicesEnabled() { + return "denied" + } + + var permission: String = "prompt" + + switch CLLocationManager.authorizationStatus() { + case .authorized, .authorizedWhenInUse, .authorizedAlways: + permission = "granted" + case .notDetermined: + permission = "prompt" + case .denied, .restricted: + permission = "denied" + default: + permission = "prompt" + } + + return permission + } + + func requestPermission() async throws { + if !CLLocationManager.locationServicesEnabled() { + return + } + + if CLLocationManager.authorizationStatus() != .notDetermined { + return + } + + return try await withCheckedThrowingContinuation({ + (continuation: CheckedContinuation) in + permissionContinuation = continuation + + DispatchQueue.main.async { + self.locationManager.requestAlwaysAuthorization() + } + }) + } + + func startWatchingPosition(_ highAccuracy: Bool) { + do { + if CapacitorGeolocation.checkPermission() != "granted" { + throw CapacitorGeolocationErrors.unauthorized + } + + DispatchQueue.main.sync { + if highAccuracy { + self.locationManager.startUpdatingLocation() + } else { + self.locationManager.startMonitoringSignificantLocationChanges() + } + } + + self.isWatchingLocation = true + } catch { + JSContext.current().exception = JSValue( + newErrorFromMessage: "\(error)", in: JSContext.current()) + } + } + + func stopWatchingPosition() { + DispatchQueue.main.sync { + self.locationManager.stopUpdatingLocation() + self.locationManager.stopMonitoringSignificantLocationChanges() + } + + self.isWatchingLocation = false + } + + func getCurrentPosition() -> [String: Any]? { + do { + if CapacitorGeolocation.checkPermission() != "granted" { + throw CapacitorGeolocationErrors.unauthorized + } + + guard let lastLocation = self.locationManager.location else { + return nil + } + + return buildLocationDict(location: lastLocation) + } catch { + JSContext.current().exception = JSValue( + newErrorFromMessage: "\(error)", in: JSContext.current()) + + return nil + } + } + + func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { + if let context = self.context, self.isWatchingLocation { + let locations: [[String: Any]] = locations.map { location in + return buildLocationDict(location: location) + } + + var details: [String: Any] = [:] + details["locations"] = locations + + try? context.dispatchEvent(event: "currentLocation", details: details) + } + + pendingCurrentLocationCalls.forEach { + (callId: Int, callback: (Result) -> Void) in + pendingCurrentLocationCalls.removeValue(forKey: callId) + callback(.success(locations.last)) + } + + if let location = locations.last { + print("\(location.coordinate.latitude),\(location.coordinate.longitude)") + } + } + + func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { + if let continuation = permissionContinuation { + continuation.resume(throwing: error) + permissionContinuation = nil + } + + if let context = context, self.isWatchingLocation { + var details: [String: Any] = [:] + details["error"] = error + + try? context.dispatchEvent(event: "currentLocation", details: details) + } + + pendingCurrentLocationCalls.forEach { + (callId: Int, callback: (Result) -> Void) in + pendingCurrentLocationCalls.removeValue(forKey: callId) + callback(.failure(error)) + } + } + + func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) { + if let continuation = permissionContinuation { + continuation.resume() + permissionContinuation = nil + } + } + + private func buildLocationDict(location: CLLocation) -> [String: Any] { + var coords: [String: Any] = [:] + coords["latitude"] = location.coordinate.latitude + coords["longitude"] = location.coordinate.longitude + coords["accuracy"] = location.horizontalAccuracy + coords["altitude"] = location.altitude + coords["altitudeAccuracy"] = location.verticalAccuracy + coords["speed"] = location.speed + coords["heading"] = location.course + + return coords + } +} diff --git a/packages/capacitor-plugin/ios/Plugin/CapacitorAPI/KV.swift b/packages/capacitor-plugin/ios/Sources/CapacitorBackgroundRunner/CapacitorAPI/KV.swift similarity index 100% rename from packages/capacitor-plugin/ios/Plugin/CapacitorAPI/KV.swift rename to packages/capacitor-plugin/ios/Sources/CapacitorBackgroundRunner/CapacitorAPI/KV.swift diff --git a/packages/capacitor-plugin/ios/Plugin/CapacitorAPI/Notifications.swift b/packages/capacitor-plugin/ios/Sources/CapacitorBackgroundRunner/CapacitorAPI/Notifications.swift similarity index 99% rename from packages/capacitor-plugin/ios/Plugin/CapacitorAPI/Notifications.swift rename to packages/capacitor-plugin/ios/Sources/CapacitorBackgroundRunner/CapacitorAPI/Notifications.swift index 0ce6ee23..5a84e306 100644 --- a/packages/capacitor-plugin/ios/Plugin/CapacitorAPI/Notifications.swift +++ b/packages/capacitor-plugin/ios/Sources/CapacitorBackgroundRunner/CapacitorAPI/Notifications.swift @@ -1,4 +1,5 @@ import Foundation +import UIKit import JavaScriptCore import UserNotifications diff --git a/packages/capacitor-plugin/ios/Plugin/CapacitorAPI/Reachability.swift b/packages/capacitor-plugin/ios/Sources/CapacitorBackgroundRunner/CapacitorAPI/Reachability.swift similarity index 100% rename from packages/capacitor-plugin/ios/Plugin/CapacitorAPI/Reachability.swift rename to packages/capacitor-plugin/ios/Sources/CapacitorBackgroundRunner/CapacitorAPI/Reachability.swift diff --git a/packages/capacitor-plugin/ios/Plugin/CapacitorAPI/Watch.swift b/packages/capacitor-plugin/ios/Sources/CapacitorBackgroundRunner/CapacitorAPI/Watch.swift similarity index 100% rename from packages/capacitor-plugin/ios/Plugin/CapacitorAPI/Watch.swift rename to packages/capacitor-plugin/ios/Sources/CapacitorBackgroundRunner/CapacitorAPI/Watch.swift diff --git a/packages/capacitor-plugin/ios/Plugin/BackgroundRunnerPlugin.swift b/packages/capacitor-plugin/ios/Sources/CapacitorBackgroundRunner/CapacitorBackgroundRunner.swift similarity index 91% rename from packages/capacitor-plugin/ios/Plugin/BackgroundRunnerPlugin.swift rename to packages/capacitor-plugin/ios/Sources/CapacitorBackgroundRunner/CapacitorBackgroundRunner.swift index 9c4d3c3f..6d0b0d24 100644 --- a/packages/capacitor-plugin/ios/Plugin/BackgroundRunnerPlugin.swift +++ b/packages/capacitor-plugin/ios/Sources/CapacitorBackgroundRunner/CapacitorBackgroundRunner.swift @@ -4,9 +4,18 @@ import WatchConnectivity import UserNotifications @objc(BackgroundRunnerPlugin) -public class BackgroundRunnerPlugin: CAPPlugin { +public class BackgroundRunnerPlugin: CAPPlugin, CAPBridgedPlugin { + public let identifier = "CapacitorBackgroundRunnerPlugin" + public let jsName = "CapacitorBackgroundRunner" + public let pluginMethods: [CAPPluginMethod] = [ + CAPPluginMethod(name: "checkPermissions", returnType: CAPPluginReturnPromise), + CAPPluginMethod(name: "requestPermissions", returnType: CAPPluginReturnPromise), + CAPPluginMethod(name: "dispatchEvent", returnType: CAPPluginReturnPromise), + CAPPluginMethod(name: "registerBackgroundTask", returnType: CAPPluginReturnPromise), + CAPPluginMethod(name: "removeNotificationListeners", returnType: CAPPluginReturnPromise) + ] private let impl = BackgroundRunner() - + override public func load() { NotificationCenter.default.addObserver( self, @@ -20,7 +29,7 @@ public class BackgroundRunnerPlugin: CAPPlugin { initWatchConnectivity() } - + @objc override public func checkPermissions(_ call: CAPPluginCall) { // check geolocation permissions let geolocationState = CapacitorGeolocation.checkPermission() @@ -56,7 +65,7 @@ public class BackgroundRunnerPlugin: CAPPlugin { } } } - + @objc func dispatchEvent(_ call: CAPPluginCall) { do { guard let runnerEvent = call.getString("event"), !runnerEvent.isEmpty else { diff --git a/packages/capacitor-plugin/ios/Sources/CapacitorBackgroundRunner/Context+CapacitorAPI.swift b/packages/capacitor-plugin/ios/Sources/CapacitorBackgroundRunner/Context+CapacitorAPI.swift new file mode 100644 index 00000000..0cb01864 --- /dev/null +++ b/packages/capacitor-plugin/ios/Sources/CapacitorBackgroundRunner/Context+CapacitorAPI.swift @@ -0,0 +1,18 @@ +import Foundation + +#if canImport(RunnerEngine) + import RunnerEngine +#endif + +extension Context { + public func setupCapacitorAPI() { + jsContext.setObject(CapacitorKVStore.self, forKeyedSubscript: "CapacitorKV" as NSString) + jsContext.setObject( + CapacitorGeolocation(context: self), forKeyedSubscript: "CapacitorGeolocation" as NSString) + jsContext.setObject(CapacitorWatch(), forKeyedSubscript: "CapacitorWatch" as NSString) + jsContext.setObject( + CapacitorNotifications.self, forKeyedSubscript: "CapacitorNotifications" as NSString) + jsContext.setObject(CapacitorDevice(), forKeyedSubscript: "CapacitorDevice" as NSString) + jsContext.setObject(CapacitorApp.self, forKeyedSubscript: "CapacitorApp" as NSString) + } +} diff --git a/packages/capacitor-plugin/ios/Plugin/RunnerConfig.swift b/packages/capacitor-plugin/ios/Sources/CapacitorBackgroundRunner/RunnerConfig.swift similarity index 100% rename from packages/capacitor-plugin/ios/Plugin/RunnerConfig.swift rename to packages/capacitor-plugin/ios/Sources/CapacitorBackgroundRunner/RunnerConfig.swift diff --git a/packages/capacitor-plugin/ios/Plugin/WatchConnectivtySessionDelegate.swift b/packages/capacitor-plugin/ios/Sources/CapacitorBackgroundRunner/WatchConnectivitySessionDelegate.swift similarity index 99% rename from packages/capacitor-plugin/ios/Plugin/WatchConnectivtySessionDelegate.swift rename to packages/capacitor-plugin/ios/Sources/CapacitorBackgroundRunner/WatchConnectivitySessionDelegate.swift index 405bdac0..931363e2 100644 --- a/packages/capacitor-plugin/ios/Plugin/WatchConnectivtySessionDelegate.swift +++ b/packages/capacitor-plugin/ios/Sources/CapacitorBackgroundRunner/WatchConnectivitySessionDelegate.swift @@ -41,3 +41,4 @@ extension BackgroundRunnerPlugin: WCSessionDelegate { try? BackgroundRunner.shared.dispatchEvent(event: "WatchConnectivity_didReceiveApplicationContext", inputArgs: args) } } + diff --git a/packages/ios-engine/Sources/RunnerEngine/Context.swift b/packages/capacitor-plugin/ios/Sources/RunnerEngine/Context.swift similarity index 99% rename from packages/ios-engine/Sources/RunnerEngine/Context.swift rename to packages/capacitor-plugin/ios/Sources/RunnerEngine/Context.swift index 857da31d..2afe49b7 100644 --- a/packages/ios-engine/Sources/RunnerEngine/Context.swift +++ b/packages/capacitor-plugin/ios/Sources/RunnerEngine/Context.swift @@ -3,7 +3,7 @@ import JavaScriptCore public class Context { let name: String - let jsContext: JSContext + public let jsContext: JSContext private var eventListeners = [String: JSValue]() private var timers = [Int: Timer]() diff --git a/packages/ios-engine/Sources/RunnerEngine/Errors.swift b/packages/capacitor-plugin/ios/Sources/RunnerEngine/Errors.swift similarity index 100% rename from packages/ios-engine/Sources/RunnerEngine/Errors.swift rename to packages/capacitor-plugin/ios/Sources/RunnerEngine/Errors.swift diff --git a/packages/ios-engine/Sources/RunnerEngine/JSConsole.swift b/packages/capacitor-plugin/ios/Sources/RunnerEngine/JSConsole.swift similarity index 100% rename from packages/ios-engine/Sources/RunnerEngine/JSConsole.swift rename to packages/capacitor-plugin/ios/Sources/RunnerEngine/JSConsole.swift diff --git a/packages/ios-engine/Sources/RunnerEngine/JSCrypto.swift b/packages/capacitor-plugin/ios/Sources/RunnerEngine/JSCrypto.swift similarity index 100% rename from packages/ios-engine/Sources/RunnerEngine/JSCrypto.swift rename to packages/capacitor-plugin/ios/Sources/RunnerEngine/JSCrypto.swift diff --git a/packages/ios-engine/Sources/RunnerEngine/JSError.swift b/packages/capacitor-plugin/ios/Sources/RunnerEngine/JSError.swift similarity index 94% rename from packages/ios-engine/Sources/RunnerEngine/JSError.swift rename to packages/capacitor-plugin/ios/Sources/RunnerEngine/JSError.swift index b6d15481..a2be222f 100644 --- a/packages/ios-engine/Sources/RunnerEngine/JSError.swift +++ b/packages/capacitor-plugin/ios/Sources/RunnerEngine/JSError.swift @@ -27,7 +27,7 @@ import JavaScriptCore self.cause = nil } - func toString() -> String { + public func toString() -> String { return message } } diff --git a/packages/ios-engine/Sources/RunnerEngine/JSFetch.swift b/packages/capacitor-plugin/ios/Sources/RunnerEngine/JSFetch.swift similarity index 100% rename from packages/ios-engine/Sources/RunnerEngine/JSFetch.swift rename to packages/capacitor-plugin/ios/Sources/RunnerEngine/JSFetch.swift diff --git a/packages/ios-engine/Sources/RunnerEngine/JSResponse.swift b/packages/capacitor-plugin/ios/Sources/RunnerEngine/JSResponse.swift similarity index 100% rename from packages/ios-engine/Sources/RunnerEngine/JSResponse.swift rename to packages/capacitor-plugin/ios/Sources/RunnerEngine/JSResponse.swift diff --git a/packages/ios-engine/Sources/RunnerEngine/JSTextDecoder.swift b/packages/capacitor-plugin/ios/Sources/RunnerEngine/JSTextDecoder.swift similarity index 100% rename from packages/ios-engine/Sources/RunnerEngine/JSTextDecoder.swift rename to packages/capacitor-plugin/ios/Sources/RunnerEngine/JSTextDecoder.swift diff --git a/packages/ios-engine/Sources/RunnerEngine/JSTextEncoder.swift b/packages/capacitor-plugin/ios/Sources/RunnerEngine/JSTextEncoder.swift similarity index 100% rename from packages/ios-engine/Sources/RunnerEngine/JSTextEncoder.swift rename to packages/capacitor-plugin/ios/Sources/RunnerEngine/JSTextEncoder.swift diff --git a/packages/ios-engine/Sources/RunnerEngine/Runner.swift b/packages/capacitor-plugin/ios/Sources/RunnerEngine/Runner.swift similarity index 84% rename from packages/ios-engine/Sources/RunnerEngine/Runner.swift rename to packages/capacitor-plugin/ios/Sources/RunnerEngine/Runner.swift index 11573ece..fa0c6628 100644 --- a/packages/ios-engine/Sources/RunnerEngine/Runner.swift +++ b/packages/capacitor-plugin/ios/Sources/RunnerEngine/Runner.swift @@ -12,7 +12,7 @@ public class Runner { runLoop = RunLoop.current } - func createContext(name: String) throws -> Context { + public func createContext(name: String) throws -> Context { return try Context(vm: machine, contextName: name, runLoop: runLoop) } } diff --git a/packages/capacitor-plugin/ios/Tests/CapacitorBackgroundRunnerTests/CapacitorBackgroundRunnerTests.swift b/packages/capacitor-plugin/ios/Tests/CapacitorBackgroundRunnerTests/CapacitorBackgroundRunnerTests.swift new file mode 100644 index 00000000..06ee0ede --- /dev/null +++ b/packages/capacitor-plugin/ios/Tests/CapacitorBackgroundRunnerTests/CapacitorBackgroundRunnerTests.swift @@ -0,0 +1,21 @@ +import Testing +@testable import CapacitorBackgroundRunner +@testable import RunnerEngine + +@Test func testKeyValueAPI() async throws { + let runner = Runner() + let context = try runner.createContext(name: "io.backgroundrunner.testkv") + context.setupCapacitorAPI() + + _ = try context.execute(code: "CapacitorKV.set('test', 'hello world');") + + let value = try context.execute(code: "CapacitorKV.get('test');") + + #expect(value?.toDictionary()?["value"] as? String == "hello world") + + _ = try context.execute(code: "CapacitorKV.remove('test');") + + let nullValue = try context.execute(code: "CapacitorKV.get('test');") + + #expect(nullValue?.isNull ?? false) +} diff --git a/packages/ios-engine/Tests/RunnerEngineTests/ContextTests.swift b/packages/capacitor-plugin/ios/Tests/RunnerEngineTests/ContextTests.swift similarity index 100% rename from packages/ios-engine/Tests/RunnerEngineTests/ContextTests.swift rename to packages/capacitor-plugin/ios/Tests/RunnerEngineTests/ContextTests.swift diff --git a/packages/ios-engine/Tests/RunnerEngineTests/RunnerTests.swift b/packages/capacitor-plugin/ios/Tests/RunnerEngineTests/RunnerTests.swift similarity index 100% rename from packages/ios-engine/Tests/RunnerEngineTests/RunnerTests.swift rename to packages/capacitor-plugin/ios/Tests/RunnerEngineTests/RunnerTests.swift diff --git a/packages/capacitor-plugin/package.json b/packages/capacitor-plugin/package.json index 2ae771d5..c80ecea9 100644 --- a/packages/capacitor-plugin/package.json +++ b/packages/capacitor-plugin/package.json @@ -11,7 +11,9 @@ "android/src/main/", "android/build.gradle", "dist/", - "ios/Plugin/", + "ios/Sources", + "ios/Tests", + "Package.swift", "scripts/install_libs.js", "CapacitorBackgroundRunner.podspec" ], @@ -30,7 +32,7 @@ ], "scripts": { "verify": "npm run verify:ios && npm run verify:android && npm run verify:web", - "verify:ios": "cd ios && pod install && xcodebuild -workspace Plugin.xcworkspace -scheme Plugin -destination generic/platform=iOS && cd ..", + "verify:ios": "xcodebuild -scheme CapacitorBackgroundRunner -destination generic/platform=iOS && xcodebuild test -scheme CapacitorBackgroundRunner -destination 'platform=iOS Simulator,OS=18.6,name=iPhone 16 Pro'", "verify:android": "cd android && ./gradlew clean build test && cd ..", "verify:web": "npm run build", "lint": "npm run eslint && npm run prettier -- --check && npm run swiftlint -- lint", @@ -81,4 +83,4 @@ "src": "android" } } -} \ No newline at end of file +} diff --git a/packages/capacitor-plugin/scripts/copy-native-sdks.sh b/packages/capacitor-plugin/scripts/copy-native-sdks.sh index ccba9c52..1e700d52 100755 --- a/packages/capacitor-plugin/scripts/copy-native-sdks.sh +++ b/packages/capacitor-plugin/scripts/copy-native-sdks.sh @@ -1,7 +1,4 @@ #!/bin/bash -rm -r ./ios/Plugin/RunnerEngine -cp -R ../ios-engine/Sources/RunnerEngine ./ios/Plugin/ - rm -f ./android/src/main/libs/android-js-engine-release.aar cp -R ../android-js-engine/AndroidJSEngine/build/outputs/aar/AndroidJSEngine-debug.aar ./android/src/main/libs/android-js-engine-release.aar diff --git a/packages/capacitor-plugin/src/index.ts b/packages/capacitor-plugin/src/index.ts index 68ca91d1..f619107e 100644 --- a/packages/capacitor-plugin/src/index.ts +++ b/packages/capacitor-plugin/src/index.ts @@ -3,7 +3,7 @@ import { registerPlugin } from '@capacitor/core'; import type { BackgroundRunnerPlugin } from './definitions'; const BackgroundRunner = registerPlugin( - 'BackgroundRunner', + 'CapacitorBackgroundRunner', { web: () => import('./web').then(m => new m.BackgroundRunnerWeb()), }, diff --git a/packages/ios-engine/.gitignore b/packages/ios-engine/.gitignore deleted file mode 100644 index ee74ae72..00000000 --- a/packages/ios-engine/.gitignore +++ /dev/null @@ -1,101 +0,0 @@ -# Created by https://www.toptal.com/developers/gitignore/api/swift,xcode -# Edit at https://www.toptal.com/developers/gitignore?templates=swift,xcode - -### Swift ### -# Xcode -# -# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore - -## User settings -xcuserdata/ - -## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) -*.xcscmblueprint -*.xccheckout - -## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) -build/ -DerivedData/ -*.moved-aside -*.pbxuser -!default.pbxuser -*.mode1v3 -!default.mode1v3 -*.mode2v3 -!default.mode2v3 -*.perspectivev3 -!default.perspectivev3 - -## Obj-C/Swift specific -*.hmap - -## App packaging -*.ipa -*.dSYM.zip -*.dSYM - -## Playgrounds -timeline.xctimeline -playground.xcworkspace - -# Swift Package Manager -# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. -# Packages/ -# Package.pins -# Package.resolved -# *.xcodeproj -# Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata -# hence it is not needed unless you have added a package configuration file to your project -# .swiftpm - -.build/ - -# CocoaPods -# We recommend against adding the Pods directory to your .gitignore. However -# you should judge for yourself, the pros and cons are mentioned at: -# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control -# Pods/ -# Add this line if you want to avoid checking in source code from the Xcode workspace -# *.xcworkspace - -# Carthage -# Add this line if you want to avoid checking in source code from Carthage dependencies. -# Carthage/Checkouts - -Carthage/Build/ - -# Accio dependency management -Dependencies/ -.accio/ - -# fastlane -# It is recommended to not store the screenshots in the git repo. -# Instead, use fastlane to re-generate the screenshots whenever they are needed. -# For more information about the recommended setup visit: -# https://docs.fastlane.tools/best-practices/source-control/#source-control - -fastlane/report.xml -fastlane/Preview.html -fastlane/screenshots/**/*.png -fastlane/test_output - -# Code Injection -# After new code Injection tools there's a generated folder /iOSInjectionProject -# https://github.com/johnno1962/injectionforxcode - -iOSInjectionProject/ - -### Xcode ### - -## Xcode 8 and earlier - -### Xcode Patch ### -*.xcodeproj/* -!*.xcodeproj/project.pbxproj -!*.xcodeproj/xcshareddata/ -!*.xcodeproj/project.xcworkspace/ -!*.xcworkspace/contents.xcworkspacedata -/*.gcno -**/xcshareddata/WorkspaceSettings.xcsettings - -# End of https://www.toptal.com/developers/gitignore/api/swift,xcode diff --git a/packages/ios-engine/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata b/packages/ios-engine/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 919434a6..00000000 --- a/packages/ios-engine/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/packages/ios-engine/CHANGELOG.md b/packages/ios-engine/CHANGELOG.md deleted file mode 100644 index 799dbc30..00000000 --- a/packages/ios-engine/CHANGELOG.md +++ /dev/null @@ -1,43 +0,0 @@ -# Change Log - -## 1.1.0 - -### Minor Changes - -- 142e96d: (iOS) KV: calling `get` on an non-existent key returns null instead of empty object - (iOS) Fixed an issue within Runner that could potentially cause EXC_BAD_ACCESS crashes - -### Patch Changes - -- 11124d2: (iOS): Removing unnecessary run loop thread causing spike in CPU while the app was in the foreground - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -## [1.0.5](https://github.com/ionic-team/capacitor-background-runner/compare/1.0.4...1.0.5) (2023-08-17) - -**Note:** Version bump only for package ios-engine - -## [1.0.4](https://github.com/ionic-team/capacitor-background-runner/compare/1.0.3...1.0.4) (2023-08-10) - -**Note:** Version bump only for package ios-engine - -## [1.0.3](https://github.com/ionic-team/capacitor-background-runner/compare/1.0.2...1.0.3) (2023-08-10) - -**Note:** Version bump only for package ios-engine - -## [1.0.2](https://github.com/ionic-team/capacitor-background-runner/compare/1.0.1...1.0.2) (2023-08-10) - -**Note:** Version bump only for package ios-engine - -## [1.0.1](https://github.com/ionic-team/capacitor-background-runner/compare/1.0.0...1.0.1) (2023-08-09) - -**Note:** Version bump only for package ios-engine - -# 1.0.0 (2023-07-18) - -### Features - -- Capacitor Plugin ([#3](https://github.com/ionic-team/enterprise-background-runner/issues/3)) ([ffac505](https://github.com/ionic-team/enterprise-background-runner/commit/ffac505560c144d2478ed6de49dc7d0c5130b15c)) -- iOS runtime for background runner ([221654a](https://github.com/ionic-team/enterprise-background-runner/commit/221654a4329be6507cc635b6d6b0a190511ea1d5)) -- **iOS:** Adding Capacitor Web APIs ([#4](https://github.com/ionic-team/enterprise-background-runner/issues/4)) ([7daa335](https://github.com/ionic-team/enterprise-background-runner/commit/7daa3350335989e8caf20c7258074a6dfa5d2cfe)) diff --git a/packages/ios-engine/Package.swift b/packages/ios-engine/Package.swift deleted file mode 100644 index 4ca19ca7..00000000 --- a/packages/ios-engine/Package.swift +++ /dev/null @@ -1,22 +0,0 @@ -// swift-tools-version: 5.7 - -import PackageDescription - -let package = Package( - name: "BackgroundRunnerEngine", - platforms: [.iOS(.v15), .macOS(.v13)], - products: [ - .library( - name: "BackgroundRunnerEngine", - targets: ["RunnerEngine"]) - ], - dependencies: [], - targets: [ - .target( - name: "RunnerEngine", - dependencies: []), - .testTarget( - name: "RunnerEngineTests", - dependencies: ["RunnerEngine"]) - ] -) diff --git a/packages/ios-engine/README.md b/packages/ios-engine/README.md deleted file mode 100644 index b224366a..00000000 --- a/packages/ios-engine/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# ios-engine - -A description of this package. diff --git a/packages/ios-engine/package.json b/packages/ios-engine/package.json deleted file mode 100644 index 1e698f55..00000000 --- a/packages/ios-engine/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "ios-engine", - "private": true, - "scripts": { - "lint": " pnpm swiftlint lint", - "fmt": " pnpm swiftlint lint --fix --format", - "swiftlint": "node-swiftlint" - }, - "dependencies": { - "@ionic/swiftlint-config": "^1.1.2", - "swiftlint": "^1.0.2" - }, - "version": "1.1.0" -} diff --git a/packages/ios-engine/swiftlint.config.js b/packages/ios-engine/swiftlint.config.js deleted file mode 100644 index d4e3c6ee..00000000 --- a/packages/ios-engine/swiftlint.config.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - ...require("@ionic/swiftlint-config"), - excluded: ["node_modules", "Tests/*", ".build", ".swiftpm"], - disabled_rules: [ - "identifier_name" - ] -}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 047ae338..44493197 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -28,29 +28,29 @@ importers: specifier: ^7.25.9 version: 7.25.9(@babel/core@7.26.0) '@capacitor/android': - specifier: ^7.0.0 - version: 7.0.1(@capacitor/core@7.0.1) + specifier: ^7.4.4 + version: 7.4.4(@capacitor/core@7.4.4) '@capacitor/app': - specifier: ^7.0.0 - version: 7.0.0(@capacitor/core@7.0.1) + specifier: ^7.1.0 + version: 7.1.0(@capacitor/core@7.4.4) '@capacitor/background-runner': specifier: workspace:^ version: link:../../packages/capacitor-plugin '@capacitor/core': - specifier: ^7.0.0 - version: 7.0.1 + specifier: ^7.4.4 + version: 7.4.4 '@capacitor/haptics': - specifier: ^7.0.0 - version: 7.0.0(@capacitor/core@7.0.1) + specifier: ^7.0.2 + version: 7.0.2(@capacitor/core@7.4.4) '@capacitor/ios': - specifier: ^7.0.0 - version: 7.0.1(@capacitor/core@7.0.1) + specifier: ^7.4.4 + version: 7.4.4(@capacitor/core@7.4.4) '@capacitor/keyboard': - specifier: ^7.0.0 - version: 7.0.0(@capacitor/core@7.0.1) + specifier: ^7.0.3 + version: 7.0.3(@capacitor/core@7.4.4) '@capacitor/status-bar': - specifier: ^7.0.0 - version: 7.0.0(@capacitor/core@7.0.1) + specifier: ^7.0.3 + version: 7.0.3(@capacitor/core@7.4.4) '@ionic/react': specifier: ^6.7.5 version: 6.7.5(react-dom@17.0.2(react@17.0.2))(react@17.0.2) @@ -149,8 +149,138 @@ importers: version: 5.1.4 devDependencies: '@capacitor/cli': - specifier: next - version: 7.0.0-rc.0 + specifier: ^7.4.4 + version: 7.4.4 + + apps/example-app-spm: + dependencies: + '@babel/plugin-syntax-flow': + specifier: ^7.26.0 + version: 7.26.0(@babel/core@7.26.0) + '@babel/plugin-transform-react-jsx': + specifier: ^7.25.9 + version: 7.25.9(@babel/core@7.26.0) + '@capacitor/app': + specifier: ^7.1.0 + version: 7.1.0(@capacitor/core@7.4.4) + '@capacitor/background-runner': + specifier: workspace:^ + version: link:../../packages/capacitor-plugin + '@capacitor/core': + specifier: ^7.4.4 + version: 7.4.4 + '@capacitor/haptics': + specifier: ^7.0.2 + version: 7.0.2(@capacitor/core@7.4.4) + '@capacitor/ios': + specifier: ^7.4.4 + version: 7.4.4(@capacitor/core@7.4.4) + '@capacitor/keyboard': + specifier: ^7.0.3 + version: 7.0.3(@capacitor/core@7.4.4) + '@capacitor/status-bar': + specifier: ^7.0.3 + version: 7.0.3(@capacitor/core@7.4.4) + '@ionic/react': + specifier: ^6.7.5 + version: 6.7.5(react-dom@17.0.2(react@17.0.2))(react@17.0.2) + '@ionic/react-router': + specifier: ^6.7.5 + version: 6.7.5(react-dom@17.0.2(react@17.0.2))(react-router-dom@5.3.4(react@17.0.2))(react-router@5.3.4(react@17.0.2))(react@17.0.2) + '@testing-library/dom': + specifier: ^9.3.4 + version: 9.3.4 + '@testing-library/jest-dom': + specifier: ^5.17.0 + version: 5.17.0 + '@testing-library/react': + specifier: ^11.2.7 + version: 11.2.7(react-dom@17.0.2(react@17.0.2))(react@17.0.2) + '@testing-library/user-event': + specifier: ^12.8.3 + version: 12.8.3(@testing-library/dom@9.3.4) + '@types/jest': + specifier: ^26.0.24 + version: 26.0.24 + '@types/node': + specifier: ^12.20.55 + version: 12.20.55 + '@types/react': + specifier: ^16.14.62 + version: 16.14.62 + '@types/react-dom': + specifier: ^16.9.25 + version: 16.9.25(@types/react@16.14.62) + '@types/react-router': + specifier: ^5.1.20 + version: 5.1.20 + '@types/react-router-dom': + specifier: ^5.3.3 + version: 5.3.3 + ionicons: + specifier: ^5.5.4 + version: 5.5.4 + react: + specifier: ^17.0.2 + version: 17.0.2 + react-dom: + specifier: ^17.0.2 + version: 17.0.2(react@17.0.2) + react-router: + specifier: ^5.3.4 + version: 5.3.4(react@17.0.2) + react-router-dom: + specifier: ^5.3.4 + version: 5.3.4(react@17.0.2) + react-scripts: + specifier: ^5.0.1 + version: 5.0.1(@babel/plugin-syntax-flow@7.26.0(@babel/core@7.26.0))(@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.0))(@types/babel__core@7.20.5)(eslint@7.32.0)(react@17.0.2)(type-fest@0.21.3)(typescript@4.9.5) + typescript: + specifier: ^4.9.5 + version: 4.9.5 + web-vitals: + specifier: ^0.2.4 + version: 0.2.4 + workbox-background-sync: + specifier: ^5.1.4 + version: 5.1.4 + workbox-broadcast-update: + specifier: ^5.1.4 + version: 5.1.4 + workbox-cacheable-response: + specifier: ^5.1.4 + version: 5.1.4 + workbox-core: + specifier: ^5.1.4 + version: 5.1.4 + workbox-expiration: + specifier: ^5.1.4 + version: 5.1.4 + workbox-google-analytics: + specifier: ^5.1.4 + version: 5.1.4 + workbox-navigation-preload: + specifier: ^5.1.4 + version: 5.1.4 + workbox-precaching: + specifier: ^5.1.4 + version: 5.1.4 + workbox-range-requests: + specifier: ^5.1.4 + version: 5.1.4 + workbox-routing: + specifier: ^5.1.4 + version: 5.1.4 + workbox-strategies: + specifier: ^5.1.4 + version: 5.1.4 + workbox-streams: + specifier: ^5.1.4 + version: 5.1.4 + devDependencies: + '@capacitor/cli': + specifier: ^7.4.4 + version: 7.4.4 packages/android-js-engine: dependencies: @@ -219,15 +349,6 @@ importers: specifier: ^5.1.6 version: 5.7.3 - packages/ios-engine: - dependencies: - '@ionic/swiftlint-config': - specifier: ^1.1.2 - version: 1.1.2 - swiftlint: - specifier: ^1.0.2 - version: 1.0.2 - packages: '@adobe/css-tools@4.4.1': @@ -963,13 +1084,13 @@ packages: peerDependencies: '@capacitor/core': ^6.2.0 - '@capacitor/android@7.0.1': - resolution: {integrity: sha512-jukJJHfkcyEBOkFBJRD3EwXMIIQo7lSv0ExPWgsIliPdGXLAj6ElvK2JaYEzec3vKyLc4RTNFVv0PMEU0vnImg==} + '@capacitor/android@7.4.4': + resolution: {integrity: sha512-y8knfV1JXNrd6XZZLZireGT+EBCN0lvOo+HZ/s7L8LkrPBu4nY5UZn0Wxz4yOezItEII9rqYJSHsS5fMJG9gdw==} peerDependencies: - '@capacitor/core': ^7.0.0 + '@capacitor/core': ^7.4.0 - '@capacitor/app@7.0.0': - resolution: {integrity: sha512-/UFwfPFsw/Jen6vjrV0lfTBOQWSaDDdmrYXKpYg4Xn8hwj0xrrRPXxC43j7VmPoj9AFMVPA+hx94ygqjChPASQ==} + '@capacitor/app@7.1.0': + resolution: {integrity: sha512-W7m09IWrUjZbo7AKeq+rc/KyucxrJekTBg0l4QCm/yDtCejE3hebxp/W2esU26KKCzMc7H3ClkUw32E9lZkwRA==} peerDependencies: '@capacitor/core': '>=7.0.0' @@ -978,24 +1099,24 @@ packages: engines: {node: '>=18.0.0'} hasBin: true - '@capacitor/cli@7.0.0-rc.0': - resolution: {integrity: sha512-gmcgxRle0lrPJuz9K2qPqx45vFP1Vr8pPvYG5nIn6KyUMFaO2ZMYgngUD1kffdsRIDp25P0/oPY6iYzYPNcYFw==} + '@capacitor/cli@7.4.4': + resolution: {integrity: sha512-J7ciBE7GlJ70sr2s8oz1+H4ZdNk4MGG41fsakUlDHWva5UWgFIZYMiEdDvGbYazAYTaxN3lVZpH9zil9FfZj+Q==} engines: {node: '>=20.0.0'} hasBin: true '@capacitor/core@6.2.0': resolution: {integrity: sha512-B9IlJtDpUqhhYb+T8+cp2Db/3RETX36STgjeU2kQZBs/SLAcFiMama227o+msRjLeo3DO+7HJjWVA1+XlyyPEg==} - '@capacitor/core@7.0.1': - resolution: {integrity: sha512-1Ob9bvA/p8g8aNwK6VesxEekGXowLVf6APjkW4LRnr05H+7z/bke+Q5pn9zqh/GgTbIxAQ/rwZrAZvvxkdm1UA==} + '@capacitor/core@7.4.4': + resolution: {integrity: sha512-xzjxpr+d2zwTpCaN0k+C6wKSZzWFAb9OVEUtmO72ihjr/NEDoLvsGl4WLfjWPcCO2zOy0b2X52tfRWjECFUjtw==} '@capacitor/docgen@0.2.2': resolution: {integrity: sha512-617jB5DlKjUljxfoANORWeqffsHqHekckH48oslKWFGzfCHYIAEPfJfMa5M4mVSzn2ifSvWB5C3st4augwhl5w==} engines: {node: '>=14.5.0'} hasBin: true - '@capacitor/haptics@7.0.0': - resolution: {integrity: sha512-8uI8rWyAbq8EzkjS+sHZSncyzujHzVbuLKgj8J5H0yUL6+r26F16gVA2iuQuIBvzbSMy7Y0/pUuWlwZr/H8AKg==} + '@capacitor/haptics@7.0.2': + resolution: {integrity: sha512-vqfeEM6s2zMgLjpITCTUIy7P/hadq/Gr5E/RClFgMJPB41Y5FsqOKD+j85/uwh8N2cf/aWaPeXUmjnTzJbEB2g==} peerDependencies: '@capacitor/core': '>=7.0.0' @@ -1004,18 +1125,18 @@ packages: peerDependencies: '@capacitor/core': ^6.2.0 - '@capacitor/ios@7.0.1': - resolution: {integrity: sha512-RN6S1C1k7ue57DFmJM4EizzsYBrahTTiMhcnlHspFLaojgHbFWZbYq1VriuRKysPU1ka/P+klsdtRFsB5K9jyw==} + '@capacitor/ios@7.4.4': + resolution: {integrity: sha512-Xp3bGWlSQAwsZGngRMWTdoD2agdMV12Whnm+/xsYPxfQSj+Tksbr7r/8Mso7VWkpnTKO4iMlx762g3PjW+wi4w==} peerDependencies: - '@capacitor/core': ^7.0.0 + '@capacitor/core': ^7.4.0 - '@capacitor/keyboard@7.0.0': - resolution: {integrity: sha512-Tqwy8wG+sx4UqiFCX4Q+bFw6uKgG7BiHKAPpeefoIgoEB8H8Jf3xZNZoVPnJIMuPsCdSvuyHXZbJXH9IEEirGA==} + '@capacitor/keyboard@7.0.3': + resolution: {integrity: sha512-BIBKjmky5rOYNhvYhNeDi0MMvjwYZ6YF9JoCYcGKvKY+XLJKtezsEL78XfOlgWZBkbfR8uq3tzktY6PqgoYLKA==} peerDependencies: '@capacitor/core': '>=7.0.0' - '@capacitor/status-bar@7.0.0': - resolution: {integrity: sha512-wsvPkWkoSOXMIgVHu4c6P1sOuDSZ1ClUo5OpLRwj7u8DYzlV4jlmNzztQn2Lvsiqx1z4kfukSaqe40k1Lo4c9g==} + '@capacitor/status-bar@7.0.3': + resolution: {integrity: sha512-JyRpVnKwHij9hgPWolF6PK+HT3e2HSPjN11/h2OmKxq8GAdPGARFLv+97eZl0pvuvm0Kka/LpiLb5whXISBg7Q==} peerDependencies: '@capacitor/core': '>=7.0.0' @@ -8714,13 +8835,13 @@ snapshots: dependencies: '@capacitor/core': 6.2.0 - '@capacitor/android@7.0.1(@capacitor/core@7.0.1)': + '@capacitor/android@7.4.4(@capacitor/core@7.4.4)': dependencies: - '@capacitor/core': 7.0.1 + '@capacitor/core': 7.4.4 - '@capacitor/app@7.0.0(@capacitor/core@7.0.1)': + '@capacitor/app@7.1.0(@capacitor/core@7.4.4)': dependencies: - '@capacitor/core': 7.0.1 + '@capacitor/core': 7.4.4 '@capacitor/cli@6.2.0': dependencies: @@ -8744,7 +8865,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@capacitor/cli@7.0.0-rc.0': + '@capacitor/cli@7.4.4': dependencies: '@ionic/cli-framework-output': 2.2.8 '@ionic/utils-subprocess': 3.0.1 @@ -8770,7 +8891,7 @@ snapshots: dependencies: tslib: 2.8.1 - '@capacitor/core@7.0.1': + '@capacitor/core@7.4.4': dependencies: tslib: 2.8.1 @@ -8782,25 +8903,25 @@ snapshots: minimist: 1.2.8 typescript: 4.2.4 - '@capacitor/haptics@7.0.0(@capacitor/core@7.0.1)': + '@capacitor/haptics@7.0.2(@capacitor/core@7.4.4)': dependencies: - '@capacitor/core': 7.0.1 + '@capacitor/core': 7.4.4 '@capacitor/ios@6.2.0(@capacitor/core@6.2.0)': dependencies: '@capacitor/core': 6.2.0 - '@capacitor/ios@7.0.1(@capacitor/core@7.0.1)': + '@capacitor/ios@7.4.4(@capacitor/core@7.4.4)': dependencies: - '@capacitor/core': 7.0.1 + '@capacitor/core': 7.4.4 - '@capacitor/keyboard@7.0.0(@capacitor/core@7.0.1)': + '@capacitor/keyboard@7.0.3(@capacitor/core@7.4.4)': dependencies: - '@capacitor/core': 7.0.1 + '@capacitor/core': 7.4.4 - '@capacitor/status-bar@7.0.0(@capacitor/core@7.0.1)': + '@capacitor/status-bar@7.0.3(@capacitor/core@7.4.4)': dependencies: - '@capacitor/core': 7.0.1 + '@capacitor/core': 7.4.4 '@changesets/apply-release-plan@7.0.7': dependencies: @@ -11004,7 +11125,7 @@ snapshots: promise-inflight: 1.0.1 rimraf: 3.0.2 ssri: 9.0.1 - tar: 6.1.11 + tar: 6.2.1 unique-filename: 2.0.1 transitivePeerDependencies: - bluebird @@ -11021,7 +11142,7 @@ snapshots: minipass-pipeline: 1.2.4 p-map: 4.0.0 ssri: 10.0.6 - tar: 6.1.11 + tar: 6.2.1 unique-filename: 3.0.0 call-bind-apply-helpers@1.0.1: @@ -14347,7 +14468,7 @@ snapshots: npmlog: 6.0.2 rimraf: 3.0.2 semver: 7.6.3 - tar: 6.1.11 + tar: 6.2.1 which: 2.0.2 transitivePeerDependencies: - bluebird