@capacitor/background-runner 2.3.0 → 3.0.0
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.
- package/CapacitorBackgroundRunner.podspec +1 -1
- package/Package.swift +2 -2
- package/android/build.gradle +12 -12
- package/android/src/main/java/io/ionic/backgroundrunner/plugin/api/Device.kt +1 -1
- package/android/src/main/java/io/ionic/backgroundrunner/plugin/api/Notifications.kt +2 -10
- package/android/src/main/java/io/ionic/backgroundrunner/plugin/api/TimedNotificationPublisher.kt +1 -0
- package/android/src/main/libs/android-js-engine-release.aar +0 -0
- package/ios/Sources/CapacitorBackgroundRunner/CapacitorBackgroundRunner.swift +252 -225
- package/package.json +8 -8
|
@@ -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
|
+
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(.
|
|
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: "
|
|
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/android/build.gradle
CHANGED
|
@@ -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.
|
|
4
|
-
androidxCoreKTXVersion = project.hasProperty('androidxCoreKTXVersion') ? rootProject.ext.androidxCoreKTXVersion : '1.
|
|
5
|
-
androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.
|
|
6
|
-
androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.
|
|
7
|
-
workManagerVersion = project.hasProperty('workManagerVersion') ? rootProject.ext.workManagerVersion : '2.
|
|
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 : '
|
|
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.
|
|
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 :
|
|
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 :
|
|
32
|
-
targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion :
|
|
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"
|
|
@@ -41,7 +41,7 @@ android {
|
|
|
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
|
-
@
|
|
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
|
-
|
|
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
|
-
|
|
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
|
}
|
package/android/src/main/java/io/ionic/backgroundrunner/plugin/api/TimedNotificationPublisher.kt
CHANGED
|
@@ -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
|
}
|
|
Binary file
|
|
@@ -1,281 +1,308 @@
|
|
|
1
|
-
import Foundation
|
|
2
1
|
import Capacitor
|
|
3
|
-
import
|
|
2
|
+
import Foundation
|
|
4
3
|
import UserNotifications
|
|
4
|
+
import WatchConnectivity
|
|
5
5
|
|
|
6
6
|
@objc(BackgroundRunnerPlugin)
|
|
7
7
|
public class BackgroundRunnerPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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
|
-
|
|
29
|
-
|
|
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
|
-
|
|
63
|
+
self.checkPermissions(call)
|
|
64
|
+
} catch {
|
|
65
|
+
call.reject("\(error)")
|
|
66
|
+
}
|
|
32
67
|
}
|
|
68
|
+
}
|
|
33
69
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
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
|
-
|
|
39
|
-
let notificationState = CapacitorNotifications.checkPermission()
|
|
76
|
+
let details = call.getObject("details", JSObject())
|
|
40
77
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
])
|
|
45
|
-
}
|
|
78
|
+
guard var config = impl.config else {
|
|
79
|
+
throw BackgroundRunnerPluginError.noRunnerConfig
|
|
80
|
+
}
|
|
46
81
|
|
|
47
|
-
|
|
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
|
-
|
|
84
|
+
// swiftlint:disable:next unowned_variable_capture
|
|
85
|
+
DispatchQueue.global(qos: .userInitiated).async { [unowned self] in
|
|
71
86
|
do {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
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
|
-
|
|
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
|
-
|
|
109
|
-
|
|
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
|
-
|
|
113
|
-
|
|
114
|
-
|
|
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
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
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
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
}
|
|
173
|
+
if let location = CapacitorGeolocation.getCurrentKnownLocation() {
|
|
174
|
+
var details: [String: Any] = [:]
|
|
175
|
+
details["locations"] = [location]
|
|
176
|
+
}
|
|
146
177
|
|
|
147
|
-
|
|
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
|
-
|
|
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
|
-
|
|
168
|
-
var details: [String: Any] = [:]
|
|
169
|
-
details["locations"] = [location]
|
|
170
|
-
}
|
|
183
|
+
}
|
|
171
184
|
|
|
172
|
-
|
|
173
|
-
|
|
185
|
+
private func initWatchConnectivity() {
|
|
186
|
+
if !WCSession.isSupported() {
|
|
187
|
+
return
|
|
188
|
+
}
|
|
174
189
|
|
|
175
|
-
|
|
190
|
+
guard let config = impl.config else {
|
|
191
|
+
return
|
|
192
|
+
}
|
|
176
193
|
|
|
194
|
+
if !config.enableWatchConnectivity {
|
|
195
|
+
return
|
|
177
196
|
}
|
|
178
197
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
return
|
|
182
|
-
}
|
|
198
|
+
WCSession.default.delegate = self
|
|
199
|
+
WCSession.default.activate()
|
|
183
200
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
if !config.enableWatchConnectivity {
|
|
189
|
-
return
|
|
190
|
-
}
|
|
201
|
+
print("Watch Connectivity Enabled")
|
|
202
|
+
}
|
|
191
203
|
|
|
192
|
-
|
|
193
|
-
|
|
204
|
+
@objc func registerNotificationCategories() {
|
|
205
|
+
let notificationCenter = UNUserNotificationCenter.current()
|
|
194
206
|
|
|
195
|
-
|
|
207
|
+
// Capture the original delegate if it's not self
|
|
208
|
+
if notificationCenter.delegate !== self {
|
|
209
|
+
originalDelegate = notificationCenter.delegate
|
|
196
210
|
}
|
|
197
211
|
|
|
198
|
-
|
|
199
|
-
|
|
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
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
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
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
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
|
-
|
|
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
|
-
|
|
246
|
-
|
|
247
|
-
|
|
253
|
+
private func isBackgroundRunnerNotification(_ userInfo: [AnyHashable: Any]) -> Bool {
|
|
254
|
+
return (userInfo["source"] as? String) == "capacitor-background-runner"
|
|
255
|
+
}
|
|
248
256
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
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
|
-
|
|
255
|
-
|
|
256
|
-
|
|
263
|
+
let eventData: [String: Any] = [
|
|
264
|
+
"actionTypeId": actionTypeId,
|
|
265
|
+
"notificationId": notificationId,
|
|
266
|
+
]
|
|
257
267
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
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
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
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": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "Capacitor Background Runner",
|
|
5
5
|
"main": "dist/plugin.cjs.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -51,11 +51,11 @@
|
|
|
51
51
|
"postinstall": "node ./scripts/install_libs.js"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
|
-
"@capacitor/android": "^
|
|
55
|
-
"@capacitor/cli": "^
|
|
56
|
-
"@capacitor/core": "^
|
|
57
|
-
"@capacitor/docgen": "0.3.0",
|
|
58
|
-
"@capacitor/ios": "^
|
|
54
|
+
"@capacitor/android": "^8.0.0",
|
|
55
|
+
"@capacitor/cli": "^8.0.0",
|
|
56
|
+
"@capacitor/core": "^8.0.0",
|
|
57
|
+
"@capacitor/docgen": "^0.3.0",
|
|
58
|
+
"@capacitor/ios": "^8.0.0",
|
|
59
59
|
"@ionic/eslint-config": "^0.4.0",
|
|
60
60
|
"@ionic/prettier-config": "^4.0.0",
|
|
61
61
|
"@ionic/swiftlint-config": "^2.0.0",
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
"typescript": "^5.9.3"
|
|
69
69
|
},
|
|
70
70
|
"peerDependencies": {
|
|
71
|
-
"@capacitor/core": ">=
|
|
71
|
+
"@capacitor/core": ">=8.0.0"
|
|
72
72
|
},
|
|
73
73
|
"prettier": "@ionic/prettier-config",
|
|
74
74
|
"swiftlint": "@ionic/swiftlint-config",
|
|
@@ -83,5 +83,5 @@
|
|
|
83
83
|
"src": "android"
|
|
84
84
|
}
|
|
85
85
|
},
|
|
86
|
-
"gitHead": "
|
|
86
|
+
"gitHead": "4559cf862ec7575f579a3bc38257efebe552daaf"
|
|
87
87
|
}
|