@capacitor/background-runner 2.3.1 → 3.1.0-dev.20260827T162451

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -11,7 +11,7 @@ Pod::Spec.new do |s|
11
11
  s.author = package['author']
12
12
  s.source = { :git => package['repository']['url'], :tag => s.version.to_s }
13
13
  s.source_files = 'ios/Sources/**/*.{swift,h,m,c,cc,mm,cpp}'
14
- s.ios.deployment_target = '14.0'
14
+ s.ios.deployment_target = '15.0'
15
15
  s.dependency 'Capacitor'
16
16
  s.swift_version = '5.1'
17
17
  end
package/Package.swift CHANGED
@@ -5,7 +5,7 @@ import PackageDescription
5
5
 
6
6
  let package = Package(
7
7
  name: "CapacitorBackgroundRunner",
8
- platforms: [.iOS(.v14), .macOS(.v13)],
8
+ platforms: [.iOS(.v15), .macOS(.v13)],
9
9
  products: [
10
10
  // Products define the executables and libraries a package produces, making them visible to other packages.
11
11
  .library(
@@ -14,7 +14,7 @@ let package = Package(
14
14
  )
15
15
  ],
16
16
  dependencies: [
17
- .package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", from: "7.0.0")
17
+ .package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", from: "8.0.0")
18
18
  ],
19
19
  targets: [
20
20
  // Targets are the basic building blocks of a package, defining a module or a test suite.
package/README.md CHANGED
@@ -5,7 +5,7 @@ Background Runner provides an event-based standalone JavaScript environment for
5
5
  ## Install
6
6
 
7
7
  ```bash
8
- npm install @capacitor/background-runner@latest-7
8
+ npm install @capacitor/background-runner
9
9
  npx cap sync
10
10
  ```
11
11
 
@@ -189,14 +189,14 @@ On load, Background Runner will automatically register a
189
189
  background task that will be scheduled and run once your app is
190
190
  backgrounded.
191
191
 
192
- | Prop | Type | Description | Since |
193
- | --------------- | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----- |
194
- | **`label`** | <code>string</code> | The name of the runner, used in logs. | 1.0.0 |
195
- | **`src`** | <code>string</code> | The path to the runner JavaScript file, relative to the app bundle. | 1.0.0 |
196
- | **`event`** | <code>string</code> | The name of the event that will be called when the OS executes the background task. | 1.0.0 |
197
- | **`repeat`** | <code>boolean</code> | If background task should repeat based on the interval set in `interval`. | 1.0.0 |
198
- | **`interval`** | <code>number</code> | The number of minutes after the the app is put into the background in which the background task should begin. If `repeat` is true, this also specifies the number of minutes between each execution. | 1.0.0 |
199
- | **`autoStart`** | <code>boolean</code> | Automatically register and schedule background task on app load. | 1.0.0 |
192
+ | Prop | Type | Description | Since |
193
+ | --------------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----- |
194
+ | **`label`** | <code>string</code> | The name of the runner, used in logs. | 1.0.0 |
195
+ | **`src`** | <code>string</code> | The path to the runner JavaScript file, relative to the app bundle. | 1.0.0 |
196
+ | **`event`** | <code>string</code> | The name of the event that will be called when the OS executes the background task. | 1.0.0 |
197
+ | **`repeat`** | <code>boolean</code> | If background task should repeat based on the interval set in `interval`. | 1.0.0 |
198
+ | **`interval`** | <code>number</code> | The number of minutes after the app is put into the background in which the background task should begin. If `repeat` is true, this also specifies the number of minutes between each execution. | 1.0.0 |
199
+ | **`autoStart`** | <code>boolean</code> | Automatically register and schedule background task on app load. | 1.0.0 |
200
200
 
201
201
  ### Examples
202
202
 
@@ -521,7 +521,7 @@ Send basic local notifications.
521
521
  | **`sound`** | <code>string</code> | Name of the audio file to play when this notification is displayed. Include the file extension with the filename. On iOS, the file should be in the app bundle. On Android, the file should be in res/raw folder. Recommended format is `.wav` because is supported by both iOS and Android. Only available for iOS and Android &lt; 26. For Android 26+ use channelId of a channel configured with the desired sound. If the sound file is not found, (i.e. empty string or wrong name) the default system notification sound will be used. If not provided, it will produce the default sound on Android and no sound on iOS. | 1.0.0 |
522
522
  | **`actionTypeId`** | <code>string</code> | Associate an action type with this notification. | 1.0.0 |
523
523
  | **`threadIdentifier`** | <code>string</code> | Used to group multiple notifications. Sets `threadIdentifier` on the [`UNMutableNotificationContent`](https://developer.apple.com/documentation/usernotifications/unmutablenotificationcontent). Only available for iOS. | 1.0.0 |
524
- | **`summaryArgument`** | <code>string</code> | The string this notification adds to the category's summary format string. Sets `summaryArgument` on the [`UNMutableNotificationContent`](https://developer.apple.com/documentation/usernotifications/unmutablenotificationcontent). Only available for iOS. | 1.0.0 |
524
+ | **`summaryArgument`** | <code>string</code> | The string this notification adds to the category's summary format string. Only available for iOS. **This option has no effect.** `summaryArgument` on [`UNMutableNotificationContent`](https://developer.apple.com/documentation/usernotifications/unmutablenotificationcontent) is deprecated since iOS 15 and the value is ignored by the system, so it is no longer set on the notification content. | 1.0.0 |
525
525
  | **`group`** | <code>string</code> | Used to group multiple notifications. Calls `setGroup()` on [`NotificationCompat.Builder`](https://developer.android.com/reference/androidx/core/app/NotificationCompat.Builder) with the provided value. Only available for Android. | 1.0.0 |
526
526
  | **`groupSummary`** | <code>string</code> | If true, this notification becomes the summary for a group of notifications. Calls `setGroupSummary()` on [`NotificationCompat.Builder`](https://developer.android.com/reference/androidx/core/app/NotificationCompat.Builder) with the provided value. Only available for Android when using `group`. | 1.0.0 |
527
527
  | **`extra`** | <code>any</code> | Set extra data to store within this notification. | 1.0.0 |
@@ -1,21 +1,21 @@
1
1
  ext {
2
2
  junitVersion = project.hasProperty('junitVersion') ? rootProject.ext.junitVersion : '4.13.2'
3
- androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.7.0'
4
- androidxCoreKTXVersion = project.hasProperty('androidxCoreKTXVersion') ? rootProject.ext.androidxCoreKTXVersion : '1.12.0'
5
- androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.2.1'
6
- androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.6.1'
7
- workManagerVersion = project.hasProperty('workManagerVersion') ? rootProject.ext.workManagerVersion : '2.8.1'
3
+ androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.7.1'
4
+ androidxCoreKTXVersion = project.hasProperty('androidxCoreKTXVersion') ? rootProject.ext.androidxCoreKTXVersion : '1.17.0'
5
+ androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.3.0'
6
+ androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.7.0'
7
+ workManagerVersion = project.hasProperty('workManagerVersion') ? rootProject.ext.workManagerVersion : '2.11.0'
8
8
 
9
9
  }
10
10
 
11
11
  buildscript {
12
- ext.kotlin_version = project.hasProperty("kotlin_version") ? rootProject.ext.kotlin_version : '1.9.25'
12
+ ext.kotlin_version = project.hasProperty("kotlin_version") ? rootProject.ext.kotlin_version : '2.2.20'
13
13
  repositories {
14
14
  google()
15
15
  mavenCentral()
16
16
  }
17
17
  dependencies {
18
- classpath 'com.android.tools.build:gradle:8.7.2'
18
+ classpath 'com.android.tools.build:gradle:8.13.0'
19
19
  classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
20
20
 
21
21
  }
@@ -25,11 +25,11 @@ apply plugin: 'com.android.library'
25
25
  apply plugin: 'org.jetbrains.kotlin.android'
26
26
 
27
27
  android {
28
- namespace "com.capacitorjs.plugins.backgroundrunner"
29
- compileSdk project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 35
28
+ namespace = "com.capacitorjs.plugins.backgroundrunner"
29
+ compileSdk = project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 36
30
30
  defaultConfig {
31
- minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 23
32
- targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 35
31
+ minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 24
32
+ targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 36
33
33
  versionCode 1
34
34
  versionName "1.0"
35
35
  testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -37,11 +37,11 @@ android {
37
37
  buildTypes {
38
38
  release {
39
39
  minifyEnabled false
40
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
40
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
41
41
  }
42
42
  }
43
43
  lintOptions {
44
- abortOnError false
44
+ abortOnError = false
45
45
  }
46
46
  compileOptions {
47
47
  sourceCompatibility JavaVersion.VERSION_21
@@ -80,7 +80,7 @@ class Device (context: android.content.Context) : DeviceAPI {
80
80
  return false
81
81
  }
82
82
 
83
- @SuppressWarnings("deprecation")
83
+ @Suppress("DEPRECATION")
84
84
  private fun getAndParseNetworkInfo(): NetworkStatus {
85
85
  val networkStatus = NetworkStatus()
86
86
  val networkInfo = connectivityManager.activeNetworkInfo
@@ -211,17 +211,9 @@ class Notifications(context: Context) : NotificationsAPI {
211
211
  PendingIntent.getBroadcast(context, request.id, intent, flags)
212
212
 
213
213
  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && !alarmManager.canScheduleExactAlarms()) {
214
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
215
- alarmManager.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, request.scheduleAt.time, pendingIntent);
216
- } else {
217
- alarmManager.set(AlarmManager.RTC, request.scheduleAt.time, pendingIntent);
218
- }
214
+ alarmManager.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, request.scheduleAt.time, pendingIntent)
219
215
  } else {
220
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
221
- alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, request.scheduleAt.time, pendingIntent);
222
- } else {
223
- alarmManager.setExact(AlarmManager.RTC, request.scheduleAt.time, pendingIntent);
224
- }
216
+ alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, request.scheduleAt.time, pendingIntent)
225
217
  }
226
218
  }
227
219
  }
@@ -34,6 +34,7 @@ class TimedNotificationPublisher : BroadcastReceiver() {
34
34
  notificationManager.notify(id, notification)
35
35
  }
36
36
 
37
+ @Suppress("DEPRECATION")
37
38
  private fun getParcelableExtraLegacy(intent: Intent): android.app.Notification? {
38
39
  return intent.getParcelableExtra(NOTIFICATION_KEY)
39
40
  }
@@ -396,9 +396,13 @@
396
396
  {
397
397
  "text": "1.0.0",
398
398
  "name": "since"
399
+ },
400
+ {
401
+ "text": "This option has no effect, iOS ignores it since iOS 15.",
402
+ "name": "deprecated"
399
403
  }
400
404
  ],
401
- "docs": "The string this notification adds to the category's summary format string.\n\nSets `summaryArgument` on the\n[`UNMutableNotificationContent`](https://developer.apple.com/documentation/usernotifications/unmutablenotificationcontent).\n\nOnly available for iOS.",
405
+ "docs": "The string this notification adds to the category's summary format string.\n\nOnly available for iOS.\n\n**This option has no effect.** `summaryArgument` on\n[`UNMutableNotificationContent`](https://developer.apple.com/documentation/usernotifications/unmutablenotificationcontent)\nis deprecated since iOS 15 and the value is ignored by the system, so it is\nno longer set on the notification content.",
402
406
  "complexTypes": [],
403
407
  "type": "string | undefined"
404
408
  },
@@ -948,7 +952,7 @@
948
952
  "name": "example"
949
953
  }
950
954
  ],
951
- "docs": "The number of minutes after the the app is put into the background in which the background task should begin.\n\nIf `repeat` is true, this also specifies the number of minutes between each execution.",
955
+ "docs": "The number of minutes after the app is put into the background in which the background task should begin.\n\nIf `repeat` is true, this also specifies the number of minutes between each execution.",
952
956
  "complexTypes": [],
953
957
  "type": "number"
954
958
  },
package/dist/docs.json CHANGED
@@ -369,7 +369,7 @@
369
369
  "name": "example"
370
370
  }
371
371
  ],
372
- "docs": "The number of minutes after the the app is put into the background in which the background task should begin.\n\nIf `repeat` is true, this also specifies the number of minutes between each execution.",
372
+ "docs": "The number of minutes after the app is put into the background in which the background task should begin.\n\nIf `repeat` is true, this also specifies the number of minutes between each execution.",
373
373
  "complexTypes": [],
374
374
  "type": "number"
375
375
  },
@@ -143,12 +143,15 @@ export interface NotificationScheduleOptions {
143
143
  /**
144
144
  * The string this notification adds to the category's summary format string.
145
145
  *
146
- * Sets `summaryArgument` on the
147
- * [`UNMutableNotificationContent`](https://developer.apple.com/documentation/usernotifications/unmutablenotificationcontent).
148
- *
149
146
  * Only available for iOS.
150
147
  *
148
+ * **This option has no effect.** `summaryArgument` on
149
+ * [`UNMutableNotificationContent`](https://developer.apple.com/documentation/usernotifications/unmutablenotificationcontent)
150
+ * is deprecated since iOS 15 and the value is ignored by the system, so it is
151
+ * no longer set on the notification content.
152
+ *
151
153
  * @since 1.0.0
154
+ * @deprecated This option has no effect, iOS ignores it since iOS 15.
152
155
  */
153
156
  summaryArgument?: string;
154
157
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"apis.js","sourceRoot":"","sources":["../../src/apis.ts"],"names":[],"mappings":"","sourcesContent":["export interface GetCurrentPositionResult {\n /**\n * Latitude in decimal degrees\n *\n * @since 1.0.0\n */\n latitude: number;\n /**\n * longitude in decimal degrees\n *\n * @since 1.0.0\n */\n longitude: number;\n /**\n * Accuracy level of the latitude and longitude coordinates in meters\n *\n * @since 1.0.0\n */\n accuracy: number;\n /**\n * The altitude the user is at (if available)\n *\n * @since 1.0.0\n */\n altitude: number | null;\n /**\n * Accuracy level of the altitude coordinate in meters, if available.\n *\n * Available on all iOS versions and on Android 8.0+.\n *\n * @since 1.0.0\n */\n altitudeAccuracy?: number | null | undefined;\n /**\n * The speed the user is traveling (if available)\n *\n * @since 1.0.0\n */\n speed: number | null;\n /**\n * The heading the user is facing (if available)\n *\n * @since 1.0.0\n */\n heading: number | null;\n}\n\nexport interface BatteryStatus {\n batteryLevel: number;\n isCharging: boolean;\n}\n\nexport interface NetworkStatus {\n connected: boolean;\n connectionType: string;\n}\n\nexport interface NotificationBadgeOptions {\n /**\n * The number to set on the application badge count.\n *\n * @since 2.0.0\n */\n count: number;\n /**\n * The **required** title for the associated badge count notification.\n *\n * Only for Android.\n *\n * @since 2.0.0\n */\n notificationTitle: string;\n /**\n * The subtitle for the associated badge count notification.\n *\n * Only for Android.\n *\n * @since 2.0.0\n */\n notificationSubtitle: string;\n}\n\nexport interface NotificationScheduleOptions {\n /**\n * The notification identifier.\n * On Android it's a 32-bit int.\n * So the value should be between -2147483648 and 2147483647 inclusive.\n *\n * @since 1.0.0\n */\n id: number;\n /**\n * The title of the notification.\n *\n * @since 1.0.0\n */\n title: string;\n /**\n * The body of the notification, shown below the title.\n *\n * @since 1.0.0\n */\n body: string;\n /**\n * Date to send this notification.\n *\n * @since 1.0.0\n */\n scheduleAt: Date;\n /**\n * Name of the audio file to play when this notification is displayed.\n *\n * Include the file extension with the filename.\n *\n * On iOS, the file should be in the app bundle.\n * On Android, the file should be in res/raw folder.\n *\n * Recommended format is `.wav` because is supported by both iOS and Android.\n *\n * Only available for iOS and Android < 26.\n * For Android 26+ use channelId of a channel configured with the desired sound.\n *\n * If the sound file is not found, (i.e. empty string or wrong name)\n * the default system notification sound will be used.\n * If not provided, it will produce the default sound on Android and no sound on iOS.\n *\n * @since 1.0.0\n */\n sound?: string;\n /**\n * Associate an action type with this notification.\n *\n * @since 1.0.0\n */\n actionTypeId?: string;\n /**\n * Used to group multiple notifications.\n *\n * Sets `threadIdentifier` on the\n * [`UNMutableNotificationContent`](https://developer.apple.com/documentation/usernotifications/unmutablenotificationcontent).\n *\n * Only available for iOS.\n *\n * @since 1.0.0\n */\n threadIdentifier?: string;\n /**\n * The string this notification adds to the category's summary format string.\n *\n * Sets `summaryArgument` on the\n * [`UNMutableNotificationContent`](https://developer.apple.com/documentation/usernotifications/unmutablenotificationcontent).\n *\n * Only available for iOS.\n *\n * @since 1.0.0\n */\n summaryArgument?: string;\n /**\n * Used to group multiple notifications.\n *\n * Calls `setGroup()` on\n * [`NotificationCompat.Builder`](https://developer.android.com/reference/androidx/core/app/NotificationCompat.Builder)\n * with the provided value.\n *\n * Only available for Android.\n *\n * @since 1.0.0\n */\n group?: string;\n /**\n * If true, this notification becomes the summary for a group of\n * notifications.\n *\n * Calls `setGroupSummary()` on\n * [`NotificationCompat.Builder`](https://developer.android.com/reference/androidx/core/app/NotificationCompat.Builder)\n * with the provided value.\n *\n * Only available for Android when using `group`.\n *\n * @since 1.0.0\n */\n groupSummary?: string;\n /**\n * Set extra data to store within this notification.\n *\n * @since 1.0.0\n */\n extra?: any;\n /**\n * If true, the notification can't be swiped away.\n *\n * Calls `setOngoing()` on\n * [`NotificationCompat.Builder`](https://developer.android.com/reference/androidx/core/app/NotificationCompat.Builder)\n * with the provided value.\n *\n * Only available for Android.\n *\n * @since 1.0.0\n */\n ongoing?: boolean;\n /**\n * If true, the notification is canceled when the user clicks on it.\n *\n * Calls `setAutoCancel()` on\n * [`NotificationCompat.Builder`](https://developer.android.com/reference/androidx/core/app/NotificationCompat.Builder)\n * with the provided value.\n *\n * Only available for Android.\n *\n * @since 1.0.0\n */\n autoCancel?: boolean;\n /**\n * Sets a multiline text block for display in a big text notification style.\n *\n * @since 1.0.0\n */\n largeBody?: string;\n /**\n * Used to set the summary text detail in inbox and big text notification styles.\n *\n * Only available for Android.\n *\n * @since 1.0.0\n */\n summaryText?: string;\n /**\n * Set a custom status bar icon.\n *\n * If set, this overrides the `smallIcon` option from Capacitor\n * configuration.\n *\n * Icons should be placed in your app's `res/drawable` folder. The value for\n * this option should be the drawable resource ID, which is the filename\n * without an extension.\n *\n * Only available for Android.\n *\n * @since 1.0.0\n */\n smallIcon?: string;\n /**\n * Set a large icon for notifications.\n *\n * Icons should be placed in your app's `res/drawable` folder. The value for\n * this option should be the drawable resource ID, which is the filename\n * without an extension.\n *\n * Only available for Android.\n *\n * @since 1.0.0\n */\n largeIcon?: string;\n /**\n * Specifies the channel the notification should be delivered on.\n *\n * If channel with the given name does not exist then the notification will\n * not fire. If not provided, it will use the default channel.\n *\n * Calls `setChannelId()` on\n * [`NotificationCompat.Builder`](https://developer.android.com/reference/androidx/core/app/NotificationCompat.Builder)\n * with the provided value.\n *\n * Only available for Android 26+.\n *\n * @since 1.0.0\n */\n channelId?: string;\n}\n\nexport interface AppInfo {\n /**\n * The name of the app.\n *\n * @since 1.0.0\n */\n name: string;\n\n /**\n * The identifier of the app.\n * On iOS it's the Bundle Identifier.\n * On Android it's the Application ID\n *\n * @since 1.0.0\n */\n id: string;\n\n /**\n * The build version.\n * On iOS it's the CFBundleVersion.\n * On Android it's the versionCode.\n *\n * @since 1.0.0\n */\n build: string;\n\n /**\n * The app version.\n * On iOS it's the CFBundleShortVersionString.\n * On Android it's package's versionName.\n *\n * @since 1.0.0\n */\n version: string;\n}\n\nexport interface AppState {\n /**\n * Whether the app is active or not.\n *\n * @since 1.0.0\n */\n isActive: boolean;\n}\n\n/**\n * Get access to device location information.\n *\n * @since 1.0.0\n */\nexport interface CapacitorGeolocation {\n /**\n * Get the device's last known location\n * @since 1.0.0\n */\n getCurrentPosition: () => GetCurrentPositionResult;\n}\n\n/**\n * A simple string key / value store backed by UserDefaults on iOS and Shared Preferences on Android.\n */\nexport interface CapacitorKV {\n /**\n * Set a string value with the given key.\n *\n * @param key\n * @param value\n * @returns\n * @since 1.0.0\n */\n set: (key: string, value: string) => void;\n /**\n * Get a string value for the given key.\n * @param key\n * @returns\n * @since 1.0.0\n */\n get: (key: string) => { value: string };\n /**\n * Remove a value with the given key.\n * @param key\n * @returns\n * @since 1.0.0\n */\n remove: (key: string) => void;\n}\n\n/**\n * Get information on the device, such as network connectivity and battery status.\n */\nexport interface CapacitorDevice {\n /**\n * Get the current battery status for the device.\n *\n * @since 1.0.0\n */\n getBatteryStatus: () => BatteryStatus;\n /**\n * Get the current network status for the device.\n *\n * @since 1.0.0\n */\n getNetworkStatus: () => NetworkStatus;\n}\n\n/**\n * Send basic local notifications.\n */\nexport interface CapacitorNotifications {\n /**\n * Schedule a local notification\n * @example `CapacitorNotifications.schedule()`\n * @param options\n * @returns void\n * @since 1.0.0\n */\n schedule: (options: NotificationScheduleOptions[]) => void;\n /**\n * Set the application badge count\n * @example `CapacitorNotifications.setBadge({...})`\n * @param options\n * @returns void\n * @since 2.0.0\n */\n setBadge: (options: NotificationBadgeOptions) => void;\n /**\n * Clears the application badge count\n * @example `CapacitorNotifications.clearBadge()`\n * @returns void\n * @since 2.0.0\n */\n clearBadge: () => void;\n}\n\n/**\n * Interact with a watch paired with this app\n *\n * sendMessage, transferUserInfo and updateApplicationContext are raw routes to the WCSession delegate methods, but have no effects currently in a CapacitorWatch Watch application.\n * They could be used if a native watch app is developed as a companion app to a Capacitor app\n */\nexport interface CapacitorWatch {\n /**\n * Sends a message to the watch with the sendMessage() WCSession delegate method\n *\n * This has no effect on a CapacitorWatch watch app\n */\n sendMessage: (options: []) => void;\n /**\n * Sends information to the watch with the transferUserInfo() WCSession delegate method\n *\n * This has no effect on a CapacitorWatch watch app\n */\n transferUserInfo: (options: []) => void;\n /**\n * Updates the application context on the watch with the updateApplicationContext() WCSession delegate method\n *\n * This has no effect on a CapacitorWatch watch app\n */\n updateApplicationContext: (options: []) => void;\n /**\n * Checks to see if the compaion watch is reachable\n */\n isReachable: boolean;\n /**\n * Replaces the current UI on the watch with what is specified here.\n * @param options the new WatchUI you want to show on the watch\n * @returns void\n */\n updateWatchUI: (options: { watchUI: string }) => void;\n /**\n * Updates the data the watch is using to display variables in text and button fields\n * @param options the new data to send to the watch\n * @returns void\n */\n updateWatchData: (options: { data: { [key: string]: string } }) => void;\n}\n\nexport interface CapacitorApp {\n getState: () => AppState;\n getInfo: () => AppInfo;\n}\n\nexport interface CapacitorAPI {\n CapacitorDevice: CapacitorDevice;\n CapacitorKV: CapacitorKV;\n CapacitorNotifications: CapacitorNotifications;\n CapacitorGeolocation: CapacitorGeolocation;\n CapacitorWatch: CapacitorWatch;\n CapacitorApp: CapacitorApp;\n}\n"]}
1
+ {"version":3,"file":"apis.js","sourceRoot":"","sources":["../../src/apis.ts"],"names":[],"mappings":"","sourcesContent":["export interface GetCurrentPositionResult {\n /**\n * Latitude in decimal degrees\n *\n * @since 1.0.0\n */\n latitude: number;\n /**\n * longitude in decimal degrees\n *\n * @since 1.0.0\n */\n longitude: number;\n /**\n * Accuracy level of the latitude and longitude coordinates in meters\n *\n * @since 1.0.0\n */\n accuracy: number;\n /**\n * The altitude the user is at (if available)\n *\n * @since 1.0.0\n */\n altitude: number | null;\n /**\n * Accuracy level of the altitude coordinate in meters, if available.\n *\n * Available on all iOS versions and on Android 8.0+.\n *\n * @since 1.0.0\n */\n altitudeAccuracy?: number | null | undefined;\n /**\n * The speed the user is traveling (if available)\n *\n * @since 1.0.0\n */\n speed: number | null;\n /**\n * The heading the user is facing (if available)\n *\n * @since 1.0.0\n */\n heading: number | null;\n}\n\nexport interface BatteryStatus {\n batteryLevel: number;\n isCharging: boolean;\n}\n\nexport interface NetworkStatus {\n connected: boolean;\n connectionType: string;\n}\n\nexport interface NotificationBadgeOptions {\n /**\n * The number to set on the application badge count.\n *\n * @since 2.0.0\n */\n count: number;\n /**\n * The **required** title for the associated badge count notification.\n *\n * Only for Android.\n *\n * @since 2.0.0\n */\n notificationTitle: string;\n /**\n * The subtitle for the associated badge count notification.\n *\n * Only for Android.\n *\n * @since 2.0.0\n */\n notificationSubtitle: string;\n}\n\nexport interface NotificationScheduleOptions {\n /**\n * The notification identifier.\n * On Android it's a 32-bit int.\n * So the value should be between -2147483648 and 2147483647 inclusive.\n *\n * @since 1.0.0\n */\n id: number;\n /**\n * The title of the notification.\n *\n * @since 1.0.0\n */\n title: string;\n /**\n * The body of the notification, shown below the title.\n *\n * @since 1.0.0\n */\n body: string;\n /**\n * Date to send this notification.\n *\n * @since 1.0.0\n */\n scheduleAt: Date;\n /**\n * Name of the audio file to play when this notification is displayed.\n *\n * Include the file extension with the filename.\n *\n * On iOS, the file should be in the app bundle.\n * On Android, the file should be in res/raw folder.\n *\n * Recommended format is `.wav` because is supported by both iOS and Android.\n *\n * Only available for iOS and Android < 26.\n * For Android 26+ use channelId of a channel configured with the desired sound.\n *\n * If the sound file is not found, (i.e. empty string or wrong name)\n * the default system notification sound will be used.\n * If not provided, it will produce the default sound on Android and no sound on iOS.\n *\n * @since 1.0.0\n */\n sound?: string;\n /**\n * Associate an action type with this notification.\n *\n * @since 1.0.0\n */\n actionTypeId?: string;\n /**\n * Used to group multiple notifications.\n *\n * Sets `threadIdentifier` on the\n * [`UNMutableNotificationContent`](https://developer.apple.com/documentation/usernotifications/unmutablenotificationcontent).\n *\n * Only available for iOS.\n *\n * @since 1.0.0\n */\n threadIdentifier?: string;\n /**\n * The string this notification adds to the category's summary format string.\n *\n * Only available for iOS.\n *\n * **This option has no effect.** `summaryArgument` on\n * [`UNMutableNotificationContent`](https://developer.apple.com/documentation/usernotifications/unmutablenotificationcontent)\n * is deprecated since iOS 15 and the value is ignored by the system, so it is\n * no longer set on the notification content.\n *\n * @since 1.0.0\n * @deprecated This option has no effect, iOS ignores it since iOS 15.\n */\n summaryArgument?: string;\n /**\n * Used to group multiple notifications.\n *\n * Calls `setGroup()` on\n * [`NotificationCompat.Builder`](https://developer.android.com/reference/androidx/core/app/NotificationCompat.Builder)\n * with the provided value.\n *\n * Only available for Android.\n *\n * @since 1.0.0\n */\n group?: string;\n /**\n * If true, this notification becomes the summary for a group of\n * notifications.\n *\n * Calls `setGroupSummary()` on\n * [`NotificationCompat.Builder`](https://developer.android.com/reference/androidx/core/app/NotificationCompat.Builder)\n * with the provided value.\n *\n * Only available for Android when using `group`.\n *\n * @since 1.0.0\n */\n groupSummary?: string;\n /**\n * Set extra data to store within this notification.\n *\n * @since 1.0.0\n */\n extra?: any;\n /**\n * If true, the notification can't be swiped away.\n *\n * Calls `setOngoing()` on\n * [`NotificationCompat.Builder`](https://developer.android.com/reference/androidx/core/app/NotificationCompat.Builder)\n * with the provided value.\n *\n * Only available for Android.\n *\n * @since 1.0.0\n */\n ongoing?: boolean;\n /**\n * If true, the notification is canceled when the user clicks on it.\n *\n * Calls `setAutoCancel()` on\n * [`NotificationCompat.Builder`](https://developer.android.com/reference/androidx/core/app/NotificationCompat.Builder)\n * with the provided value.\n *\n * Only available for Android.\n *\n * @since 1.0.0\n */\n autoCancel?: boolean;\n /**\n * Sets a multiline text block for display in a big text notification style.\n *\n * @since 1.0.0\n */\n largeBody?: string;\n /**\n * Used to set the summary text detail in inbox and big text notification styles.\n *\n * Only available for Android.\n *\n * @since 1.0.0\n */\n summaryText?: string;\n /**\n * Set a custom status bar icon.\n *\n * If set, this overrides the `smallIcon` option from Capacitor\n * configuration.\n *\n * Icons should be placed in your app's `res/drawable` folder. The value for\n * this option should be the drawable resource ID, which is the filename\n * without an extension.\n *\n * Only available for Android.\n *\n * @since 1.0.0\n */\n smallIcon?: string;\n /**\n * Set a large icon for notifications.\n *\n * Icons should be placed in your app's `res/drawable` folder. The value for\n * this option should be the drawable resource ID, which is the filename\n * without an extension.\n *\n * Only available for Android.\n *\n * @since 1.0.0\n */\n largeIcon?: string;\n /**\n * Specifies the channel the notification should be delivered on.\n *\n * If channel with the given name does not exist then the notification will\n * not fire. If not provided, it will use the default channel.\n *\n * Calls `setChannelId()` on\n * [`NotificationCompat.Builder`](https://developer.android.com/reference/androidx/core/app/NotificationCompat.Builder)\n * with the provided value.\n *\n * Only available for Android 26+.\n *\n * @since 1.0.0\n */\n channelId?: string;\n}\n\nexport interface AppInfo {\n /**\n * The name of the app.\n *\n * @since 1.0.0\n */\n name: string;\n\n /**\n * The identifier of the app.\n * On iOS it's the Bundle Identifier.\n * On Android it's the Application ID\n *\n * @since 1.0.0\n */\n id: string;\n\n /**\n * The build version.\n * On iOS it's the CFBundleVersion.\n * On Android it's the versionCode.\n *\n * @since 1.0.0\n */\n build: string;\n\n /**\n * The app version.\n * On iOS it's the CFBundleShortVersionString.\n * On Android it's package's versionName.\n *\n * @since 1.0.0\n */\n version: string;\n}\n\nexport interface AppState {\n /**\n * Whether the app is active or not.\n *\n * @since 1.0.0\n */\n isActive: boolean;\n}\n\n/**\n * Get access to device location information.\n *\n * @since 1.0.0\n */\nexport interface CapacitorGeolocation {\n /**\n * Get the device's last known location\n * @since 1.0.0\n */\n getCurrentPosition: () => GetCurrentPositionResult;\n}\n\n/**\n * A simple string key / value store backed by UserDefaults on iOS and Shared Preferences on Android.\n */\nexport interface CapacitorKV {\n /**\n * Set a string value with the given key.\n *\n * @param key\n * @param value\n * @returns\n * @since 1.0.0\n */\n set: (key: string, value: string) => void;\n /**\n * Get a string value for the given key.\n * @param key\n * @returns\n * @since 1.0.0\n */\n get: (key: string) => { value: string };\n /**\n * Remove a value with the given key.\n * @param key\n * @returns\n * @since 1.0.0\n */\n remove: (key: string) => void;\n}\n\n/**\n * Get information on the device, such as network connectivity and battery status.\n */\nexport interface CapacitorDevice {\n /**\n * Get the current battery status for the device.\n *\n * @since 1.0.0\n */\n getBatteryStatus: () => BatteryStatus;\n /**\n * Get the current network status for the device.\n *\n * @since 1.0.0\n */\n getNetworkStatus: () => NetworkStatus;\n}\n\n/**\n * Send basic local notifications.\n */\nexport interface CapacitorNotifications {\n /**\n * Schedule a local notification\n * @example `CapacitorNotifications.schedule()`\n * @param options\n * @returns void\n * @since 1.0.0\n */\n schedule: (options: NotificationScheduleOptions[]) => void;\n /**\n * Set the application badge count\n * @example `CapacitorNotifications.setBadge({...})`\n * @param options\n * @returns void\n * @since 2.0.0\n */\n setBadge: (options: NotificationBadgeOptions) => void;\n /**\n * Clears the application badge count\n * @example `CapacitorNotifications.clearBadge()`\n * @returns void\n * @since 2.0.0\n */\n clearBadge: () => void;\n}\n\n/**\n * Interact with a watch paired with this app\n *\n * sendMessage, transferUserInfo and updateApplicationContext are raw routes to the WCSession delegate methods, but have no effects currently in a CapacitorWatch Watch application.\n * They could be used if a native watch app is developed as a companion app to a Capacitor app\n */\nexport interface CapacitorWatch {\n /**\n * Sends a message to the watch with the sendMessage() WCSession delegate method\n *\n * This has no effect on a CapacitorWatch watch app\n */\n sendMessage: (options: []) => void;\n /**\n * Sends information to the watch with the transferUserInfo() WCSession delegate method\n *\n * This has no effect on a CapacitorWatch watch app\n */\n transferUserInfo: (options: []) => void;\n /**\n * Updates the application context on the watch with the updateApplicationContext() WCSession delegate method\n *\n * This has no effect on a CapacitorWatch watch app\n */\n updateApplicationContext: (options: []) => void;\n /**\n * Checks to see if the compaion watch is reachable\n */\n isReachable: boolean;\n /**\n * Replaces the current UI on the watch with what is specified here.\n * @param options the new WatchUI you want to show on the watch\n * @returns void\n */\n updateWatchUI: (options: { watchUI: string }) => void;\n /**\n * Updates the data the watch is using to display variables in text and button fields\n * @param options the new data to send to the watch\n * @returns void\n */\n updateWatchData: (options: { data: { [key: string]: string } }) => void;\n}\n\nexport interface CapacitorApp {\n getState: () => AppState;\n getInfo: () => AppInfo;\n}\n\nexport interface CapacitorAPI {\n CapacitorDevice: CapacitorDevice;\n CapacitorKV: CapacitorKV;\n CapacitorNotifications: CapacitorNotifications;\n CapacitorGeolocation: CapacitorGeolocation;\n CapacitorWatch: CapacitorWatch;\n CapacitorApp: CapacitorApp;\n}\n"]}
@@ -25,7 +25,7 @@ export interface BackgroundRunnerConfig {
25
25
  */
26
26
  repeat: boolean;
27
27
  /**
28
- * The number of minutes after the the app is put into the background in which the background task should begin.
28
+ * The number of minutes after the app is put into the background in which the background task should begin.
29
29
  *
30
30
  * If `repeat` is true, this also specifies the number of minutes between each execution.
31
31
  *
@@ -76,7 +76,7 @@ declare module '@capacitor/cli' {
76
76
  */
77
77
  repeat: boolean;
78
78
  /**
79
- * The number of minutes after the the app is put into the background in which the background task should begin.
79
+ * The number of minutes after the app is put into the background in which the background task should begin.
80
80
  *
81
81
  * If `repeat` is true, this also specifies the number of minutes between each execution.
82
82
  *
@@ -1 +1 @@
1
- {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"AAAA,wCAAwC","sourcesContent":["/// <reference types=\"@capacitor/cli\" />\n\nimport type { PermissionState, PluginListenerHandle } from '@capacitor/core';\n\nexport interface BackgroundRunnerConfig {\n /**\n * The name of the runner, used in logs.\n *\n * @since 1.0.0\n */\n label: string;\n /**\n * The path to the runner JavaScript file, relative to the app bundle.\n *\n * @since 1.0.0\n */\n src: string;\n /**\n * The name of the event that will be called when the OS executes the background task.\n *\n * @since 1.0.0\n */\n event: string;\n /**\n * If background task should repeat based on the interval set in `interval`.\n *\n * @since 1.0.0\n */\n repeat: boolean;\n /**\n * The number of minutes after the the app is put into the background in which the background task should begin.\n *\n * If `repeat` is true, this also specifies the number of minutes between each execution.\n *\n * @since 1.0.0\n */\n interval: number;\n /**\n * Automatically register and schedule background task on app load.\n *\n * @since 1.0.0\n */\n autoStart?: boolean;\n}\n\ndeclare module '@capacitor/cli' {\n export interface PluginsConfig {\n /**\n * On load, Background Runner will automatically register a\n * background task that will be scheduled and run once your app is\n * backgrounded.\n */\n BackgroundRunner?: {\n /**\n * The name of the runner, used in logs.\n *\n * @since 1.0.0\n * @example \"com.example.background.task\"\n */\n label: string;\n /**\n * The path to the runner JavaScript file, relative to the app bundle.\n *\n * @since 1.0.0\n * @example \"runners/background.js\"\n */\n src: string;\n /**\n * The name of the event that will be called when the OS executes the background task.\n *\n * @since 1.0.0\n * @example \"myCustomEvent\"\n */\n event: string;\n /**\n * If background task should repeat based on the interval set in `interval`.\n *\n * @since 1.0.0\n * @example true\n */\n repeat: boolean;\n /**\n * The number of minutes after the the app is put into the background in which the background task should begin.\n *\n * If `repeat` is true, this also specifies the number of minutes between each execution.\n *\n * @since 1.0.0\n * @example 15\n */\n interval: number;\n /**\n * Automatically register and schedule background task on app load.\n *\n * @since 1.0.0\n * @example true\n */\n autoStart?: boolean;\n };\n }\n}\n\nexport type API = 'geolocation' | 'notifications';\n\nexport interface PermissionStatus {\n geolocation: PermissionState;\n notifications: PermissionState;\n}\n\nexport interface DispatchEventOptions {\n /**\n * The runner label to dispatch the event to\n *\n * @since 1.0.0\n */\n label: string;\n /**\n * The name of the registered event listener.\n *\n * @since 1.0.0\n */\n event: string;\n details: { [key: string]: any };\n}\n\nexport interface RequestPermissionOptions {\n apis: API[];\n}\n\nexport interface RegisterBackgroundTaskOptions {\n runner: BackgroundRunnerConfig;\n}\n\nexport interface NotificationActionEvent {\n actionTypeId: string;\n notificationId: number;\n}\n\nexport interface BackgroundRunnerPlugin {\n /**\n * Check permissions for the various Capacitor device APIs.\n *\n * @since 1.0.0\n */\n checkPermissions(): Promise<PermissionStatus>;\n /**\n * Request permission to display local notifications.\n *\n * @since 1.0.0\n */\n requestPermissions(options: RequestPermissionOptions): Promise<PermissionStatus>;\n /**\n * Dispatches an event to the configured runner.\n * @param options\n * @since 1.0.0\n */\n dispatchEvent<T = void>(options: DispatchEventOptions): Promise<T>;\n /**\n * Add a listener for notification actions.\n *\n * @since 2.1.1\n */\n addListener(\n eventName: 'backgroundRunnerNotificationReceived',\n listenerFunc: (event: NotificationActionEvent) => void,\n ): Promise<PluginListenerHandle>;\n /**\n * Remove notification action listeners for this plugin.\n *\n * @since 2.1.1\n */\n removeNotificationListeners(): Promise<void>;\n}\n\ndeclare module '@capacitor/cli' {\n export interface PluginsConfig {\n BackgroundRunner?: BackgroundRunnerConfig;\n }\n}\n"]}
1
+ {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"AAAA,wCAAwC","sourcesContent":["/// <reference types=\"@capacitor/cli\" />\n\nimport type { PermissionState, PluginListenerHandle } from '@capacitor/core';\n\nexport interface BackgroundRunnerConfig {\n /**\n * The name of the runner, used in logs.\n *\n * @since 1.0.0\n */\n label: string;\n /**\n * The path to the runner JavaScript file, relative to the app bundle.\n *\n * @since 1.0.0\n */\n src: string;\n /**\n * The name of the event that will be called when the OS executes the background task.\n *\n * @since 1.0.0\n */\n event: string;\n /**\n * If background task should repeat based on the interval set in `interval`.\n *\n * @since 1.0.0\n */\n repeat: boolean;\n /**\n * The number of minutes after the app is put into the background in which the background task should begin.\n *\n * If `repeat` is true, this also specifies the number of minutes between each execution.\n *\n * @since 1.0.0\n */\n interval: number;\n /**\n * Automatically register and schedule background task on app load.\n *\n * @since 1.0.0\n */\n autoStart?: boolean;\n}\n\ndeclare module '@capacitor/cli' {\n export interface PluginsConfig {\n /**\n * On load, Background Runner will automatically register a\n * background task that will be scheduled and run once your app is\n * backgrounded.\n */\n BackgroundRunner?: {\n /**\n * The name of the runner, used in logs.\n *\n * @since 1.0.0\n * @example \"com.example.background.task\"\n */\n label: string;\n /**\n * The path to the runner JavaScript file, relative to the app bundle.\n *\n * @since 1.0.0\n * @example \"runners/background.js\"\n */\n src: string;\n /**\n * The name of the event that will be called when the OS executes the background task.\n *\n * @since 1.0.0\n * @example \"myCustomEvent\"\n */\n event: string;\n /**\n * If background task should repeat based on the interval set in `interval`.\n *\n * @since 1.0.0\n * @example true\n */\n repeat: boolean;\n /**\n * The number of minutes after the app is put into the background in which the background task should begin.\n *\n * If `repeat` is true, this also specifies the number of minutes between each execution.\n *\n * @since 1.0.0\n * @example 15\n */\n interval: number;\n /**\n * Automatically register and schedule background task on app load.\n *\n * @since 1.0.0\n * @example true\n */\n autoStart?: boolean;\n };\n }\n}\n\nexport type API = 'geolocation' | 'notifications';\n\nexport interface PermissionStatus {\n geolocation: PermissionState;\n notifications: PermissionState;\n}\n\nexport interface DispatchEventOptions {\n /**\n * The runner label to dispatch the event to\n *\n * @since 1.0.0\n */\n label: string;\n /**\n * The name of the registered event listener.\n *\n * @since 1.0.0\n */\n event: string;\n details: { [key: string]: any };\n}\n\nexport interface RequestPermissionOptions {\n apis: API[];\n}\n\nexport interface RegisterBackgroundTaskOptions {\n runner: BackgroundRunnerConfig;\n}\n\nexport interface NotificationActionEvent {\n actionTypeId: string;\n notificationId: number;\n}\n\nexport interface BackgroundRunnerPlugin {\n /**\n * Check permissions for the various Capacitor device APIs.\n *\n * @since 1.0.0\n */\n checkPermissions(): Promise<PermissionStatus>;\n /**\n * Request permission to display local notifications.\n *\n * @since 1.0.0\n */\n requestPermissions(options: RequestPermissionOptions): Promise<PermissionStatus>;\n /**\n * Dispatches an event to the configured runner.\n * @param options\n * @since 1.0.0\n */\n dispatchEvent<T = void>(options: DispatchEventOptions): Promise<T>;\n /**\n * Add a listener for notification actions.\n *\n * @since 2.1.1\n */\n addListener(\n eventName: 'backgroundRunnerNotificationReceived',\n listenerFunc: (event: NotificationActionEvent) => void,\n ): Promise<PluginListenerHandle>;\n /**\n * Remove notification action listeners for this plugin.\n *\n * @since 2.1.1\n */\n removeNotificationListeners(): Promise<void>;\n}\n\ndeclare module '@capacitor/cli' {\n export interface PluginsConfig {\n BackgroundRunner?: BackgroundRunnerConfig;\n }\n}\n"]}
@@ -18,6 +18,8 @@ enum CapacitorGeolocationErrors: Error, Equatable {
18
18
  }
19
19
 
20
20
  class CapacitorGeolocation: NSObject, CapacitorGeolocationExports, CLLocationManagerDelegate {
21
+ private static let permissionManager = CLLocationManager()
22
+
21
23
  private weak var context: Context?
22
24
  private var pendingCurrentLocationCalls: [Int: (Result<CLLocation?, Error>) -> Void] = [:]
23
25
  private var isWatchingLocation: Bool = false
@@ -36,7 +38,7 @@ class CapacitorGeolocation: NSObject, CapacitorGeolocationExports, CLLocationMan
36
38
  self.context = context
37
39
  self.locationManager.delegate = self
38
40
 
39
- if CLLocationManager.authorizationStatus() == .authorizedAlways {
41
+ if self.locationManager.authorizationStatus == .authorizedAlways {
40
42
  self.locationManager.allowsBackgroundLocationUpdates = true
41
43
  self.locationManager.desiredAccuracy = kCLLocationAccuracyKilometer
42
44
  self.locationManager.pausesLocationUpdatesAutomatically = false
@@ -55,8 +57,8 @@ class CapacitorGeolocation: NSObject, CapacitorGeolocationExports, CLLocationMan
55
57
 
56
58
  var permission: String = "prompt"
57
59
 
58
- switch CLLocationManager.authorizationStatus() {
59
- case .authorized, .authorizedWhenInUse, .authorizedAlways:
60
+ switch permissionManager.authorizationStatus {
61
+ case .authorizedWhenInUse, .authorizedAlways:
60
62
  permission = "granted"
61
63
  case .notDetermined:
62
64
  permission = "prompt"
@@ -74,7 +76,7 @@ class CapacitorGeolocation: NSObject, CapacitorGeolocationExports, CLLocationMan
74
76
  return
75
77
  }
76
78
 
77
- if CLLocationManager.authorizationStatus() != .notDetermined {
79
+ if self.locationManager.authorizationStatus != .notDetermined {
78
80
  return
79
81
  }
80
82
 
@@ -30,8 +30,6 @@ struct NotificationOption {
30
30
  let actionTypeId: String?
31
31
  let extra: [String: Any]?
32
32
  let threadIdentifier: String?
33
- let summaryArgument: String?
34
- let groupSummary: String?
35
33
 
36
34
  init(from dict: [String: Any?]) throws {
37
35
  guard let id = dict["id"] as? Int else {
@@ -58,8 +56,6 @@ struct NotificationOption {
58
56
  self.sound = dict["sound"] as? String
59
57
  self.actionTypeId = dict["actionTypeId"] as? String
60
58
  self.extra = dict["extra"] as? [String: Any]
61
- self.summaryArgument = dict["summaryArgument"] as? String
62
- self.groupSummary = dict["groupSummary"] as? String
63
59
  }
64
60
  }
65
61
 
@@ -151,10 +147,6 @@ class CapacitorNotifications: NSObject, CapacitorNotificationsExports {
151
147
  content.threadIdentifier = threadIdentifier
152
148
  }
153
149
 
154
- if let summaryArgument = notificationOption.summaryArgument {
155
- content.summaryArgument = summaryArgument
156
- }
157
-
158
150
  if let sound = notificationOption.sound {
159
151
  content.sound = UNNotificationSound(named: UNNotificationSoundName(sound))
160
152
  }
@@ -1,281 +1,308 @@
1
- import Foundation
2
1
  import Capacitor
3
- import WatchConnectivity
2
+ import Foundation
4
3
  import UserNotifications
4
+ import WatchConnectivity
5
5
 
6
6
  @objc(BackgroundRunnerPlugin)
7
7
  public class BackgroundRunnerPlugin: CAPPlugin, CAPBridgedPlugin {
8
- public let identifier = "CapacitorBackgroundRunnerPlugin"
9
- public let jsName = "CapacitorBackgroundRunner"
10
- public let pluginMethods: [CAPPluginMethod] = [
11
- CAPPluginMethod(name: "checkPermissions", returnType: CAPPluginReturnPromise),
12
- CAPPluginMethod(name: "requestPermissions", returnType: CAPPluginReturnPromise),
13
- CAPPluginMethod(name: "dispatchEvent", returnType: CAPPluginReturnPromise),
14
- CAPPluginMethod(name: "registerBackgroundTask", returnType: CAPPluginReturnPromise),
15
- CAPPluginMethod(name: "removeNotificationListeners", returnType: CAPPluginReturnPromise)
16
- ]
17
- private let impl = BackgroundRunner()
18
- private weak var originalDelegate: UNUserNotificationCenterDelegate?
19
-
20
- override public func load() {
21
- NotificationCenter.default.addObserver(
22
- self,
23
- selector: #selector(didEnterBackground),
24
- name: UIApplication.didEnterBackgroundNotification,
25
- object: nil
26
- )
8
+ public let identifier = "CapacitorBackgroundRunnerPlugin"
9
+ public let jsName = "CapacitorBackgroundRunner"
10
+ public let pluginMethods: [CAPPluginMethod] = [
11
+ CAPPluginMethod(name: "checkPermissions", returnType: CAPPluginReturnPromise),
12
+ CAPPluginMethod(name: "requestPermissions", returnType: CAPPluginReturnPromise),
13
+ CAPPluginMethod(name: "dispatchEvent", returnType: CAPPluginReturnPromise),
14
+ CAPPluginMethod(name: "registerBackgroundTask", returnType: CAPPluginReturnPromise),
15
+ CAPPluginMethod(name: "removeNotificationListeners", returnType: CAPPluginReturnPromise),
16
+ ]
17
+ private let impl = BackgroundRunner()
18
+ private weak var originalDelegate: UNUserNotificationCenterDelegate?
19
+
20
+ override public func load() {
21
+ NotificationCenter.default.addObserver(
22
+ self,
23
+ selector: #selector(didEnterBackground),
24
+ name: UIApplication.didEnterBackgroundNotification,
25
+ object: nil
26
+ )
27
+
28
+ // Register as notification delegate
29
+ registerNotificationCategories()
30
+
31
+ initWatchConnectivity()
32
+ }
33
+
34
+ @objc override public func checkPermissions(_ call: CAPPluginCall) {
35
+ // check geolocation permissions
36
+ let geolocationState = CapacitorGeolocation.checkPermission()
37
+
38
+ // check notification permissions
39
+ let notificationState = CapacitorNotifications.checkPermission()
40
+
41
+ call.resolve([
42
+ "geolocation": geolocationState,
43
+ "notifications": notificationState,
44
+ ])
45
+ }
46
+
47
+ @objc override public func requestPermissions(_ call: CAPPluginCall) {
48
+ Task {
49
+ let permissions = call.getArray("apis") as? [String] ?? []
50
+
51
+ do {
52
+ if permissions.contains("notifications") {
53
+ try CapacitorNotifications.requestPermission()
54
+ }
27
55
 
28
- // Register as notification delegate
29
- registerNotificationCategories()
56
+ if permissions.contains("geolocation") {
57
+ let geolocation = CapacitorGeolocation()
58
+ print("geolocation requested...")
59
+ try await geolocation.requestPermission()
60
+ print("geolocation requested...done")
61
+ }
30
62
 
31
- initWatchConnectivity()
63
+ self.checkPermissions(call)
64
+ } catch {
65
+ call.reject("\(error)")
66
+ }
32
67
  }
68
+ }
33
69
 
34
- @objc override public func checkPermissions(_ call: CAPPluginCall) {
35
- // check geolocation permissions
36
- let geolocationState = CapacitorGeolocation.checkPermission()
70
+ @objc func dispatchEvent(_ call: CAPPluginCall) {
71
+ do {
72
+ guard let runnerEvent = call.getString("event"), !runnerEvent.isEmpty else {
73
+ throw BackgroundRunnerPluginError.invalidArgument(reason: "event is missing or invalid")
74
+ }
37
75
 
38
- // check notification permissions
39
- let notificationState = CapacitorNotifications.checkPermission()
76
+ let details = call.getObject("details", JSObject())
40
77
 
41
- call.resolve([
42
- "geolocation": geolocationState,
43
- "notifications": notificationState
44
- ])
45
- }
78
+ guard var config = impl.config else {
79
+ throw BackgroundRunnerPluginError.noRunnerConfig
80
+ }
46
81
 
47
- @objc override public func requestPermissions(_ call: CAPPluginCall) {
48
- Task {
49
- let permissions = call.getArray("apis") as? [String] ?? []
50
-
51
- do {
52
- if permissions.contains("notifications") {
53
- try CapacitorNotifications.requestPermission()
54
- }
55
-
56
- if permissions.contains("geolocation") {
57
- let geolocation = CapacitorGeolocation()
58
- print("geolocation requested...")
59
- try await geolocation.requestPermission()
60
- print("geolocation requested...done")
61
- }
62
-
63
- self.checkPermissions(call)
64
- } catch {
65
- call.reject("\(error)")
66
- }
67
- }
68
- }
82
+ config.event = runnerEvent
69
83
 
70
- @objc func dispatchEvent(_ call: CAPPluginCall) {
84
+ // swiftlint:disable:next unowned_variable_capture
85
+ DispatchQueue.global(qos: .userInitiated).async { [unowned self] in
71
86
  do {
72
- guard let runnerEvent = call.getString("event"), !runnerEvent.isEmpty else {
73
- throw BackgroundRunnerPluginError.invalidArgument(reason: "event is missing or invalid")
74
- }
75
-
76
- let details = call.getObject("details", JSObject())
77
-
78
- guard var config = impl.config else {
79
- throw BackgroundRunnerPluginError.noRunnerConfig
80
- }
81
-
82
- config.event = runnerEvent
83
-
84
- // swiftlint:disable:next unowned_variable_capture
85
- DispatchQueue.global(qos: .userInitiated).async { [unowned self] in
86
- do {
87
- let result = try self.impl.execute(
88
- config: config,
89
- inputArgs: details as [String: Any],
90
- callbackId: call.callbackId
91
- )
92
-
93
- if let result = result {
94
- call.resolve(result)
95
- return
96
- }
97
-
98
- call.resolve()
99
- } catch {
100
- call.reject("\(error)")
101
- }
102
- }
87
+ let result = try self.impl.execute(
88
+ config: config,
89
+ inputArgs: details as [String: Any],
90
+ callbackId: call.callbackId
91
+ )
92
+
93
+ if let result = result {
94
+ call.resolve(result)
95
+ return
96
+ }
97
+
98
+ call.resolve()
103
99
  } catch {
104
- call.reject("\(error)")
100
+ call.reject("\(error)")
105
101
  }
102
+ }
103
+ } catch {
104
+ call.reject("\(error)")
105
+ }
106
+ }
107
+
108
+ @objc func registerBackgroundTask(_ call: CAPPluginCall) {
109
+ call.resolve()
110
+ }
111
+
112
+ @objc func removeNotificationListeners(_ call: CAPPluginCall) {
113
+ notifyListeners("backgroundRunnerNotificationReceived", data: nil)
114
+ call.resolve()
115
+ }
116
+
117
+ @objc private func didEnterBackground() {
118
+ do {
119
+ try impl.scheduleBackgroundTasks()
120
+ } catch {
121
+ print("could not schedule background task: \(error)")
106
122
  }
123
+ }
107
124
 
108
- @objc func registerBackgroundTask(_ call: CAPPluginCall) {
109
- call.resolve()
125
+ public static func registerBackgroundTask() {
126
+ do {
127
+ try BackgroundRunner.shared.registerBackgroundTask()
128
+ } catch {
129
+ print("could not register background task: \(error)")
130
+ }
131
+ }
132
+
133
+ public static func dispatchEvent(
134
+ event: String, eventArgs: [AnyHashable: Any], completionHandler: ((Result<Bool, Error>) -> Void)
135
+ ) {
136
+ if event.isEmpty {
137
+ completionHandler(
138
+ .failure(BackgroundRunnerPluginError.invalidArgument(reason: "event is missing or invalid"))
139
+ )
140
+ return
110
141
  }
111
142
 
112
- @objc func removeNotificationListeners(_ call: CAPPluginCall) {
113
- notifyListeners("backgroundRunnerNotificationReceived", data: nil)
114
- call.resolve()
143
+ var args: [String: Any] = [:]
144
+
145
+ eventArgs.forEach { (key: AnyHashable, value: Any) in
146
+ if let strKey = key as? String {
147
+ args[strKey] = value
148
+ }
115
149
  }
116
150
 
117
- @objc private func didEnterBackground() {
118
- do {
119
- try impl.scheduleBackgroundTasks()
120
- } catch {
121
- print("could not schedule background task: \(error)")
122
- }
151
+ do {
152
+ try BackgroundRunner.shared.dispatchEvent(event: event, inputArgs: args)
153
+ completionHandler(.success(true))
154
+ } catch {
155
+ completionHandler(.failure(error))
123
156
  }
157
+ }
124
158
 
125
- public static func registerBackgroundTask() {
126
- do {
127
- try BackgroundRunner.shared.registerBackgroundTask()
128
- } catch {
129
- print("could not register background task: \(error)")
130
- }
159
+ public static func handleApplicationDidFinishLaunching(
160
+ launchOptions: [UIApplication.LaunchOptionsKey: Any]?
161
+ ) {
162
+ guard let launchOptions = launchOptions else {
163
+ return
131
164
  }
132
165
 
133
- public static func dispatchEvent(event: String, eventArgs: [AnyHashable: Any], completionHandler: ((Result<Bool, Error>) -> Void)) {
134
- if event.isEmpty {
135
- completionHandler(.failure(BackgroundRunnerPluginError.invalidArgument(reason: "event is missing or invalid")))
136
- return
137
- }
166
+ var events: [String: [String: Any]?] = [:]
138
167
 
139
- var args: [String: Any] = [:]
168
+ if launchOptions[.location] != nil {
169
+ // application was launched for a location event
170
+ var details: [String: Any] = [:]
171
+ details["locations"] = nil
140
172
 
141
- eventArgs.forEach { (key: AnyHashable, value: Any) in
142
- if let strKey = key as? String {
143
- args[strKey] = value
144
- }
145
- }
173
+ if let location = CapacitorGeolocation.getCurrentKnownLocation() {
174
+ var details: [String: Any] = [:]
175
+ details["locations"] = [location]
176
+ }
146
177
 
147
- do {
148
- try BackgroundRunner.shared.dispatchEvent(event: event, inputArgs: args)
149
- completionHandler(.success(true))
150
- } catch {
151
- completionHandler(.failure(error))
152
- }
178
+ events["currentLocation"] = details
153
179
  }
154
180
 
155
- public static func handleApplicationDidFinishLaunching(launchOptions: [UIApplication.LaunchOptionsKey: Any]?) {
156
- guard let launchOptions = launchOptions else {
157
- return
158
- }
159
-
160
- var events: [String: [String: Any]?] = [:]
161
-
162
- if launchOptions[.location] != nil {
163
- // application was launched for a location event
164
- var details: [String: Any] = [:]
165
- details["locations"] = nil
181
+ print("emit events: \(events)")
166
182
 
167
- if let location = CapacitorGeolocation.getCurrentKnownLocation() {
168
- var details: [String: Any] = [:]
169
- details["locations"] = [location]
170
- }
183
+ }
171
184
 
172
- events["currentLocation"] = details
173
- }
185
+ private func initWatchConnectivity() {
186
+ if !WCSession.isSupported() {
187
+ return
188
+ }
174
189
 
175
- print("emit events: \(events)")
190
+ guard let config = impl.config else {
191
+ return
192
+ }
176
193
 
194
+ if !config.enableWatchConnectivity {
195
+ return
177
196
  }
178
197
 
179
- private func initWatchConnectivity() {
180
- if !WCSession.isSupported() {
181
- return
182
- }
198
+ WCSession.default.delegate = self
199
+ WCSession.default.activate()
183
200
 
184
- guard let config = impl.config else {
185
- return
186
- }
187
-
188
- if !config.enableWatchConnectivity {
189
- return
190
- }
201
+ print("Watch Connectivity Enabled")
202
+ }
191
203
 
192
- WCSession.default.delegate = self
193
- WCSession.default.activate()
204
+ @objc func registerNotificationCategories() {
205
+ let notificationCenter = UNUserNotificationCenter.current()
194
206
 
195
- print("Watch Connectivity Enabled")
207
+ // Capture the original delegate if it's not self
208
+ if notificationCenter.delegate !== self {
209
+ originalDelegate = notificationCenter.delegate
196
210
  }
197
211
 
198
- @objc func registerNotificationCategories() {
199
- let notificationCenter = UNUserNotificationCenter.current()
200
-
201
- // Capture the original delegate if it's not self
202
- if notificationCenter.delegate !== self {
203
- originalDelegate = notificationCenter.delegate
204
- }
205
-
206
- // Set the plugin as the notification delegate
207
- notificationCenter.delegate = self
208
- }
212
+ // Set the plugin as the notification delegate
213
+ notificationCenter.delegate = self
214
+ }
209
215
  }
210
216
 
211
217
  // MARK: - UNUserNotificationCenterDelegate
212
218
  extension BackgroundRunnerPlugin: UNUserNotificationCenterDelegate {
213
- // This method will be called when a notification is tapped
214
- public func userNotificationCenter(_ center: UNUserNotificationCenter,
215
- didReceive response: UNNotificationResponse,
216
- withCompletionHandler completionHandler: @escaping () -> Void) {
217
- let userInfo = response.notification.request.content.userInfo
218
-
219
- if isBackgroundRunnerNotification(userInfo) {
220
- handleBackgroundRunnerNotification(response, completionHandler: completionHandler)
221
- } else {
222
- forwardToOriginalDelegate(center, didReceive: response, withCompletionHandler: completionHandler)
223
- }
219
+ // This method will be called when a notification is tapped
220
+ public func userNotificationCenter(
221
+ _ center: UNUserNotificationCenter,
222
+ didReceive response: UNNotificationResponse,
223
+ withCompletionHandler completionHandler: @escaping () -> Void
224
+ ) {
225
+ let userInfo = response.notification.request.content.userInfo
226
+
227
+ if isBackgroundRunnerNotification(userInfo) {
228
+ handleBackgroundRunnerNotification(response, completionHandler: completionHandler)
229
+ } else {
230
+ forwardToOriginalDelegate(
231
+ center, didReceive: response, withCompletionHandler: completionHandler)
224
232
  }
225
-
226
- // This is needed to present notifications when the app is in the foreground
227
- public func userNotificationCenter(_ center: UNUserNotificationCenter,
228
- willPresent notification: UNNotification,
229
- withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
230
- let userInfo = notification.request.content.userInfo
231
-
232
- if isBackgroundRunnerNotification(userInfo) {
233
- handleBackgroundRunnerPresentation(completionHandler: completionHandler)
234
- } else {
235
- forwardToOriginalDelegate(center, willPresent: notification, withCompletionHandler: completionHandler)
236
- }
233
+ }
234
+
235
+ // This is needed to present notifications when the app is in the foreground
236
+ public func userNotificationCenter(
237
+ _ center: UNUserNotificationCenter,
238
+ willPresent notification: UNNotification,
239
+ withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void
240
+ ) {
241
+ let userInfo = notification.request.content.userInfo
242
+
243
+ if isBackgroundRunnerNotification(userInfo) {
244
+ handleBackgroundRunnerPresentation(completionHandler: completionHandler)
245
+ } else {
246
+ forwardToOriginalDelegate(
247
+ center, willPresent: notification, withCompletionHandler: completionHandler)
237
248
  }
249
+ }
238
250
 
239
- // MARK: - Helper Methods
240
-
241
- private func isBackgroundRunnerNotification(_ userInfo: [AnyHashable: Any]) -> Bool {
242
- return (userInfo["source"] as? String) == "capacitor-background-runner"
243
- }
251
+ // MARK: - Helper Methods
244
252
 
245
- private func handleBackgroundRunnerNotification(_ response: UNNotificationResponse, completionHandler: @escaping () -> Void) {
246
- let actionTypeId = response.notification.request.content.categoryIdentifier
247
- let notificationId = Int(response.notification.request.identifier) ?? -1
253
+ private func isBackgroundRunnerNotification(_ userInfo: [AnyHashable: Any]) -> Bool {
254
+ return (userInfo["source"] as? String) == "capacitor-background-runner"
255
+ }
248
256
 
249
- let eventData: [String: Any] = [
250
- "actionTypeId": actionTypeId,
251
- "notificationId": notificationId
252
- ]
257
+ private func handleBackgroundRunnerNotification(
258
+ _ response: UNNotificationResponse, completionHandler: @escaping () -> Void
259
+ ) {
260
+ let actionTypeId = response.notification.request.content.categoryIdentifier
261
+ let notificationId = Int(response.notification.request.identifier) ?? -1
253
262
 
254
- notifyListeners("backgroundRunnerNotificationReceived", data: eventData, retainUntilConsumed: true)
255
- completionHandler()
256
- }
263
+ let eventData: [String: Any] = [
264
+ "actionTypeId": actionTypeId,
265
+ "notificationId": notificationId,
266
+ ]
257
267
 
258
- private func forwardToOriginalDelegate(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
259
- if let originalDelegate = originalDelegate, originalDelegate.responds(to: #selector(userNotificationCenter(_:didReceive:withCompletionHandler:))) {
260
- originalDelegate.userNotificationCenter?(center, didReceive: response, withCompletionHandler: completionHandler)
261
- } else {
262
- completionHandler()
263
- }
268
+ notifyListeners(
269
+ "backgroundRunnerNotificationReceived", data: eventData, retainUntilConsumed: true)
270
+ completionHandler()
271
+ }
272
+
273
+ private func forwardToOriginalDelegate(
274
+ _ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse,
275
+ withCompletionHandler completionHandler: @escaping () -> Void
276
+ ) {
277
+ if let originalDelegate = originalDelegate,
278
+ originalDelegate.responds(
279
+ to: #selector(userNotificationCenter(_:didReceive:withCompletionHandler:)))
280
+ {
281
+ originalDelegate.userNotificationCenter?(
282
+ center, didReceive: response, withCompletionHandler: completionHandler)
283
+ } else {
284
+ completionHandler()
264
285
  }
265
-
266
- private func handleBackgroundRunnerPresentation(completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
267
- if #available(iOS 14.0, *) {
268
- completionHandler([.banner, .sound, .badge])
269
- } else {
270
- completionHandler([.alert, .sound, .badge])
271
- }
272
- }
273
-
274
- private func forwardToOriginalDelegate(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
275
- if let originalDelegate = originalDelegate, originalDelegate.responds(to: #selector(userNotificationCenter(_:willPresent:withCompletionHandler:))) {
276
- originalDelegate.userNotificationCenter?(center, willPresent: notification, withCompletionHandler: completionHandler)
277
- } else {
278
- handleBackgroundRunnerPresentation(completionHandler: completionHandler)
279
- }
286
+ }
287
+
288
+ private func handleBackgroundRunnerPresentation(
289
+ completionHandler: @escaping (UNNotificationPresentationOptions) -> Void
290
+ ) {
291
+ completionHandler([.banner, .sound, .badge])
292
+ }
293
+
294
+ private func forwardToOriginalDelegate(
295
+ _ center: UNUserNotificationCenter, willPresent notification: UNNotification,
296
+ withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void
297
+ ) {
298
+ if let originalDelegate = originalDelegate,
299
+ originalDelegate.responds(
300
+ to: #selector(userNotificationCenter(_:willPresent:withCompletionHandler:)))
301
+ {
302
+ originalDelegate.userNotificationCenter?(
303
+ center, willPresent: notification, withCompletionHandler: completionHandler)
304
+ } else {
305
+ handleBackgroundRunnerPresentation(completionHandler: completionHandler)
280
306
  }
307
+ }
281
308
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capacitor/background-runner",
3
- "version": "2.3.1",
3
+ "version": "3.1.0-dev.20260827T162451",
4
4
  "description": "Capacitor Background Runner",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",
@@ -30,32 +30,12 @@
30
30
  "plugin",
31
31
  "native"
32
32
  ],
33
- "scripts": {
34
- "verify": "npm run verify:ios && npm run verify:android && npm run verify:web",
35
- "verify:ios": "xcodebuild -scheme CapacitorBackgroundRunner -destination generic/platform=iOS && xcodebuild test -scheme CapacitorBackgroundRunner -destination 'platform=iOS Simulator,OS=18.6,name=iPhone 16 Pro'",
36
- "verify:android": "cd android && ./gradlew clean build test && cd ..",
37
- "verify:web": "npm run build",
38
- "lint": "npm run eslint && npm run prettier -- --check && npm run swiftlint -- lint",
39
- "fmt": "npm run eslint -- --fix && npm run prettier -- --write && npm run swiftlint -- --fix --format",
40
- "eslint": "eslint . --ext ts",
41
- "prettier": "prettier \"**/*.{css,html,ts,js,java}\" --plugin=prettier-plugin-java",
42
- "swiftlint": "node-swiftlint",
43
- "docgen": "docgen --api BackgroundRunnerPlugin --output-readme README.md --output-json dist/docs.json",
44
- "docgen-api": "docgen --api CapacitorAPI --output-readme API.md --output-json dist/docs-api.json && node ./scripts/combine_docs.js",
45
- "build-sdk": "./scripts/build-native-sdks.sh",
46
- "build": "npm run clean && npm run docgen && npm run docgen-api && tsc && rollup -c rollup.config.js --bundleConfigAsCjs && npm run build-sdk && ./scripts/copy-native-sdks.sh && npm pack && mv ./capacitor-background-runner-*.tgz ../../ && ./scripts/copy-readme.sh",
47
- "pack": "npm run build && ./scripts/copy-native-sdks.sh && npm pack && mv ./capacitor-background-runner-*.tgz ../../",
48
- "clean": "rimraf ./dist",
49
- "watch": "tsc --watch",
50
- "prepublishOnly": "npm run build",
51
- "postinstall": "node ./scripts/install_libs.js"
52
- },
53
33
  "devDependencies": {
54
- "@capacitor/android": "^6.2.1",
55
- "@capacitor/cli": "^6.2.1",
56
- "@capacitor/core": "^6.2.1",
57
- "@capacitor/docgen": "0.3.0",
58
- "@capacitor/ios": "^6.2.1",
34
+ "@capacitor/android": "^8.0.0",
35
+ "@capacitor/cli": "^8.0.0",
36
+ "@capacitor/core": "^8.0.0",
37
+ "@capacitor/docgen": "^0.3.0",
38
+ "@capacitor/ios": "^8.0.0",
59
39
  "@ionic/eslint-config": "^0.4.0",
60
40
  "@ionic/prettier-config": "^4.0.0",
61
41
  "@ionic/swiftlint-config": "^2.0.0",
@@ -68,7 +48,7 @@
68
48
  "typescript": "^5.9.3"
69
49
  },
70
50
  "peerDependencies": {
71
- "@capacitor/core": ">=6.0.0"
51
+ "@capacitor/core": ">=8.0.0"
72
52
  },
73
53
  "prettier": "@ionic/prettier-config",
74
54
  "swiftlint": "@ionic/swiftlint-config",
@@ -83,5 +63,23 @@
83
63
  "src": "android"
84
64
  }
85
65
  },
86
- "gitHead": "894e33fd34e7906e17d03a62602f3c5ab4101100"
87
- }
66
+ "scripts": {
67
+ "verify": "npm run verify:ios && npm run verify:android && npm run verify:web",
68
+ "verify:ios": "xcodebuild -scheme CapacitorBackgroundRunner -destination generic/platform=iOS && xcodebuild test -scheme CapacitorBackgroundRunner -destination 'platform=iOS Simulator,OS=26.0.1,name=iPhone 17 Pro'",
69
+ "verify:android": "cd android && ./gradlew clean build test && cd ..",
70
+ "verify:web": "npm run build",
71
+ "lint": "npm run eslint && npm run prettier -- --check && npm run swiftlint -- lint",
72
+ "fmt": "npm run eslint -- --fix && npm run prettier -- --write && npm run swiftlint -- --fix --format",
73
+ "eslint": "eslint . --ext ts",
74
+ "prettier": "prettier \"**/*.{css,html,ts,js,java}\" --plugin=prettier-plugin-java",
75
+ "swiftlint": "node-swiftlint",
76
+ "docgen": "docgen --api BackgroundRunnerPlugin --output-readme README.md --output-json dist/docs.json",
77
+ "docgen-api": "docgen --api CapacitorAPI --output-readme API.md --output-json dist/docs-api.json && node ./scripts/combine_docs.js",
78
+ "build-sdk": "./scripts/build-native-sdks.sh",
79
+ "build": "npm run clean && npm run docgen && npm run docgen-api && tsc && rollup -c rollup.config.js --bundleConfigAsCjs && npm run build-sdk && ./scripts/copy-native-sdks.sh && pnpm pack && mv ./capacitor-background-runner-*.tgz ../../ && ./scripts/copy-readme.sh",
80
+ "pack": "npm run build && ./scripts/copy-native-sdks.sh && pnpm pack && mv ./capacitor-background-runner-*.tgz ../../",
81
+ "clean": "rimraf ./dist",
82
+ "watch": "tsc --watch",
83
+ "postinstall": "node ./scripts/install_libs.js"
84
+ }
85
+ }