In apple iWatch background task is not getting called or triggering with schedule time
Asked Answered
T

1

6

Update location when a task is triggered when the app in background. But unable to execute a task with background mode. My sample code with scheduleBackgroundRefreshWithPreferredDate is as 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 schedule task reschedule 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 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];

}
Titter answered 20/6, 2017 at 9:54 Comment(3)
i want to sent current location(updated watch location) to iOS app even when watch app in background modeTitter
It makes no sense to send location information from you watch to the phone using WatchConnectivity. If you want to use WatchConnectivity, the app needs to be running at least in the background on the phone, so it is easier and more optimal to just get the location data on the phone rather than get it on the watch and send it to the phone.Postbox
if I get watch location on iPhone than I calculate distance between iPhone and iWatch and trigger notification base on distance of between themTitter
A
7

Background execution is very difficult on watchOS3. There are many restrictions, and even if you've successfully scheduled background refresh task, there is no guarantee that watchOS will start it.

According to my experience after digging into WWDC sessions and documentation:

  1. watchOS3 will not give your app any background execution time if app is not in Dock or do not have active complication on current watchface
  2. number of background refresh tasks is limited to about 1 per hour for apps in Dock and 2 per hour for apps with active complication
  3. time of background execution is also limited, and if app exceeds this time, it will be terminated by watchOS daemon
  4. once you call setTaskCompleted, app goes to suspended state, so async locationManager:didUpdateLocations: method from your code should not be executed
Actinal answered 20/6, 2017 at 13:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.