From 85954412f164cd681a945a20faee2b99a9e7cd1e Mon Sep 17 00:00:00 2001 From: Charlie Scheer Date: Sun, 30 May 2021 09:45:42 +1200 Subject: [PATCH 01/11] Add background refresh using BackgroundTask api --- Simplenote/SPAppDelegate+Extensions.swift | 48 +++++++++++++++++++++++ Simplenote/SPAppDelegate.m | 8 ++++ Simplenote/Simplenote-Info.plist | 8 ++++ 3 files changed, 64 insertions(+) diff --git a/Simplenote/SPAppDelegate+Extensions.swift b/Simplenote/SPAppDelegate+Extensions.swift index 2a7c4384d..9794e7a20 100644 --- a/Simplenote/SPAppDelegate+Extensions.swift +++ b/Simplenote/SPAppDelegate+Extensions.swift @@ -1,4 +1,5 @@ import Foundation +import BackgroundTasks // MARK: - Initialization @@ -405,3 +406,50 @@ extension SPAppDelegate { EditorFactory.shared.scrollPositionCache.cleanup(keeping: allIdentifiers) } } + +// MARK: - Background Fetch +// +@available(iOS 13.0, *) +extension SPAppDelegate { + @objc + func registerBackgroundRefreshTask() { + BGTaskScheduler.shared.register(forTaskWithIdentifier: BackgroundRefreshConstants.identifier, using: .main) { task in + guard let task = task as? BGAppRefreshTask else { + return + } + self.handleAppRefresh(task: task) + } + } + + private func handleAppRefresh(task: BGAppRefreshTask) { + scheduleAppRefresh() + print("Ran handle app refersh") + simperium.backgroundFetch { result in + if result == .failed { + NSLog("<< Background Fetch: New Data Received") + task.setTaskCompleted(success: false) + return + } else if result == .noData { + NSLog("<< Background Fetch: No Data Received") + } + task.setTaskCompleted(success: true) + } + } + + + @objc + func scheduleAppRefresh() { + let request = BGAppRefreshTaskRequest(identifier: BackgroundRefreshConstants.identifier) + request.earliestBeginDate = Date(timeIntervalSinceNow: BackgroundRefreshConstants.earliestBeginDate) //15 minutes + do { + try BGTaskScheduler.shared.submit(request) + } catch { + print("Couldn't schedule app refersh: \(error)") + } + } +} + +private struct BackgroundRefreshConstants { + static let identifier = "com.codality.NotationalFlow.backgroundRefresh" + static let earliestBeginDate = 900.0 +} diff --git a/Simplenote/SPAppDelegate.m b/Simplenote/SPAppDelegate.m index bf5577ea6..059f9c450 100644 --- a/Simplenote/SPAppDelegate.m +++ b/Simplenote/SPAppDelegate.m @@ -166,6 +166,11 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( [self showPasscodeLockIfNecessary]; } + // Register background refresh task to system + if (@available(iOS 13.0, *)) { + [self registerBackgroundRefreshTask]; + } + // Index (All of the) Spotlight Items if the user upgraded [self indexSpotlightItemsIfNeeded]; @@ -190,6 +195,9 @@ - (void)applicationDidEnterBackground:(UIApplication *)application [self showPasscodeLockIfNecessary]; [self cleanupScrollPositionCache]; + + //Schedule background refresh + [self scheduleAppRefresh]; } - (void)applicationWillEnterForeground:(UIApplication *)application diff --git a/Simplenote/Simplenote-Info.plist b/Simplenote/Simplenote-Info.plist index abc348b2b..b02af7ac0 100644 --- a/Simplenote/Simplenote-Info.plist +++ b/Simplenote/Simplenote-Info.plist @@ -78,8 +78,16 @@ com.codality.NotationalFlow.newNote com.codality.NotationalFlow.openNote + UIBackgroundModes + + fetch + UILaunchStoryboardName LaunchScreen + BGTaskSchedulerPermittedIdentifiers + + com.codality.NotationalFlow.backgroundRefresh + UIPrerenderedIcon UIRequiredDeviceCapabilities From eeb1d8ebdaff09f55a2b7f41fd6c1f7898f89a0d Mon Sep 17 00:00:00 2001 From: Charlie Scheer Date: Sun, 30 May 2021 12:35:49 +1200 Subject: [PATCH 02/11] Updated earliest background refresh to 30 minutes --- Simplenote/SPAppDelegate+Extensions.swift | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Simplenote/SPAppDelegate+Extensions.swift b/Simplenote/SPAppDelegate+Extensions.swift index 9794e7a20..a2ae0486c 100644 --- a/Simplenote/SPAppDelegate+Extensions.swift +++ b/Simplenote/SPAppDelegate+Extensions.swift @@ -436,11 +436,10 @@ extension SPAppDelegate { } } - @objc func scheduleAppRefresh() { let request = BGAppRefreshTaskRequest(identifier: BackgroundRefreshConstants.identifier) - request.earliestBeginDate = Date(timeIntervalSinceNow: BackgroundRefreshConstants.earliestBeginDate) //15 minutes + request.earliestBeginDate = Date(timeIntervalSinceNow: BackgroundRefreshConstants.earliestBeginDate) do { try BGTaskScheduler.shared.submit(request) } catch { @@ -451,5 +450,5 @@ extension SPAppDelegate { private struct BackgroundRefreshConstants { static let identifier = "com.codality.NotationalFlow.backgroundRefresh" - static let earliestBeginDate = 900.0 + static let earliestBeginDate = 1800.0 //30 minutes } From 3ed393f605393a6721b559746254383ab19a7d67 Mon Sep 17 00:00:00 2001 From: Charlie Scheer Date: Wed, 2 Jun 2021 10:29:06 +1200 Subject: [PATCH 03/11] Updated refresh to simply wakeup SN and let simperium sync --- Simplenote/SPAppDelegate+Extensions.swift | 38 +++++++++++++++-------- Simplenote/SPAppDelegate.m | 6 ++-- Simplenote/Simplenote-Info.plist | 8 ++--- 3 files changed, 33 insertions(+), 19 deletions(-) diff --git a/Simplenote/SPAppDelegate+Extensions.swift b/Simplenote/SPAppDelegate+Extensions.swift index a2ae0486c..b2c099415 100644 --- a/Simplenote/SPAppDelegate+Extensions.swift +++ b/Simplenote/SPAppDelegate+Extensions.swift @@ -413,7 +413,12 @@ extension SPAppDelegate { extension SPAppDelegate { @objc func registerBackgroundRefreshTask() { - BGTaskScheduler.shared.register(forTaskWithIdentifier: BackgroundRefreshConstants.identifier, using: .main) { task in + guard BuildConfiguration.current == .debug else { + return + } + + NSLog("Registered background task with identifier \(BackgroundRefreshConstants.bgTaskIdentifier)") + BGTaskScheduler.shared.register(forTaskWithIdentifier: BackgroundRefreshConstants.bgTaskIdentifier, using: .main) { task in guard let task = task as? BGAppRefreshTask else { return } @@ -422,23 +427,28 @@ extension SPAppDelegate { } private func handleAppRefresh(task: BGAppRefreshTask) { + NSLog("Did fire handle app refresh") + guard BuildConfiguration.current == .debug else { + return + } + + NSLog("Background refresh intiated") scheduleAppRefresh() - print("Ran handle app refersh") - simperium.backgroundFetch { result in - if result == .failed { - NSLog("<< Background Fetch: New Data Received") - task.setTaskCompleted(success: false) - return - } else if result == .noData { - NSLog("<< Background Fetch: No Data Received") - } + + DispatchQueue.main.asyncAfter(deadline: .now() + BackgroundRefreshConstants.timeOut) { + NSLog("Background refresh finishing") task.setTaskCompleted(success: true) } } @objc func scheduleAppRefresh() { - let request = BGAppRefreshTaskRequest(identifier: BackgroundRefreshConstants.identifier) + guard BuildConfiguration.current == .debug else { + return + } + + NSLog("Background refresh scheduled") + let request = BGAppRefreshTaskRequest(identifier: BackgroundRefreshConstants.bgTaskIdentifier) request.earliestBeginDate = Date(timeIntervalSinceNow: BackgroundRefreshConstants.earliestBeginDate) do { try BGTaskScheduler.shared.submit(request) @@ -449,6 +459,8 @@ extension SPAppDelegate { } private struct BackgroundRefreshConstants { - static let identifier = "com.codality.NotationalFlow.backgroundRefresh" - static let earliestBeginDate = 1800.0 //30 minutes + static let earliestBeginDate = TimeInterval(60) //30 minutes + static let timeOut = TimeInterval(25) + static let bundleIdentifier = Bundle.main.bundleIdentifier ?? "com.codality.NotationalFlow" + static let bgTaskIdentifier = bundleIdentifier + ".refresh" } diff --git a/Simplenote/SPAppDelegate.m b/Simplenote/SPAppDelegate.m index 059f9c450..28d665bd0 100644 --- a/Simplenote/SPAppDelegate.m +++ b/Simplenote/SPAppDelegate.m @@ -196,8 +196,10 @@ - (void)applicationDidEnterBackground:(UIApplication *)application [self showPasscodeLockIfNecessary]; [self cleanupScrollPositionCache]; - //Schedule background refresh - [self scheduleAppRefresh]; + // Schedule background refresh + if (@available(iOS 13.0, *)) { + [self scheduleAppRefresh]; + } } - (void)applicationWillEnterForeground:(UIApplication *)application diff --git a/Simplenote/Simplenote-Info.plist b/Simplenote/Simplenote-Info.plist index b02af7ac0..f30c3c211 100644 --- a/Simplenote/Simplenote-Info.plist +++ b/Simplenote/Simplenote-Info.plist @@ -84,16 +84,16 @@ UILaunchStoryboardName LaunchScreen - BGTaskSchedulerPermittedIdentifiers - - com.codality.NotationalFlow.backgroundRefresh - UIPrerenderedIcon UIRequiredDeviceCapabilities armv7 + BGTaskSchedulerPermittedIdentifiers + + $(PRODUCT_BUNDLE_IDENTIFIER).refresh + UISupportedInterfaceOrientations UIInterfaceOrientationPortrait From 6d08985e79adfac60dd59581e7687844adb81a88 Mon Sep 17 00:00:00 2001 From: Charlie Scheer Date: Wed, 2 Jun 2021 10:31:48 +1200 Subject: [PATCH 04/11] Updated background refresh time --- Simplenote/SPAppDelegate+Extensions.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Simplenote/SPAppDelegate+Extensions.swift b/Simplenote/SPAppDelegate+Extensions.swift index b2c099415..9bf0999ee 100644 --- a/Simplenote/SPAppDelegate+Extensions.swift +++ b/Simplenote/SPAppDelegate+Extensions.swift @@ -459,7 +459,7 @@ extension SPAppDelegate { } private struct BackgroundRefreshConstants { - static let earliestBeginDate = TimeInterval(60) //30 minutes + static let earliestBeginDate = TimeInterval(1800.0) //30 minutes static let timeOut = TimeInterval(25) static let bundleIdentifier = Bundle.main.bundleIdentifier ?? "com.codality.NotationalFlow" static let bgTaskIdentifier = bundleIdentifier + ".refresh" From f8409c0e6118d671deb186901147c851c7012a1e Mon Sep 17 00:00:00 2001 From: Charlie Scheer Date: Thu, 3 Jun 2021 08:59:27 +1200 Subject: [PATCH 05/11] Moved BG Fetch to its own file --- Simplenote.xcodeproj/project.pbxproj | 4 ++ Simplenote/SPAppDelegate+Extensions.swift | 58 -------------------- Simplenote/SPAppDelegate.m | 5 +- Simplenote/SPBackgroundRefresh.swift | 66 +++++++++++++++++++++++ 4 files changed, 73 insertions(+), 60 deletions(-) create mode 100644 Simplenote/SPBackgroundRefresh.swift diff --git a/Simplenote.xcodeproj/project.pbxproj b/Simplenote.xcodeproj/project.pbxproj index 08b8cd611..2cc4d8ce7 100644 --- a/Simplenote.xcodeproj/project.pbxproj +++ b/Simplenote.xcodeproj/project.pbxproj @@ -416,6 +416,7 @@ BA4499B325ED8AB0000C563E /* NoticeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA4499B225ED8AB0000C563E /* NoticeView.swift */; }; BA4499BC25ED95D0000C563E /* Notice.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA4499BB25ED95D0000C563E /* Notice.swift */; }; BA4499C525ED95E5000C563E /* NoticeAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA4499C425ED95E5000C563E /* NoticeAction.swift */; }; + BA471060266821C0001A91A5 /* SPBackgroundRefresh.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA47105F266821C0001A91A5 /* SPBackgroundRefresh.swift */; }; BA4C6CFC264C744300B723A7 /* SeparatorsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA4C6CFB264C744300B723A7 /* SeparatorsView.swift */; }; BA55124E2600210B00D8F882 /* TimerFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA55124D2600210B00D8F882 /* TimerFactory.swift */; }; BA55B05A25F067DF0042582B /* NoticePresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA55B05925F067DF0042582B /* NoticePresenter.swift */; }; @@ -954,6 +955,7 @@ BA4499B225ED8AB0000C563E /* NoticeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoticeView.swift; sourceTree = ""; }; BA4499BB25ED95D0000C563E /* Notice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Notice.swift; sourceTree = ""; }; BA4499C425ED95E5000C563E /* NoticeAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoticeAction.swift; sourceTree = ""; }; + BA47105F266821C0001A91A5 /* SPBackgroundRefresh.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SPBackgroundRefresh.swift; sourceTree = ""; }; BA4C6CFB264C744300B723A7 /* SeparatorsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeparatorsView.swift; sourceTree = ""; }; BA55124D2600210B00D8F882 /* TimerFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimerFactory.swift; sourceTree = ""; }; BA55B05925F067DF0042582B /* NoticePresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoticePresenter.swift; sourceTree = ""; }; @@ -1880,6 +1882,7 @@ BA55124D2600210B00D8F882 /* TimerFactory.swift */, BAB01791260AAE93007A9CC3 /* NoticeFactory.swift */, BA4C6CFB264C744300B723A7 /* SeparatorsView.swift */, + BA47105F266821C0001A91A5 /* SPBackgroundRefresh.swift */, ); name = Tools; sourceTree = ""; @@ -2968,6 +2971,7 @@ BAA4856925D5E40900F3BDB9 /* SearchQuery+Simplenote.swift in Sources */, B56B357F1AC3565600B9F365 /* UITextView+Simplenote.m in Sources */, B5C9F71E193E75FE00FD2491 /* SPDebugViewController.m in Sources */, + BA471060266821C0001A91A5 /* SPBackgroundRefresh.swift in Sources */, B5A6166F2150855300CBE47B /* Preferences.m in Sources */, 46A3C98E17DFA81A002865AE /* SPObjectManager.m in Sources */, B5DF734F22A599D100602CE7 /* SPNotifications.m in Sources */, diff --git a/Simplenote/SPAppDelegate+Extensions.swift b/Simplenote/SPAppDelegate+Extensions.swift index 9bf0999ee..8dcb14880 100644 --- a/Simplenote/SPAppDelegate+Extensions.swift +++ b/Simplenote/SPAppDelegate+Extensions.swift @@ -406,61 +406,3 @@ extension SPAppDelegate { EditorFactory.shared.scrollPositionCache.cleanup(keeping: allIdentifiers) } } - -// MARK: - Background Fetch -// -@available(iOS 13.0, *) -extension SPAppDelegate { - @objc - func registerBackgroundRefreshTask() { - guard BuildConfiguration.current == .debug else { - return - } - - NSLog("Registered background task with identifier \(BackgroundRefreshConstants.bgTaskIdentifier)") - BGTaskScheduler.shared.register(forTaskWithIdentifier: BackgroundRefreshConstants.bgTaskIdentifier, using: .main) { task in - guard let task = task as? BGAppRefreshTask else { - return - } - self.handleAppRefresh(task: task) - } - } - - private func handleAppRefresh(task: BGAppRefreshTask) { - NSLog("Did fire handle app refresh") - guard BuildConfiguration.current == .debug else { - return - } - - NSLog("Background refresh intiated") - scheduleAppRefresh() - - DispatchQueue.main.asyncAfter(deadline: .now() + BackgroundRefreshConstants.timeOut) { - NSLog("Background refresh finishing") - task.setTaskCompleted(success: true) - } - } - - @objc - func scheduleAppRefresh() { - guard BuildConfiguration.current == .debug else { - return - } - - NSLog("Background refresh scheduled") - let request = BGAppRefreshTaskRequest(identifier: BackgroundRefreshConstants.bgTaskIdentifier) - request.earliestBeginDate = Date(timeIntervalSinceNow: BackgroundRefreshConstants.earliestBeginDate) - do { - try BGTaskScheduler.shared.submit(request) - } catch { - print("Couldn't schedule app refersh: \(error)") - } - } -} - -private struct BackgroundRefreshConstants { - static let earliestBeginDate = TimeInterval(1800.0) //30 minutes - static let timeOut = TimeInterval(25) - static let bundleIdentifier = Bundle.main.bundleIdentifier ?? "com.codality.NotationalFlow" - static let bgTaskIdentifier = bundleIdentifier + ".refresh" -} diff --git a/Simplenote/SPAppDelegate.m b/Simplenote/SPAppDelegate.m index 28d665bd0..95f5f00d2 100644 --- a/Simplenote/SPAppDelegate.m +++ b/Simplenote/SPAppDelegate.m @@ -44,6 +44,7 @@ @interface SPAppDelegate () @property (strong, nonatomic) NSManagedObjectModel *managedObjectModel; @property (strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator; @property (weak, nonatomic) SPModalActivityIndicator *signOutActivityIndicator; +@property (strong, nonatomic) SPBackgroundRefresh *backgroundRefresh; @end @@ -168,7 +169,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( // Register background refresh task to system if (@available(iOS 13.0, *)) { - [self registerBackgroundRefreshTask]; + [self.backgroundRefresh registerBackgroundRefreshTask]; } // Index (All of the) Spotlight Items if the user upgraded @@ -198,7 +199,7 @@ - (void)applicationDidEnterBackground:(UIApplication *)application // Schedule background refresh if (@available(iOS 13.0, *)) { - [self scheduleAppRefresh]; + [self.backgroundRefresh scheduleAppRefresh]; } } diff --git a/Simplenote/SPBackgroundRefresh.swift b/Simplenote/SPBackgroundRefresh.swift new file mode 100644 index 000000000..aeadecaae --- /dev/null +++ b/Simplenote/SPBackgroundRefresh.swift @@ -0,0 +1,66 @@ +import Foundation +import BackgroundTasks + + +class SPBackgroundRefresh: NSObject { +} + +@available(iOS 13.0, *) +extension SPBackgroundRefresh { + // MARK: - Background Fetch + // + @objc + func registerBackgroundRefreshTask() { + guard BuildConfiguration.current == .debug else { + return + } + + NSLog("Registered background task with identifier \(Constants.bgTaskIdentifier)") + BGTaskScheduler.shared.register(forTaskWithIdentifier: Constants.bgTaskIdentifier, using: .main) { task in + guard let task = task as? BGAppRefreshTask else { + return + } + self.handleAppRefresh(task: task) + } + } + + private func handleAppRefresh(task: BGAppRefreshTask) { + NSLog("Did fire handle app refresh") + guard BuildConfiguration.current == .debug else { + return + } + + NSLog("Background refresh intiated") + scheduleAppRefresh() + + DispatchQueue.main.asyncAfter(deadline: .now() + Constants.timeOut) { + NSLog("Background refresh finishing") + task.setTaskCompleted(success: true) + } + } + + @objc + func scheduleAppRefresh() { + guard BuildConfiguration.current == .debug else { + return + } + + NSLog("Background refresh scheduled") + let request = BGAppRefreshTaskRequest(identifier: Constants.bgTaskIdentifier) + request.earliestBeginDate = Date(timeIntervalSinceNow: Constants.earliestBeginDate) + do { + try BGTaskScheduler.shared.submit(request) + } catch { + print("Couldn't schedule app refersh: \(error)") + } + } +} + + +private struct Constants { + static let earliestBeginDate = TimeInterval(60) //30 minutes + static let timeOut = TimeInterval(25) + static let bundleIdentifier = Bundle.main.bundleIdentifier ?? "com.codality.NotationalFlow" + static let bgTaskIdentifier = bundleIdentifier + ".refresh" + static let timerTimeOut = TimeInterval(5) +} From 43250c5708d7527b0a601b3177bfe46000c99659 Mon Sep 17 00:00:00 2001 From: Charlie Scheer Date: Thu, 3 Jun 2021 11:49:53 +1200 Subject: [PATCH 06/11] Added timeouts for background refresh --- Simplenote.xcodeproj/project.pbxproj | 8 +-- ...h.swift => BackgroundRefreshManager.swift} | 57 +++++++++++++++---- Simplenote/SPAppDelegate.m | 10 +++- 3 files changed, 56 insertions(+), 19 deletions(-) rename Simplenote/{SPBackgroundRefresh.swift => BackgroundRefreshManager.swift} (63%) diff --git a/Simplenote.xcodeproj/project.pbxproj b/Simplenote.xcodeproj/project.pbxproj index 2cc4d8ce7..05876207d 100644 --- a/Simplenote.xcodeproj/project.pbxproj +++ b/Simplenote.xcodeproj/project.pbxproj @@ -416,7 +416,7 @@ BA4499B325ED8AB0000C563E /* NoticeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA4499B225ED8AB0000C563E /* NoticeView.swift */; }; BA4499BC25ED95D0000C563E /* Notice.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA4499BB25ED95D0000C563E /* Notice.swift */; }; BA4499C525ED95E5000C563E /* NoticeAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA4499C425ED95E5000C563E /* NoticeAction.swift */; }; - BA471060266821C0001A91A5 /* SPBackgroundRefresh.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA47105F266821C0001A91A5 /* SPBackgroundRefresh.swift */; }; + BA471060266821C0001A91A5 /* BackgroundRefreshManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA47105F266821C0001A91A5 /* BackgroundRefreshManager.swift */; }; BA4C6CFC264C744300B723A7 /* SeparatorsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA4C6CFB264C744300B723A7 /* SeparatorsView.swift */; }; BA55124E2600210B00D8F882 /* TimerFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA55124D2600210B00D8F882 /* TimerFactory.swift */; }; BA55B05A25F067DF0042582B /* NoticePresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA55B05925F067DF0042582B /* NoticePresenter.swift */; }; @@ -955,7 +955,7 @@ BA4499B225ED8AB0000C563E /* NoticeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoticeView.swift; sourceTree = ""; }; BA4499BB25ED95D0000C563E /* Notice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Notice.swift; sourceTree = ""; }; BA4499C425ED95E5000C563E /* NoticeAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoticeAction.swift; sourceTree = ""; }; - BA47105F266821C0001A91A5 /* SPBackgroundRefresh.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SPBackgroundRefresh.swift; sourceTree = ""; }; + BA47105F266821C0001A91A5 /* BackgroundRefreshManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundRefreshManager.swift; sourceTree = ""; }; BA4C6CFB264C744300B723A7 /* SeparatorsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeparatorsView.swift; sourceTree = ""; }; BA55124D2600210B00D8F882 /* TimerFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimerFactory.swift; sourceTree = ""; }; BA55B05925F067DF0042582B /* NoticePresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoticePresenter.swift; sourceTree = ""; }; @@ -1882,7 +1882,7 @@ BA55124D2600210B00D8F882 /* TimerFactory.swift */, BAB01791260AAE93007A9CC3 /* NoticeFactory.swift */, BA4C6CFB264C744300B723A7 /* SeparatorsView.swift */, - BA47105F266821C0001A91A5 /* SPBackgroundRefresh.swift */, + BA47105F266821C0001A91A5 /* BackgroundRefreshManager.swift */, ); name = Tools; sourceTree = ""; @@ -2971,7 +2971,7 @@ BAA4856925D5E40900F3BDB9 /* SearchQuery+Simplenote.swift in Sources */, B56B357F1AC3565600B9F365 /* UITextView+Simplenote.m in Sources */, B5C9F71E193E75FE00FD2491 /* SPDebugViewController.m in Sources */, - BA471060266821C0001A91A5 /* SPBackgroundRefresh.swift in Sources */, + BA471060266821C0001A91A5 /* BackgroundRefreshManager.swift in Sources */, B5A6166F2150855300CBE47B /* Preferences.m in Sources */, 46A3C98E17DFA81A002865AE /* SPObjectManager.m in Sources */, B5DF734F22A599D100602CE7 /* SPNotifications.m in Sources */, diff --git a/Simplenote/SPBackgroundRefresh.swift b/Simplenote/BackgroundRefreshManager.swift similarity index 63% rename from Simplenote/SPBackgroundRefresh.swift rename to Simplenote/BackgroundRefreshManager.swift index aeadecaae..b2c7f7372 100644 --- a/Simplenote/SPBackgroundRefresh.swift +++ b/Simplenote/BackgroundRefreshManager.swift @@ -1,20 +1,52 @@ import Foundation import BackgroundTasks +class BackgroundRefreshManager: NSObject { + private var timer: Timer? { + didSet { + oldValue?.invalidate() + } + } + + private var handler: (()->Void)? + + var finished: Bool = false { + didSet { + if finished == true { + handler?() + } + } + } + + @objc + func refreshTimer() { + // If refresh is not running there will be no handler + guard handler != nil else { + return + } + + timer = Timer.scheduledTimer(timeInterval: Constants.timerTimeOut, target: self, selector: #selector(finishRefresh), userInfo: nil, repeats: false) + } + + @objc + private func finishRefresh() { + guard finished == true, let handler = handler else { + return + } -class SPBackgroundRefresh: NSObject { + handler() + + finished = false + self.handler = nil + } } @available(iOS 13.0, *) -extension SPBackgroundRefresh { +extension BackgroundRefreshManager { // MARK: - Background Fetch // @objc func registerBackgroundRefreshTask() { - guard BuildConfiguration.current == .debug else { - return - } - NSLog("Registered background task with identifier \(Constants.bgTaskIdentifier)") BGTaskScheduler.shared.register(forTaskWithIdentifier: Constants.bgTaskIdentifier, using: .main) { task in guard let task = task as? BGAppRefreshTask else { @@ -26,17 +58,18 @@ extension SPBackgroundRefresh { private func handleAppRefresh(task: BGAppRefreshTask) { NSLog("Did fire handle app refresh") - guard BuildConfiguration.current == .debug else { - return + handler = { + task.setTaskCompleted(success: true) + } + + task.expirationHandler = { + self.finishRefresh() } NSLog("Background refresh intiated") scheduleAppRefresh() - DispatchQueue.main.asyncAfter(deadline: .now() + Constants.timeOut) { - NSLog("Background refresh finishing") - task.setTaskCompleted(success: true) - } + refreshTimer() } @objc diff --git a/Simplenote/SPAppDelegate.m b/Simplenote/SPAppDelegate.m index 95f5f00d2..9dc88268f 100644 --- a/Simplenote/SPAppDelegate.m +++ b/Simplenote/SPAppDelegate.m @@ -44,7 +44,7 @@ @interface SPAppDelegate () @property (strong, nonatomic) NSManagedObjectModel *managedObjectModel; @property (strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator; @property (weak, nonatomic) SPModalActivityIndicator *signOutActivityIndicator; -@property (strong, nonatomic) SPBackgroundRefresh *backgroundRefresh; +@property (strong, nonatomic) BackgroundRefreshManager *refreshManager; @end @@ -169,7 +169,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( // Register background refresh task to system if (@available(iOS 13.0, *)) { - [self.backgroundRefresh registerBackgroundRefreshTask]; + [self.refreshManager registerBackgroundRefreshTask]; } // Index (All of the) Spotlight Items if the user upgraded @@ -199,7 +199,7 @@ - (void)applicationDidEnterBackground:(UIApplication *)application // Schedule background refresh if (@available(iOS 13.0, *)) { - [self.backgroundRefresh scheduleAppRefresh]; + [self.refreshManager scheduleAppRefresh]; } } @@ -431,6 +431,10 @@ - (void)setSelectedTag:(NSString *)selectedTag { - (void)bucket:(SPBucket *)bucket didChangeObjectForKey:(NSString *)key forChangeType:(SPBucketChangeType)change memberNames:(NSArray *)memberNames { + if (@available(iOS 13.0, *)) { + [self.refreshManager refreshTimer]; + } + if ([bucket isEqual:[_simperium notesBucket]]) { // Note change switch (change) { From 8e7163581912cf7d8a7ecb4d28379f2043ba1013 Mon Sep 17 00:00:00 2001 From: Charlie Scheer Date: Thu, 3 Jun 2021 12:05:59 +1200 Subject: [PATCH 07/11] Removed retain cycle on bg.finishrefresh --- Simplenote/BackgroundRefreshManager.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Simplenote/BackgroundRefreshManager.swift b/Simplenote/BackgroundRefreshManager.swift index b2c7f7372..9402a7e94 100644 --- a/Simplenote/BackgroundRefreshManager.swift +++ b/Simplenote/BackgroundRefreshManager.swift @@ -62,8 +62,8 @@ extension BackgroundRefreshManager { task.setTaskCompleted(success: true) } - task.expirationHandler = { - self.finishRefresh() + task.expirationHandler = { [weak self] in + self?.finishRefresh() } NSLog("Background refresh intiated") From 3e5b1e1dc965f317372fd0c9ce86d76516e23c87 Mon Sep 17 00:00:00 2001 From: Charlie Scheer Date: Thu, 3 Jun 2021 15:46:56 +1200 Subject: [PATCH 08/11] Updated background refresh as a stored property in app delegate --- Simplenote/BackgroundRefreshManager.swift | 6 ++++-- Simplenote/SPAppDelegate.m | 17 ++++++++++++++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/Simplenote/BackgroundRefreshManager.swift b/Simplenote/BackgroundRefreshManager.swift index 9402a7e94..f164e44da 100644 --- a/Simplenote/BackgroundRefreshManager.swift +++ b/Simplenote/BackgroundRefreshManager.swift @@ -24,15 +24,16 @@ class BackgroundRefreshManager: NSObject { guard handler != nil else { return } - + NSLog("Refresh Timer Called") timer = Timer.scheduledTimer(timeInterval: Constants.timerTimeOut, target: self, selector: #selector(finishRefresh), userInfo: nil, repeats: false) } @objc private func finishRefresh() { - guard finished == true, let handler = handler else { + guard let handler = handler else { return } + NSLog("Finish Refresh Called") handler() @@ -83,6 +84,7 @@ extension BackgroundRefreshManager { request.earliestBeginDate = Date(timeIntervalSinceNow: Constants.earliestBeginDate) do { try BGTaskScheduler.shared.submit(request) + NSLog("Background refresh submitted") } catch { print("Couldn't schedule app refersh: \(error)") } diff --git a/Simplenote/SPAppDelegate.m b/Simplenote/SPAppDelegate.m index 9dc88268f..c089cfa52 100644 --- a/Simplenote/SPAppDelegate.m +++ b/Simplenote/SPAppDelegate.m @@ -48,7 +48,6 @@ @interface SPAppDelegate () @end - #pragma mark ================================================================================ #pragma mark Simplenote AppDelegate #pragma mark ================================================================================ @@ -668,4 +667,20 @@ + (SPAppDelegate *)sharedDelegate return (SPAppDelegate *)[[UIApplication sharedApplication] delegate]; } + +#pragma mark ================================================================================ +#pragma mark Background Refresh +#pragma mark ================================================================================ + +- (BackgroundRefreshManager *)refreshManager +{ + if (_refreshManager != nil) { + return _refreshManager; + } + + _refreshManager = [[BackgroundRefreshManager alloc] init]; + + return _refreshManager; +} + @end From 466e734894ea742c0b04c1acff22b7a528d4b94a Mon Sep 17 00:00:00 2001 From: Charlie Scheer Date: Fri, 4 Jun 2021 11:57:35 +1200 Subject: [PATCH 09/11] Removed finished variable from refresh manager --- Simplenote/BackgroundRefreshManager.swift | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/Simplenote/BackgroundRefreshManager.swift b/Simplenote/BackgroundRefreshManager.swift index f164e44da..b54df7f63 100644 --- a/Simplenote/BackgroundRefreshManager.swift +++ b/Simplenote/BackgroundRefreshManager.swift @@ -10,16 +10,7 @@ class BackgroundRefreshManager: NSObject { private var handler: (()->Void)? - var finished: Bool = false { - didSet { - if finished == true { - handler?() - } - } - } - - @objc - func refreshTimer() { + private func refreshTimer() { // If refresh is not running there will be no handler guard handler != nil else { return @@ -37,8 +28,13 @@ class BackgroundRefreshManager: NSObject { handler() - finished = false self.handler = nil + self.timer = nil + } + + @objc + func onSimperiumChange() { + refreshTimer() } } From 22a114aa0b95559d0b512bb27dc57f786ddcfcb3 Mon Sep 17 00:00:00 2001 From: Charlie Scheer Date: Fri, 4 Jun 2021 11:58:23 +1200 Subject: [PATCH 10/11] Added a method to cancel pending BG tasks if SN enters the foreground --- Simplenote/BackgroundRefreshManager.swift | 8 ++++++-- Simplenote/SPAppDelegate.m | 4 ++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/Simplenote/BackgroundRefreshManager.swift b/Simplenote/BackgroundRefreshManager.swift index b54df7f63..0048f0380 100644 --- a/Simplenote/BackgroundRefreshManager.swift +++ b/Simplenote/BackgroundRefreshManager.swift @@ -85,13 +85,17 @@ extension BackgroundRefreshManager { print("Couldn't schedule app refersh: \(error)") } } + + @objc + func cancelPendingRefreshTasks() { + BGTaskScheduler.shared.cancel(taskRequestWithIdentifier: Constants.bgTaskIdentifier) + } } private struct Constants { static let earliestBeginDate = TimeInterval(60) //30 minutes - static let timeOut = TimeInterval(25) static let bundleIdentifier = Bundle.main.bundleIdentifier ?? "com.codality.NotationalFlow" static let bgTaskIdentifier = bundleIdentifier + ".refresh" - static let timerTimeOut = TimeInterval(5) + static let timerTimeOut = TimeInterval(8) } diff --git a/Simplenote/SPAppDelegate.m b/Simplenote/SPAppDelegate.m index c089cfa52..0e5a8ddfc 100644 --- a/Simplenote/SPAppDelegate.m +++ b/Simplenote/SPAppDelegate.m @@ -205,6 +205,10 @@ - (void)applicationDidEnterBackground:(UIApplication *)application - (void)applicationWillEnterForeground:(UIApplication *)application { [self dismissPasscodeLockIfPossible]; + + if (@available(iOS 13.0, *)) { + [self.refreshManager cancelPendingRefreshTasks]; + } } - (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray> * _Nullable))restorationHandler From 4442d5509e2cc98f1d801cd37fc403b332374e5d Mon Sep 17 00:00:00 2001 From: Charlie Scheer Date: Fri, 4 Jun 2021 11:58:46 +1200 Subject: [PATCH 11/11] Updated refresh timer method to onSimperiumChange --- Simplenote/SPAppDelegate.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Simplenote/SPAppDelegate.m b/Simplenote/SPAppDelegate.m index 0e5a8ddfc..b89dfaaf2 100644 --- a/Simplenote/SPAppDelegate.m +++ b/Simplenote/SPAppDelegate.m @@ -435,7 +435,7 @@ - (void)setSelectedTag:(NSString *)selectedTag { - (void)bucket:(SPBucket *)bucket didChangeObjectForKey:(NSString *)key forChangeType:(SPBucketChangeType)change memberNames:(NSArray *)memberNames { if (@available(iOS 13.0, *)) { - [self.refreshManager refreshTimer]; + [self.refreshManager onSimperiumChange]; } if ([bucket isEqual:[_simperium notesBucket]]) {