Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Simplenote.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -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 /* 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 */; };
Expand Down Expand Up @@ -954,6 +955,7 @@
BA4499B225ED8AB0000C563E /* NoticeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoticeView.swift; sourceTree = "<group>"; };
BA4499BB25ED95D0000C563E /* Notice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Notice.swift; sourceTree = "<group>"; };
BA4499C425ED95E5000C563E /* NoticeAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoticeAction.swift; sourceTree = "<group>"; };
BA47105F266821C0001A91A5 /* BackgroundRefreshManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundRefreshManager.swift; sourceTree = "<group>"; };
BA4C6CFB264C744300B723A7 /* SeparatorsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeparatorsView.swift; sourceTree = "<group>"; };
BA55124D2600210B00D8F882 /* TimerFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimerFactory.swift; sourceTree = "<group>"; };
BA55B05925F067DF0042582B /* NoticePresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoticePresenter.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1880,6 +1882,7 @@
BA55124D2600210B00D8F882 /* TimerFactory.swift */,
BAB01791260AAE93007A9CC3 /* NoticeFactory.swift */,
BA4C6CFB264C744300B723A7 /* SeparatorsView.swift */,
BA47105F266821C0001A91A5 /* BackgroundRefreshManager.swift */,
);
name = Tools;
sourceTree = "<group>";
Expand Down Expand Up @@ -2968,6 +2971,7 @@
BAA4856925D5E40900F3BDB9 /* SearchQuery+Simplenote.swift in Sources */,
B56B357F1AC3565600B9F365 /* UITextView+Simplenote.m in Sources */,
B5C9F71E193E75FE00FD2491 /* SPDebugViewController.m in Sources */,
BA471060266821C0001A91A5 /* BackgroundRefreshManager.swift in Sources */,
B5A6166F2150855300CBE47B /* Preferences.m in Sources */,
46A3C98E17DFA81A002865AE /* SPObjectManager.m in Sources */,
B5DF734F22A599D100602CE7 /* SPNotifications.m in Sources */,
Expand Down
101 changes: 101 additions & 0 deletions Simplenote/BackgroundRefreshManager.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import Foundation
import BackgroundTasks

class BackgroundRefreshManager: NSObject {
private var timer: Timer? {
didSet {
oldValue?.invalidate()
}
}

private var handler: (()->Void)?

private func refreshTimer() {
// If refresh is not running there will be no handler
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 let handler = handler else {
return
}
NSLog("Finish Refresh Called")

handler()

self.handler = nil
self.timer = nil
}

@objc
func onSimperiumChange() {
refreshTimer()
}
}

@available(iOS 13.0, *)
extension BackgroundRefreshManager {
// MARK: - Background Fetch
//
@objc
func registerBackgroundRefreshTask() {
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")
handler = {
task.setTaskCompleted(success: true)
}

task.expirationHandler = { [weak self] in
self?.finishRefresh()
}

NSLog("Background refresh intiated")
scheduleAppRefresh()

refreshTimer()
}

@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)
NSLog("Background refresh submitted")
} catch {
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 bundleIdentifier = Bundle.main.bundleIdentifier ?? "com.codality.NotationalFlow"
static let bgTaskIdentifier = bundleIdentifier + ".refresh"
static let timerTimeOut = TimeInterval(8)
}
1 change: 1 addition & 0 deletions Simplenote/SPAppDelegate+Extensions.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Foundation
import BackgroundTasks


// MARK: - Initialization
Expand Down
36 changes: 35 additions & 1 deletion Simplenote/SPAppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@ @interface SPAppDelegate ()
@property (strong, nonatomic) NSManagedObjectModel *managedObjectModel;
@property (strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
@property (weak, nonatomic) SPModalActivityIndicator *signOutActivityIndicator;
@property (strong, nonatomic) BackgroundRefreshManager *refreshManager;

@end


#pragma mark ================================================================================
#pragma mark Simplenote AppDelegate
#pragma mark ================================================================================
Expand Down Expand Up @@ -166,6 +166,11 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
[self showPasscodeLockIfNecessary];
}

// Register background refresh task to system
if (@available(iOS 13.0, *)) {
[self.refreshManager registerBackgroundRefreshTask];
}

// Index (All of the) Spotlight Items if the user upgraded
[self indexSpotlightItemsIfNeeded];

Expand All @@ -190,11 +195,20 @@ - (void)applicationDidEnterBackground:(UIApplication *)application

[self showPasscodeLockIfNecessary];
[self cleanupScrollPositionCache];

// Schedule background refresh
if (@available(iOS 13.0, *)) {
[self.refreshManager scheduleAppRefresh];
}
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
[self dismissPasscodeLockIfPossible];

if (@available(iOS 13.0, *)) {
[self.refreshManager cancelPendingRefreshTasks];
}
}

- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler
Expand Down Expand Up @@ -420,6 +434,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 onSimperiumChange];
}

if ([bucket isEqual:[_simperium notesBucket]]) {
// Note change
switch (change) {
Expand Down Expand Up @@ -653,4 +671,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
8 changes: 8 additions & 0 deletions Simplenote/Simplenote-Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@
<string>com.codality.NotationalFlow.newNote</string>
<string>com.codality.NotationalFlow.openNote</string>
</array>
<key>UIBackgroundModes</key>
<array>
<string>fetch</string>
</array>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIPrerenderedIcon</key>
Expand All @@ -86,6 +90,10 @@
<array>
<string>armv7</string>
</array>
<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
<string>$(PRODUCT_BUNDLE_IDENTIFIER).refresh</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
Expand Down