@capacitor/background-runner 3.1.0-dev.20260916T095625 → 3.1.0-dev.20260916T142655

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.
@@ -7,17 +7,16 @@ import android.net.ConnectivityManager
7
7
  import android.net.Network
8
8
  import android.net.NetworkCapabilities
9
9
  import android.os.BatteryManager
10
- import android.os.Build
11
10
  import io.ionic.android_js_engine.capacitor_api.DeviceAPI
12
11
  import org.json.JSONObject
13
12
 
14
- class Device (context: android.content.Context) : DeviceAPI {
15
- private val context: android.content.Context
13
+ class Device (context: Context) : DeviceAPI {
14
+ private val context: Context
16
15
  private val connectivityManager: ConnectivityManager
17
16
 
18
17
  init {
19
18
  this.context = context
20
- this.connectivityManager = this.context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager;
19
+ this.connectivityManager = this.context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
21
20
  }
22
21
 
23
22
  override fun getBatteryStatus(): String {
@@ -30,25 +29,20 @@ class Device (context: android.content.Context) : DeviceAPI {
30
29
 
31
30
  override fun getNetworkStatus(): String {
32
31
  var status = NetworkStatus()
33
-
34
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
35
- val activeNetwork: Network? = this.connectivityManager.activeNetwork
36
- val capabilities: NetworkCapabilities? =
37
- this.connectivityManager.getNetworkCapabilities(this.connectivityManager.activeNetwork)
38
- if (activeNetwork != null && capabilities != null) {
39
- status.connected =
40
- capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED) &&
41
- capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
42
- if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
43
- status.connectionType = NetworkStatus.ConnectionType.WIFI
44
- } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
45
- status.connectionType = NetworkStatus.ConnectionType.CELLULAR
46
- } else {
47
- status.connectionType = NetworkStatus.ConnectionType.UNKNOWN
48
- }
32
+ val activeNetwork: Network? = this.connectivityManager.activeNetwork
33
+ val capabilities: NetworkCapabilities? =
34
+ this.connectivityManager.getNetworkCapabilities(this.connectivityManager.activeNetwork)
35
+ if (activeNetwork != null && capabilities != null) {
36
+ status.connected =
37
+ capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED) &&
38
+ capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
39
+ if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
40
+ status.connectionType = NetworkStatus.ConnectionType.WIFI
41
+ } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
42
+ status.connectionType = NetworkStatus.ConnectionType.CELLULAR
43
+ } else {
44
+ status.connectionType = NetworkStatus.ConnectionType.UNKNOWN
49
45
  }
50
- } else {
51
- status = getAndParseNetworkInfo()
52
46
  }
53
47
 
54
48
  val networkInfo = JSONObject()
@@ -79,20 +73,4 @@ class Device (context: android.content.Context) : DeviceAPI {
79
73
  }
80
74
  return false
81
75
  }
82
-
83
- @Suppress("DEPRECATION")
84
- private fun getAndParseNetworkInfo(): NetworkStatus {
85
- val networkStatus = NetworkStatus()
86
- val networkInfo = connectivityManager.activeNetworkInfo
87
- if (networkInfo != null) {
88
- networkStatus.connected = networkInfo.isConnected
89
- val typeName = networkInfo.typeName
90
- if (typeName == "WIFI") {
91
- networkStatus.connectionType = NetworkStatus.ConnectionType.WIFI
92
- } else if (typeName == "MOBILE") {
93
- networkStatus.connectionType = NetworkStatus.ConnectionType.CELLULAR
94
- }
95
- }
96
- return networkStatus
97
- }
98
76
  }
@@ -125,42 +125,38 @@ class Notifications(context: Context) : NotificationsAPI {
125
125
  }
126
126
 
127
127
  private fun createNotificationChannel() {
128
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
129
- val name: CharSequence = "Default"
130
- val description = "Default"
131
- val importance = NotificationManager.IMPORTANCE_DEFAULT
132
- val channel = NotificationChannel(defaultNotificationChannelID, name, importance)
133
- channel.description = description
134
- val audioAttributes = AudioAttributes.Builder()
135
- .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
136
- .setUsage(AudioAttributes.USAGE_ALARM)
137
- .build()
138
- val soundUri = this.getDefaultSoundUrl(context)
139
- if (soundUri != null) {
140
- channel.setSound(soundUri, audioAttributes)
141
- }
142
-
143
- val notificationManager = context.getSystemService(
144
- NotificationManager::class.java
145
- )
146
- notificationManager.createNotificationChannel(channel)
128
+ val name: CharSequence = "Default"
129
+ val description = "Default"
130
+ val importance = NotificationManager.IMPORTANCE_DEFAULT
131
+ val channel = NotificationChannel(defaultNotificationChannelID, name, importance)
132
+ channel.description = description
133
+ val audioAttributes = AudioAttributes.Builder()
134
+ .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
135
+ .setUsage(AudioAttributes.USAGE_ALARM)
136
+ .build()
137
+ val soundUri = this.getDefaultSoundUrl(context)
138
+ if (soundUri != null) {
139
+ channel.setSound(soundUri, audioAttributes)
147
140
  }
141
+
142
+ val notificationManager = context.getSystemService(
143
+ NotificationManager::class.java
144
+ )
145
+ notificationManager.createNotificationChannel(channel)
148
146
  }
149
147
 
150
148
  private fun createBadgeNotificationChannel() {
151
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
152
- val name: CharSequence = "Badge"
153
- val description = "Badge"
154
- val importance = NotificationManager.IMPORTANCE_LOW
155
- val channel = NotificationChannel(defaultBadgeNotificationChannelID, name, importance)
156
- channel.description = description
157
- channel.setShowBadge(true)
158
-
159
- val notificationManager = context.getSystemService(
160
- NotificationManager::class.java
161
- )
162
- notificationManager.createNotificationChannel(channel)
163
- }
149
+ val name: CharSequence = "Badge"
150
+ val description = "Badge"
151
+ val importance = NotificationManager.IMPORTANCE_LOW
152
+ val channel = NotificationChannel(defaultBadgeNotificationChannelID, name, importance)
153
+ channel.description = description
154
+ channel.setShowBadge(true)
155
+
156
+ val notificationManager = context.getSystemService(
157
+ NotificationManager::class.java
158
+ )
159
+ notificationManager.createNotificationChannel(channel)
164
160
  }
165
161
 
166
162
  private fun getDefaultSoundUrl(context: Context): Uri? {
@@ -189,11 +189,7 @@ class CapacitorNotifications: NSObject, CapacitorNotificationsExports {
189
189
  let badgeOptions = SetBadgeOption(from: jsonDict)
190
190
 
191
191
  DispatchQueue.main.async {
192
- if #available(iOS 16.0, *) {
193
- UNUserNotificationCenter.current().setBadgeCount(badgeOptions.count)
194
- } else {
195
- UIApplication.shared.applicationIconBadgeNumber = badgeOptions.count
196
- }
192
+ UNUserNotificationCenter.current().setBadgeCount(badgeOptions.count)
197
193
  }
198
194
  } catch {
199
195
  JSContext.current().exception = JSValue(newErrorFromMessage: "\(error)", in: JSContext.current())
@@ -207,11 +203,7 @@ class CapacitorNotifications: NSObject, CapacitorNotificationsExports {
207
203
  }
208
204
 
209
205
  DispatchQueue.main.async {
210
- if #available(iOS 16.0, *) {
211
- UNUserNotificationCenter.current().setBadgeCount(0)
212
- } else {
213
- UIApplication.shared.applicationIconBadgeNumber = 0
214
- }
206
+ UNUserNotificationCenter.current().setBadgeCount(0)
215
207
  }
216
208
  } catch {
217
209
  JSContext.current().exception = JSValue(newErrorFromMessage: "\(error)", in: JSContext.current())
@@ -5,304 +5,302 @@ 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
- )
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
- }
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?
55
19
 
56
- if permissions.contains("geolocation") {
57
- let geolocation = CapacitorGeolocation()
58
- print("geolocation requested...")
59
- try await geolocation.requestPermission()
60
- print("geolocation requested...done")
61
- }
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()
62
30
 
63
- self.checkPermissions(call)
64
- } catch {
65
- call.reject("\(error)")
66
- }
31
+ initWatchConnectivity()
67
32
  }
68
- }
69
33
 
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
- }
34
+ @objc override public func checkPermissions(_ call: CAPPluginCall) {
35
+ // check geolocation permissions
36
+ let geolocationState = CapacitorGeolocation.checkPermission()
75
37
 
76
- let details = call.getObject("details", JSObject())
38
+ // check notification permissions
39
+ let notificationState = CapacitorNotifications.checkPermission()
77
40
 
78
- guard var config = impl.config else {
79
- throw BackgroundRunnerPluginError.noRunnerConfig
80
- }
41
+ call.resolve([
42
+ "geolocation": geolocationState,
43
+ "notifications": notificationState
44
+ ])
45
+ }
81
46
 
82
- config.event = runnerEvent
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
+ }
83
69
 
84
- // swiftlint:disable:next unowned_variable_capture
85
- DispatchQueue.global(qos: .userInitiated).async { [unowned self] in
70
+ @objc func dispatchEvent(_ call: CAPPluginCall) {
86
71
  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()
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
+ }
99
103
  } catch {
100
- call.reject("\(error)")
104
+ call.reject("\(error)")
101
105
  }
102
- }
103
- } catch {
104
- call.reject("\(error)")
105
106
  }
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)")
122
- }
123
- }
124
107
 
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
108
+ @objc func registerBackgroundTask(_ call: CAPPluginCall) {
109
+ call.resolve()
141
110
  }
142
111
 
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
- }
112
+ @objc func removeNotificationListeners(_ call: CAPPluginCall) {
113
+ notifyListeners("backgroundRunnerNotificationReceived", data: nil)
114
+ call.resolve()
149
115
  }
150
116
 
151
- do {
152
- try BackgroundRunner.shared.dispatchEvent(event: event, inputArgs: args)
153
- completionHandler(.success(true))
154
- } catch {
155
- completionHandler(.failure(error))
117
+ @objc private func didEnterBackground() {
118
+ do {
119
+ try impl.scheduleBackgroundTasks()
120
+ } catch {
121
+ print("could not schedule background task: \(error)")
122
+ }
156
123
  }
157
- }
158
124
 
159
- public static func handleApplicationDidFinishLaunching(
160
- launchOptions: [UIApplication.LaunchOptionsKey: Any]?
161
- ) {
162
- guard let launchOptions = launchOptions else {
163
- return
125
+ public static func registerBackgroundTask() {
126
+ do {
127
+ try BackgroundRunner.shared.registerBackgroundTask()
128
+ } catch {
129
+ print("could not register background task: \(error)")
130
+ }
164
131
  }
165
132
 
166
- var events: [String: [String: Any]?] = [:]
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
141
+ }
167
142
 
168
- if launchOptions[.location] != nil {
169
- // application was launched for a location event
170
- var details: [String: Any] = [:]
171
- details["locations"] = nil
143
+ var args: [String: Any] = [:]
172
144
 
173
- if let location = CapacitorGeolocation.getCurrentKnownLocation() {
174
- var details: [String: Any] = [:]
175
- details["locations"] = [location]
176
- }
145
+ eventArgs.forEach { (key: AnyHashable, value: Any) in
146
+ if let strKey = key as? String {
147
+ args[strKey] = value
148
+ }
149
+ }
177
150
 
178
- events["currentLocation"] = details
151
+ do {
152
+ try BackgroundRunner.shared.dispatchEvent(event: event, inputArgs: args)
153
+ completionHandler(.success(true))
154
+ } catch {
155
+ completionHandler(.failure(error))
156
+ }
179
157
  }
180
158
 
181
- print("emit events: \(events)")
159
+ public static func handleApplicationDidFinishLaunching(
160
+ launchOptions: [UIApplication.LaunchOptionsKey: Any]?
161
+ ) {
162
+ guard let launchOptions = launchOptions else {
163
+ return
164
+ }
182
165
 
183
- }
166
+ var events: [String: [String: Any]?] = [:]
184
167
 
185
- private func initWatchConnectivity() {
186
- if !WCSession.isSupported() {
187
- return
188
- }
168
+ if launchOptions[.location] != nil {
169
+ // application was launched for a location event
170
+ var details: [String: Any] = [:]
171
+ details["locations"] = nil
189
172
 
190
- guard let config = impl.config else {
191
- return
192
- }
173
+ if let location = CapacitorGeolocation.getCurrentKnownLocation() {
174
+ var details: [String: Any] = [:]
175
+ details["locations"] = [location]
176
+ }
177
+
178
+ events["currentLocation"] = details
179
+ }
180
+
181
+ print("emit events: \(events)")
193
182
 
194
- if !config.enableWatchConnectivity {
195
- return
196
183
  }
197
184
 
198
- WCSession.default.delegate = self
199
- WCSession.default.activate()
185
+ private func initWatchConnectivity() {
186
+ if !WCSession.isSupported() {
187
+ return
188
+ }
189
+
190
+ guard let config = impl.config else {
191
+ return
192
+ }
200
193
 
201
- print("Watch Connectivity Enabled")
202
- }
194
+ if !config.enableWatchConnectivity {
195
+ return
196
+ }
203
197
 
204
- @objc func registerNotificationCategories() {
205
- let notificationCenter = UNUserNotificationCenter.current()
198
+ WCSession.default.delegate = self
199
+ WCSession.default.activate()
206
200
 
207
- // Capture the original delegate if it's not self
208
- if notificationCenter.delegate !== self {
209
- originalDelegate = notificationCenter.delegate
201
+ print("Watch Connectivity Enabled")
210
202
  }
211
203
 
212
- // Set the plugin as the notification delegate
213
- notificationCenter.delegate = self
214
- }
204
+ @objc func registerNotificationCategories() {
205
+ let notificationCenter = UNUserNotificationCenter.current()
206
+
207
+ // Capture the original delegate if it's not self
208
+ if notificationCenter.delegate !== self {
209
+ originalDelegate = notificationCenter.delegate
210
+ }
211
+
212
+ // Set the plugin as the notification delegate
213
+ notificationCenter.delegate = self
214
+ }
215
215
  }
216
216
 
217
217
  // MARK: - UNUserNotificationCenterDelegate
218
218
  extension BackgroundRunnerPlugin: UNUserNotificationCenterDelegate {
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)
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)
232
+ }
232
233
  }
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)
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)
248
+ }
248
249
  }
249
- }
250
250
 
251
- // MARK: - Helper Methods
251
+ // MARK: - Helper Methods
252
252
 
253
- private func isBackgroundRunnerNotification(_ userInfo: [AnyHashable: Any]) -> Bool {
254
- return (userInfo["source"] as? String) == "capacitor-background-runner"
255
- }
253
+ private func isBackgroundRunnerNotification(_ userInfo: [AnyHashable: Any]) -> Bool {
254
+ return (userInfo["source"] as? String) == "capacitor-background-runner"
255
+ }
256
256
 
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
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
262
262
 
263
- let eventData: [String: Any] = [
264
- "actionTypeId": actionTypeId,
265
- "notificationId": notificationId,
266
- ]
263
+ let eventData: [String: Any] = [
264
+ "actionTypeId": actionTypeId,
265
+ "notificationId": notificationId
266
+ ]
267
267
 
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()
268
+ notifyListeners(
269
+ "backgroundRunnerNotificationReceived", data: eventData, retainUntilConsumed: true)
270
+ completionHandler()
285
271
  }
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)
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
+ originalDelegate.userNotificationCenter?(
281
+ center, didReceive: response, withCompletionHandler: completionHandler)
282
+ } else {
283
+ completionHandler()
284
+ }
285
+ }
286
+
287
+ private func handleBackgroundRunnerPresentation(
288
+ completionHandler: @escaping (UNNotificationPresentationOptions) -> Void
289
+ ) {
290
+ completionHandler([.banner, .sound, .badge])
291
+ }
292
+
293
+ private func forwardToOriginalDelegate(
294
+ _ center: UNUserNotificationCenter, willPresent notification: UNNotification,
295
+ withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void
296
+ ) {
297
+ if let originalDelegate = originalDelegate,
298
+ originalDelegate.responds(
299
+ to: #selector(userNotificationCenter(_:willPresent:withCompletionHandler:))) {
300
+ originalDelegate.userNotificationCenter?(
301
+ center, willPresent: notification, withCompletionHandler: completionHandler)
302
+ } else {
303
+ handleBackgroundRunnerPresentation(completionHandler: completionHandler)
304
+ }
306
305
  }
307
- }
308
306
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capacitor/background-runner",
3
- "version": "3.1.0-dev.20260916T095625",
3
+ "version": "3.1.0-dev.20260916T142655",
4
4
  "description": "Capacitor Background Runner",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",