I need to add the snapshot of a watch app to be placed in Dock as it's a new feature I can't find any resources to guide me. I have read Apple's Documentation https://developer.apple.com/library/prerelease/content/samplecode/WatchBackgroundRefresh/Introduction/Intro.html and I have implemented this code in the main InterfaceController of the Watch app based on the Apple Documentation: https://developer.apple.com/library/prerelease/content/samplecode/WatchBackgroundRefresh/Introduction/Intro.html but handleBackgroundTasks is never called. Am I doing something wrong? can I have screenshot of another InterfaceController rather than main InterfaceController to be placed in the Dock? how?
@interface ExtensionDelegate : NSObject <WKExtensionDelegate>
@property (nonatomic, weak) MainInterfaceController *interfaceController;
@implementation ExtensionDelegate
-(void)applicationDidEnterBackground {
[self scheduleRefreshBackgroundTask];
[self scheduleSnapshotRefreshBackgroundTask];
}
-(void)scheduleRefreshBackgroundTask WK_AVAILABLE_WATCHOS_ONLY(3.0){
// Background Refresh
NSDictionary *backgroundRefreshUserInfo = @{@"reason": @"Bakcground Refresh"};
NSDate *backgroundRefreshDate = [NSDate dateWithTimeIntervalSinceNow:30 * 60];
[[WKExtension sharedExtension] scheduleBackgroundRefreshWithPreferredDate:backgroundRefreshDate
userInfo:backgroundRefreshUserInfo
scheduledCompletion:^(NSError *error){
if (error == nil) {
DMLogVerbose(DebugLogTypeWatch, @"successfully scheduled background refresh tesk");
} else {
DMLogError(DebugLogTypeWatch, @"unable to schedule background refresh task, error:%@", error);
}
}];
}
-(void)scheduleSnapshotRefreshBackgroundTask WK_AVAILABLE_WATCHOS_ONLY(3.0){
//fire in 1 hr
NSDate *inputDate = [NSDate date];
NSDate *fireDate = [inputDate initWithTimeIntervalSinceNow:1 * 60 * 60];
//optional.. any sourceCoding compliant data can be passed here
// SnapShot
NSDictionary *userInfo = @{@"reason": @"Snapshot Refresh"};
[[WKExtension sharedExtension] scheduleSnapshotRefreshWithPreferredDate:fireDate
userInfo:userInfo
scheduledCompletion:^(NSError *error){
if (error == nil) {
DMLogVerbose(DebugLogTypeWatch, @"successfully scheduled background tesk, use the crown to send the app to the background and wait for handle:backgroundTasks to fire.");
}
}];
}
-(void)handleBackgroundTasks:(NSSet<WKRefreshBackgroundTask *> *)backgroundTasks WK_AVAILABLE_WATCHOS_ONLY(3.0) {
for (WKRefreshBackgroundTask *task in backgroundTasks) {
if ([[WKExtension sharedExtension] applicationState] == WKApplicationStateBackground) {
// Snapshot
if ([task isKindOfClass:[WKSnapshotRefreshBackgroundTask class]]) {
if (self.interfaceController) {
[self.interfaceController updateData:YES];
[self.interfaceController initializeDefaultUI];
[self scheduleSnapshotRefreshBackgroundTask];
}
}
// Connectivity Refresh
else if ([task isKindOfClass:[WKWatchConnectivityRefreshBackgroundTask class]]) {
// do something
}
// Network (URLSession)
else if ([task isKindOfClass:[WKURLSessionRefreshBackgroundTask class]]) {
// Resume download
NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:[DataManager watchDataURLSessionIdentifier]];
NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfig
delegate:
[TWNDataManager sharedDataManager].currentWatchDataDownloader
delegateQueue:nil];
DMLogVerbose(DebugLogTypeWatch, @"Resume watch download session in background:%@", session);
}
// Background Refresh
else if ([task isKindOfClass:[WKApplicationRefreshBackgroundTask class]]){
NSDictionary *userInfo = [task userInfo];
NSString *reason = [userInfo objectForKey:@"reason"];
if ([reason isEqualToString:@"Bakcground Refresh"]) {
if (self.interfaceController && !self.isBackgroundUpdating) {
self.isBackgroundUpdating = YES;
[self.interfaceController updateData:YES];
self.isBackgroundUpdating = NO;
[self scheduleRefreshBackgroundTask];
}
}
}
}
[task setTaskCompleted];
}
}
I have the same problem. I have tested Apple's sample code also https://developer.apple.com/library/prerelease/content/samplecode/WatchBackgroundRefresh/Introduction/Intro.html and the
handle(_:)
method was not called. Until I have restarted the simulators a few times, cleaned the product, did the usual stuff. Then I got it working, but only one out od 30 times testing was the method functioning properly (scheduling the snapshot request after finished downloading and then waking up the app). I have filled a bug report and I hope to see this fixed in their next beta version, since I lose a lot of time in testing that is not working as per documentation.