@capacitor/background-runner 1.0.6-dev-20240409T144959.0 → 1.0.6-dev-20240416T204052.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.
@@ -5,8 +5,8 @@ import JavaScriptCore
5
5
 
6
6
  public class BackgroundRunner {
7
7
  public static let shared = BackgroundRunner()
8
-
9
- private var config: RunnerConfig?
8
+ public var config: RunnerConfig?
9
+
10
10
  private var runner = Runner()
11
11
 
12
12
  public init() {
@@ -17,93 +17,51 @@ public class BackgroundRunner {
17
17
  print("could not initialize BackgroundRunner: \(error)")
18
18
  }
19
19
  }
20
-
21
- public func registerBackgroundTask() {
20
+
21
+ public func scheduleBackgroundTasks() throws {
22
22
  guard let config = config else {
23
- print("no runner to register")
24
- return
23
+ throw BackgroundRunnerPluginError.noRunnerConfig
25
24
  }
26
-
27
- if config.event == nil {
28
- print("cannot register background task without a event to call")
29
- return
30
- }
31
-
32
- BGTaskScheduler.shared.register(forTaskWithIdentifier: config.label, using: nil) { task in
33
- do {
34
- task.expirationHandler = {
35
- print("task timed out")
36
- }
37
-
38
- guard let event = config.event else {
39
- throw BackgroundRunnerPluginError.invalidRunnerConfig(reason: "runner event is missing or invalid")
40
- }
41
-
42
- _ = try BackgroundRunner.shared.execute(config: config, event: event)
43
-
44
- task.setTaskCompleted(success: true)
45
- } catch {
46
- print("background task error: \(error)")
47
- task.setTaskCompleted(success: false)
48
- }
49
- }
50
- }
51
-
52
- public func scheduleBackgroundTasks() {
53
- guard let config = config else {
25
+
26
+ if !config.autoSchedule {
54
27
  return
55
28
  }
56
29
 
57
30
  guard let interval = config.interval else {
58
- print("cannot register background task without a configured interval")
59
- return
31
+ throw BackgroundRunnerPluginError.invalidRunnerConfig(reason: "cannot register background task without a configured interval")
60
32
  }
61
33
 
62
34
  let request = BGAppRefreshTaskRequest(identifier: config.label)
63
35
  request.earliestBeginDate = Date(timeIntervalSinceNow: Double(interval) * 60)
64
36
 
65
- do {
66
- print("Scheduling \(config.label)")
37
+ print("Scheduling \(config.label)")
67
38
 
68
- try BGTaskScheduler.shared.submit(request)
69
- } catch {
70
- print("Could not schedule app refresh: \(error)")
71
- }
72
- }
73
-
74
- public func getConfig() -> RunnerConfig? {
75
- return config
39
+ try BGTaskScheduler.shared.submit(request)
76
40
  }
77
41
 
78
- public func dispatchEvent(event: String, inputArgs: [String: Any]?, callbackId: String? = nil) throws {
79
- if let config = config {
80
- let waitGroup = DispatchGroup()
81
- waitGroup.enter()
82
-
83
- var err: Error?
42
+ public func registerBackgroundTask() throws {
43
+ guard let config = config else {
44
+ throw BackgroundRunnerPluginError.noRunnerConfig
45
+ }
84
46
 
85
- // swiftlint:disable:next unowned_variable_capture
86
- DispatchQueue.global(qos: .userInitiated).async { [unowned self] in
87
- do {
88
- _ = try self.execute(config: config, event: event, inputArgs: inputArgs, callbackId: callbackId)
89
- } catch {
90
- err = error
91
- print("[\(config.label)]: \(error)")
47
+ BGTaskScheduler.shared.register(forTaskWithIdentifier: config.label, using: nil) { task in
48
+ do {
49
+ task.expirationHandler = {
50
+ print("task timed out")
92
51
  }
93
52
 
94
- waitGroup.leave()
95
- }
53
+ _ = try BackgroundRunner.shared.execute(config: config)
96
54
 
97
- waitGroup.wait()
98
-
99
- if let err = err {
100
- throw err
55
+ task.setTaskCompleted(success: true)
56
+ } catch {
57
+ print("background task error: \(error)")
58
+ task.setTaskCompleted(success: false)
101
59
  }
102
60
  }
103
61
  }
104
-
62
+
105
63
  // swiftlint:disable:next cyclomatic_complexity function_body_length
106
- public func execute(config: RunnerConfig, event: String, inputArgs: [String: Any]? = nil, callbackId: String? = nil) throws -> [String: Any]? {
64
+ public func execute(config: RunnerConfig, inputArgs: [String: Any]? = nil, callbackId: String? = nil) throws -> [String: Any]? {
107
65
  do {
108
66
  let context = try initContext(config: config, callbackId: callbackId)
109
67
 
@@ -170,9 +128,10 @@ public class BackgroundRunner {
170
128
 
171
129
  waitGroup.enter()
172
130
 
173
- try context.dispatchEvent(event: event, details: args)
131
+ try context.dispatchEvent(event: config.event, details: args)
174
132
 
175
133
  waitGroup.wait()
134
+
176
135
 
177
136
  if let rejection = rejectionErr {
178
137
  throw EngineError.jsException(details: rejection.message)
@@ -185,6 +144,33 @@ public class BackgroundRunner {
185
144
  }
186
145
  }
187
146
 
147
+ public func dispatchEvent(event: String, inputArgs: [String: Any]?, callbackId: String? = nil) throws {
148
+ if let config = config {
149
+ let waitGroup = DispatchGroup()
150
+ waitGroup.enter()
151
+
152
+ var err: Error?
153
+
154
+ // swiftlint:disable:next unowned_variable_capture
155
+ DispatchQueue.global(qos: .userInitiated).async { [unowned self] in
156
+ do {
157
+ _ = try self.execute(config: config, inputArgs: inputArgs, callbackId: callbackId)
158
+ } catch {
159
+ err = error
160
+ print("[\(config.label)]: \(error)")
161
+ }
162
+
163
+ waitGroup.leave()
164
+ }
165
+
166
+ waitGroup.wait()
167
+
168
+ if let err = err {
169
+ throw err
170
+ }
171
+ }
172
+ }
173
+
188
174
  private func loadRunnerConfig() throws -> RunnerConfig? {
189
175
  guard let capacitorConfigFileURL = Bundle.main.url(forResource: "capacitor.config.json", withExtension: nil) else {
190
176
  throw BackgroundRunnerPluginError.runnerError(reason: "capacitor.config.json file not found")
@@ -1,6 +1,7 @@
1
1
  import Foundation
2
2
 
3
3
  public enum BackgroundRunnerPluginError: Error, Equatable {
4
+ case noRunnerConfig
4
5
  case invalidRunnerConfig(reason: String)
5
6
  case invalidArgument(reason: String)
6
7
  case runnerError(reason: String)
@@ -13,6 +13,7 @@ public class BackgroundRunnerPlugin: CAPPlugin {
13
13
  name: UIApplication.didEnterBackgroundNotification,
14
14
  object: nil
15
15
  )
16
+
16
17
  initWatchConnectivity()
17
18
  }
18
19
 
@@ -54,22 +55,23 @@ public class BackgroundRunnerPlugin: CAPPlugin {
54
55
 
55
56
  @objc func dispatchEvent(_ call: CAPPluginCall) {
56
57
  do {
57
- guard let runnerEvent = call.getString("event") else {
58
+ guard let runnerEvent = call.getString("event"), !runnerEvent.isEmpty else {
58
59
  throw BackgroundRunnerPluginError.invalidArgument(reason: "event is missing or invalid")
59
60
  }
60
61
 
61
62
  let details = call.getObject("details", JSObject())
62
63
 
63
- guard let config = impl.getConfig() else {
64
- throw BackgroundRunnerPluginError.runnerError(reason: "no runner config loaded")
64
+ guard var config = impl.config else {
65
+ throw BackgroundRunnerPluginError.noRunnerConfig
65
66
  }
67
+
68
+ config.event = runnerEvent
66
69
 
67
70
  // swiftlint:disable:next unowned_variable_capture
68
71
  DispatchQueue.global(qos: .userInitiated).async { [unowned self] in
69
72
  do {
70
73
  let result = try self.impl.execute(
71
74
  config: config,
72
- event: runnerEvent,
73
75
  inputArgs: details as [String: Any],
74
76
  callbackId: call.callbackId
75
77
  )
@@ -94,14 +96,27 @@ public class BackgroundRunnerPlugin: CAPPlugin {
94
96
  }
95
97
 
96
98
  @objc private func didEnterBackground() {
97
- impl.scheduleBackgroundTasks()
99
+ do {
100
+ try impl.scheduleBackgroundTasks()
101
+ } catch {
102
+ print("could not schedule background task: \(error)")
103
+ }
98
104
  }
99
105
 
100
106
  public static func registerBackgroundTask() {
101
- BackgroundRunner.shared.registerBackgroundTask()
107
+ do {
108
+ try BackgroundRunner.shared.registerBackgroundTask()
109
+ } catch {
110
+ print("could not register background task: \(error)")
111
+ }
102
112
  }
103
113
 
104
114
  public static func dispatchEvent(event: String, eventArgs: [AnyHashable: Any], completionHandler: ((Result<Bool, Error>) -> Void)) {
115
+ if event.isEmpty {
116
+ completionHandler(.failure(BackgroundRunnerPluginError.invalidArgument(reason: "event is missing or invalid")))
117
+ return
118
+ }
119
+
105
120
  var args: [String: Any] = [:]
106
121
 
107
122
  eventArgs.forEach { (key: AnyHashable, value: Any) in
@@ -147,7 +162,7 @@ public class BackgroundRunnerPlugin: CAPPlugin {
147
162
  return
148
163
  }
149
164
 
150
- guard let config = impl.getConfig() else {
165
+ guard let config = impl.config else {
151
166
  return
152
167
  }
153
168
 
@@ -13,9 +13,11 @@ class CapacitorKVStore: NSObject, CapacitorKVStoreExports {
13
13
  }
14
14
 
15
15
  static func get(_ key: String) -> JSValue {
16
+ guard let value = UserDefaults.standard.string(forKey: key) else {
17
+ return JSValue(nullIn: JSContext.current())
18
+ }
19
+
16
20
  var valueWrapper: [String: String] = [:]
17
-
18
- let value = UserDefaults.standard.string(forKey: key)
19
21
  valueWrapper["value"] = value
20
22
 
21
23
  return JSValue(object: valueWrapper, in: JSContext.current())
@@ -5,7 +5,7 @@ public struct RunnerConfig {
5
5
  let label: String
6
6
  let src: String
7
7
  var autoSchedule: Bool
8
- let event: String?
8
+ var event: String
9
9
  let repeats: Bool?
10
10
  let enableWatchConnectivity: Bool
11
11
 
@@ -20,7 +20,7 @@ public struct RunnerConfig {
20
20
  throw BackgroundRunnerPluginError.invalidRunnerConfig(reason: "runner source file path is missing or invalid")
21
21
  }
22
22
 
23
- let event = jsObject["event"] as? String
23
+ let event = jsObject["event"] as? String ?? ""
24
24
  let repeats = jsObject["repeat"] as? Bool
25
25
  let interval = jsObject["interval"] as? Int
26
26
  let autoStart = jsObject["autoStart"] as? Bool
@@ -3,31 +3,17 @@ import JavaScriptCore
3
3
 
4
4
  public class Runner {
5
5
  var machine: JSVirtualMachine
6
- var contexts: [String: Context]
7
6
 
8
7
  private let runLoop: RunLoop
9
8
  private var thread: Thread?
10
9
 
11
10
  public init() {
12
11
  machine = JSVirtualMachine()
13
- contexts = [:]
14
12
  runLoop = RunLoop.current
15
13
  }
16
14
 
17
15
  func createContext(name: String) throws -> Context {
18
- let context = try Context(vm: machine, contextName: name, runLoop: runLoop)
19
-
20
- if contexts.keys.contains(name) {
21
- throw EngineError.runnerError(details: "context with name \(name) already exists")
22
- }
23
-
24
- contexts[name] = context
25
-
26
- return context
27
- }
28
-
29
- func destroyContext(name: String) {
30
- contexts.removeValue(forKey: name)
16
+ return try Context(vm: machine, contextName: name, runLoop: runLoop)
31
17
  }
32
18
 
33
19
  func start() {
@@ -54,6 +40,7 @@ public class Runner {
54
40
  }
55
41
 
56
42
  thread.cancel()
43
+
57
44
  while !thread.isFinished {
58
45
  Thread.sleep(forTimeInterval: 0.05)
59
46
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capacitor/background-runner",
3
- "version": "1.0.6-dev-20240409T144959.0",
3
+ "version": "1.0.6-dev-20240416T204052.0",
4
4
  "description": "Capacitor Background Runner",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",
@@ -81,5 +81,5 @@
81
81
  "src": "android"
82
82
  }
83
83
  },
84
- "gitHead": "18f72b6c17bb83bb0e9dde3b0b4c1d3db5309b0d"
84
+ "gitHead": "142e96d6415e4d5f8bcf8b217993cd99e2764659"
85
85
  }