@capacitor/background-runner 3.1.0-dev.20260914T170000 → 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.
- package/android/src/main/java/io/ionic/backgroundrunner/plugin/api/Device.kt +16 -38
- package/android/src/main/java/io/ionic/backgroundrunner/plugin/api/Notifications.kt +28 -32
- package/android/src/main/libs/android-js-engine-release.aar +0 -0
- package/ios/Sources/CapacitorBackgroundRunner/CapacitorAPI/Notifications.swift +2 -10
- package/ios/Sources/CapacitorBackgroundRunner/CapacitorBackgroundRunner.swift +248 -250
- package/package.json +1 -1
|
@@ -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:
|
|
15
|
-
private val 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
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
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
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
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
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
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? {
|
|
Binary file
|
|
@@ -189,11 +189,7 @@ class CapacitorNotifications: NSObject, CapacitorNotificationsExports {
|
|
|
189
189
|
let badgeOptions = SetBadgeOption(from: jsonDict)
|
|
190
190
|
|
|
191
191
|
DispatchQueue.main.async {
|
|
192
|
-
|
|
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
|
-
|
|
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
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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
|
-
|
|
64
|
-
} catch {
|
|
65
|
-
call.reject("\(error)")
|
|
66
|
-
}
|
|
31
|
+
initWatchConnectivity()
|
|
67
32
|
}
|
|
68
|
-
}
|
|
69
33
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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
|
-
|
|
38
|
+
// check notification permissions
|
|
39
|
+
let notificationState = CapacitorNotifications.checkPermission()
|
|
77
40
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
41
|
+
call.resolve([
|
|
42
|
+
"geolocation": geolocationState,
|
|
43
|
+
"notifications": notificationState
|
|
44
|
+
])
|
|
45
|
+
}
|
|
81
46
|
|
|
82
|
-
|
|
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
|
-
|
|
85
|
-
DispatchQueue.global(qos: .userInitiated).async { [unowned self] in
|
|
70
|
+
@objc func dispatchEvent(_ call: CAPPluginCall) {
|
|
86
71
|
do {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
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
|
-
|
|
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
|
-
|
|
126
|
-
|
|
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
|
-
|
|
144
|
-
|
|
145
|
-
|
|
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
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
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
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
174
|
-
|
|
175
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
186
|
-
|
|
187
|
-
|
|
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
|
-
|
|
191
|
-
|
|
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
|
-
|
|
199
|
-
|
|
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
|
-
|
|
202
|
-
|
|
194
|
+
if !config.enableWatchConnectivity {
|
|
195
|
+
return
|
|
196
|
+
}
|
|
203
197
|
|
|
204
|
-
|
|
205
|
-
|
|
198
|
+
WCSession.default.delegate = self
|
|
199
|
+
WCSession.default.activate()
|
|
206
200
|
|
|
207
|
-
|
|
208
|
-
if notificationCenter.delegate !== self {
|
|
209
|
-
originalDelegate = notificationCenter.delegate
|
|
201
|
+
print("Watch Connectivity Enabled")
|
|
210
202
|
}
|
|
211
203
|
|
|
212
|
-
|
|
213
|
-
|
|
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
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
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
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
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
|
-
|
|
251
|
+
// MARK: - Helper Methods
|
|
252
252
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
253
|
+
private func isBackgroundRunnerNotification(_ userInfo: [AnyHashable: Any]) -> Bool {
|
|
254
|
+
return (userInfo["source"] as? String) == "capacitor-background-runner"
|
|
255
|
+
}
|
|
256
256
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
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
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
263
|
+
let eventData: [String: Any] = [
|
|
264
|
+
"actionTypeId": actionTypeId,
|
|
265
|
+
"notificationId": notificationId
|
|
266
|
+
]
|
|
267
267
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
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
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
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