In the background, Apple iWatch does not call or start with a schedule

Refresh location when a task starts when the application is in the background. But failed to complete the task in the background. My sample code with scheduleBackgroundRefreshWithPreferredDate looks below

[WKExtension.sharedExtension scheduleBackgroundRefreshWithPreferredDate:[NSDate dateWithTimeIntervalSinceNow:60] userInfo:nil scheduledCompletion:^(NSError * _Nullable error) { if(error == nil) { NSLog(@"background refresh task re-scheduling successfuly "); } else{ NSLog(@"Error occurred while re-scheduling background refresh: %@",error.localizedDescription); } }]; 

After completing the schedule task in handleBackgroundTasks:

 - (void)handleBackgroundTasks:(NSSet<WKRefreshBackgroundTask *> *)backgroundTasks { for (WKRefreshBackgroundTask * task in backgroundTasks) { if ([task isKindOfClass:[WKApplicationRefreshBackgroundTask class]]) { WKApplicationRefreshBackgroundTask *backgroundTask = (WKApplicationRefreshBackgroundTask*)task; // location update methods schedule as background task [self startLocationUpdate]; [backgroundTask setTaskCompleted]; } else if ([task isKindOfClass:[WKSnapshotRefreshBackgroundTask class]]) { WKSnapshotRefreshBackgroundTask *snapshotTask = (WKSnapshotRefreshBackgroundTask*)task; [snapshotTask setTaskCompletedWithDefaultStateRestored:YES estimatedSnapshotExpiration:[NSDate distantFuture] userInfo:nil]; } else if ([task isKindOfClass:[WKWatchConnectivityRefreshBackgroundTask class]]) { WKWatchConnectivityRefreshBackgroundTask *backgroundTask = (WKWatchConnectivityRefreshBackgroundTask*)task; [backgroundTask setTaskCompleted]; } else if ([task isKindOfClass:[WKURLSessionRefreshBackgroundTask class]]) { WKURLSessionRefreshBackgroundTask *backgroundTask = (WKURLSessionRefreshBackgroundTask*)task; [backgroundTask setTaskCompleted]; } else { [task setTaskCompleted]; } } } 

Background task methods as shown below

 -(void)startLocationUpdate { locationMgr = [[CLLocationManager alloc] init]; [locationMgr setDelegate:self]; locationMgr.desiredAccuracy = kCLLocationAccuracyBest; locationMgr.distanceFilter = kCLDistanceFilterNone; // locationMgr.allowsBackgroundLocationUpdates = YES; [locationMgr requestAlwaysAuthorization]; [locationMgr startUpdatingLocation]; [WKExtension.sharedExtension scheduleBackgroundRefreshWithPreferredDate:[NSDate dateWithTimeIntervalSinceNow:60] userInfo:nil scheduledCompletion:^(NSError * _Nullable error) { if(error == nil) { NSLog(@"background refresh task re-scheduling successfuly "); } else{ NSLog(@"Error occurred while re-scheduling background refresh: %@",error.localizedDescription); } }]; } - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations { NSTimeInterval locationAge = -[[locations lastObject].timestamp timeIntervalSinceNow]; NSLog(@"Location Age : %f",locationAge); if (locationAge > 5.0) return; NSLog(@"latitude: %f longitude: %f",[locations lastObject].coordinate.latitude,[locations lastObject].coordinate.longitude); //NSString *strLocation = [NSString stringWithFormat:@"%f,%f" ,[locations lastObject].coordinate.latitude , [locations lastObject].coordinate.longitude]; NSString *strLocation = @"bgLocation"; NSDictionary *applicationData = [[NSDictionary alloc] initWithObjects:@[strLocation] forKeys:@[@"watchlocation"]]; [[WCSession defaultSession] transferUserInfo:applicationData]; } 
+5
source share
1 answer

Running the background is very difficult on watchOS3. There are many limitations, and even if you have successfully scheduled a background update task, there is no guarantee that watchOS will launch it.

According to my experience after a dig in WWDC sessions and documentation:

  • watchOS3 will not give your application any background runtime if the application is not in the Dock or has active complication in the current time zone
  • The number of background update tasks is limited to approximately 1 hour for applications in the Dock and 2 per hour for applications with active complication.
  • background execution time is also limited, and if the application exceeds this time, it will be interrupted by the watchOS daemon
  • after calling setTaskCompleted application goes into a suspended state, so the async method locationManager:didUpdateLocations: from your code should not be executed
+5
source

Source: https://habr.com/ru/post/1269022/


All Articles