Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/bg fetch #1303

Draft
wants to merge 11 commits into
base: trunk
Choose a base branch
from
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)?

var finished: Bool = false {
didSet {
if finished == true {
handler?()
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need to track finished

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A totally. The finished variable was something I had put in because I was having issues making an instance of the backgroundFetchManager in the app delegate. Was trying to use changing it to trigger ending the refresh, but using the handler instead can serve that same purpose. I have removed the finished var.


@objc
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()

finished = false
self.handler = nil
charliescheer marked this conversation as resolved.
Show resolved Hide resolved
}
}

@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)")
}
}
}


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)
}
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
32 changes: 31 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,6 +195,11 @@ - (void)applicationDidEnterBackground:(UIApplication *)application

[self showPasscodeLockIfNecessary];
[self cleanupScrollPositionCache];

// Schedule background refresh
if (@available(iOS 13.0, *)) {
[self.refreshManager scheduleAppRefresh];
charliescheer marked this conversation as resolved.
Show resolved Hide resolved
}
}

- (void)applicationWillEnterForeground:(UIApplication *)application
Expand Down Expand Up @@ -420,6 +430,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];
charliescheer marked this conversation as resolved.
Show resolved Hide resolved
}

if ([bucket isEqual:[_simperium notesBucket]]) {
// Note change
switch (change) {
Expand Down Expand Up @@ -653,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
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