@@ -14,7 +14,9 @@ public class SwiftWorkmanagerPlugin: FlutterPluginAppLifeCycleDelegate {
1414 static let identifier = " be.tramckrijte.workmanager "
1515
1616 static let defaultBGProcessingTaskIdentifier = " workmanager.background.task "
17-
17+ static let defaultBGAppRefreshTaskIdentifier = " workmanager.background.refresh.task "
18+ var bgRefreshTaskFrequency = 0.0
19+
1820 private static var flutterPluginRegistrantCallback : FlutterPluginRegistrantCallback ?
1921
2022 private struct ForegroundMethodChannel {
@@ -36,6 +38,15 @@ public class SwiftWorkmanagerPlugin: FlutterPluginAppLifeCycleDelegate {
3638 case requiresCharging
3739 }
3840 }
41+
42+ struct RegisterAppRefreshTask {
43+ static let name = " \( RegisterAppRefreshTask . self) " . lowercasingFirst
44+ enum Arguments : String {
45+ case initialDelaySeconds
46+ case refreshFrequencySeconds
47+ }
48+ }
49+
3950 struct CancelAllTasks {
4051 static let name = " \( CancelAllTasks . self) " . lowercasingFirst
4152 enum Arguments : String {
@@ -77,6 +88,51 @@ public class SwiftWorkmanagerPlugin: FlutterPluginAppLifeCycleDelegate {
7788 operationQueue. addOperation ( operation)
7889 }
7990
91+ @available ( iOS 13 . 0 , * )
92+ private func scheduleAppRefresh( ) {
93+ let request = BGAppRefreshTaskRequest ( identifier: SwiftWorkmanagerPlugin . defaultBGAppRefreshTaskIdentifier)
94+
95+ request. earliestBeginDate = Date ( timeIntervalSinceNow: bgRefreshTaskFrequency * 60 )
96+
97+ do {
98+ try BGTaskScheduler . shared. submit ( request)
99+ } catch {
100+ print ( " Could not schedule app refresh: \( error) " )
101+ }
102+ }
103+
104+ @available ( iOS 13 . 0 , * )
105+ private func handleAppRefresh( task: BGAppRefreshTask ) {
106+ print ( " handleAppRefresh() " , task. identifier)
107+
108+ if ( bgRefreshTaskFrequency > 0 ) {
109+ // Schedule a new refresh task.
110+ scheduleAppRefresh ( )
111+ }
112+
113+ let operationQueue = OperationQueue ( )
114+
115+ // Create an operation that performs the main part of the background task.
116+ let operation = BackgroundTaskOperation (
117+ task. identifier,
118+ flutterPluginRegistrantCallback: SwiftWorkmanagerPlugin . flutterPluginRegistrantCallback
119+ )
120+
121+ // Provide the background task with an expiration handler that cancels the operation.
122+ task. expirationHandler = {
123+ operation. cancel ( )
124+ }
125+
126+ // Inform the system that the background task is complete
127+ // when the operation completes.
128+ operation. completionBlock = {
129+ task. setTaskCompleted ( success: !operation. isCancelled)
130+ }
131+
132+ // Start the operation.
133+ operationQueue. addOperation ( operation)
134+ }
135+
80136 public override func application( _ application: UIApplication ,
81137 didFinishLaunchingWithOptions launchOptions: [ AnyHashable : Any ] = [ : ] ) -> Bool {
82138 if #available( iOS 13 . 0 , * ) {
@@ -88,6 +144,10 @@ public class SwiftWorkmanagerPlugin: FlutterPluginAppLifeCycleDelegate {
88144 self . handleBGProcessingTask ( task)
89145 }
90146 }
147+
148+ BGTaskScheduler . shared. register ( forTaskWithIdentifier: SwiftWorkmanagerPlugin . defaultBGAppRefreshTaskIdentifier, using: nil ) { task in
149+ self . handleAppRefresh ( task: task as! BGAppRefreshTask )
150+ }
91151 }
92152
93153 return true
@@ -128,24 +188,49 @@ extension SwiftWorkmanagerPlugin: FlutterPlugin {
128188 UserDefaultsHelper . storeIsDebug ( isInDebug)
129189 result ( true )
130190
131- case ( ForegroundMethodChannel . Methods. RegisterOneOffTask. name, let . some( arguments) ) :
132- if !validateCallbackHandle( ) {
133- result (
134- FlutterError (
135- code: " 1 " ,
136- message: " You have not properly initialized the Flutter WorkManager Package. " +
137- " You should ensure you have called the 'initialize' function first! " +
138- " Example: \n " +
139- " \n " +
140- " `Workmanager().initialize( \n " +
141- " callbackDispatcher, \n " +
142- " )` " +
143- " \n " +
144- " \n " +
145- " The `callbackDispatcher` is a top level function. See example in repository. " ,
146- details: nil
147- )
191+ case ( ForegroundMethodChannel . Methods. RegisterAppRefreshTask. name, let . some( arguments) ) :
192+ print ( " ForegroundMethodChannel.Methods.RegisterAppRefreshTask " )
193+ if !validateCallbackHandle( result: result) {
194+ return
195+ }
196+
197+ if #available( iOS 13 . 0 , * ) {
198+ let method = ForegroundMethodChannel . Methods. RegisterAppRefreshTask. self
199+ guard let initialDelaySeconds =
200+ arguments [ method. Arguments. initialDelaySeconds. rawValue] as? Int64 else {
201+ result ( WMPError . invalidParameters. asFlutterError)
202+ return
203+ }
204+
205+ guard let regreshFrequencySeconds =
206+ arguments [ method. Arguments. refreshFrequencySeconds. rawValue] as? Int64 else {
207+ result ( WMPError . invalidParameters. asFlutterError)
208+ return
209+ }
210+
211+ // save this, can't store in task
212+ bgRefreshTaskFrequency = Double ( regreshFrequencySeconds)
213+
214+ let request = BGAppRefreshTaskRequest (
215+ identifier: SwiftWorkmanagerPlugin . defaultBGAppRefreshTaskIdentifier
148216 )
217+
218+ request. earliestBeginDate = Date ( timeIntervalSinceNow: Double ( initialDelaySeconds) )
219+
220+ do {
221+ try BGTaskScheduler . shared. submit ( request)
222+ result ( true )
223+ } catch {
224+ result ( WMPError . bgTaskSchedulingFailed ( error) . asFlutterError)
225+ }
226+
227+ return
228+ } else {
229+ result ( WMPError . unhandledMethod ( call. method) . asFlutterError)
230+ }
231+
232+ case ( ForegroundMethodChannel . Methods. RegisterOneOffTask. name, let . some( arguments) ) :
233+ if !validateCallbackHandle( result: result) {
149234 return
150235 }
151236
@@ -207,8 +292,27 @@ extension SwiftWorkmanagerPlugin: FlutterPlugin {
207292 }
208293 }
209294
210- private func validateCallbackHandle( ) -> Bool {
211- return UserDefaultsHelper . getStoredCallbackHandle ( ) != nil
295+ private func validateCallbackHandle( result: @escaping FlutterResult ) -> Bool {
296+ let valid = UserDefaultsHelper . getStoredCallbackHandle ( ) != nil
297+ if ( !valid) {
298+ result (
299+ FlutterError (
300+ code: " 1 " ,
301+ message: " You have not properly initialized the Flutter WorkManager Package. " +
302+ " You should ensure you have called the 'initialize' function first! " +
303+ " Example: \n " +
304+ " \n " +
305+ " `Workmanager().initialize( \n " +
306+ " callbackDispatcher, \n " +
307+ " )` " +
308+ " \n " +
309+ " \n " +
310+ " The `callbackDispatcher` is a top level function. See example in repository. " ,
311+ details: nil
312+ )
313+ )
314+ }
315+ return valid
212316 }
213317}
214318
0 commit comments