在Apple iWatch后台任务没有被调用或触发计划时间

Ash*_*ish 6 objective-c ios watchkit watchos-3 watchos-4

当应用程序在后台触发任务时更新位置.但无法使用后台模式执行任务.我的scheduleBackgroundRefreshWithPreferredDate示例代码如下所示

[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);
        }
    }];
Run Code Online (Sandbox Code Playgroud)

计划任务重新安排后 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];
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

背景任务方法如下

-(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];

}
Run Code Online (Sandbox Code Playgroud)

abj*_*ato 7

watchOS3上的后台执行非常困难.有许多限制,即使您已成功安排后台刷新任务,也无法保证watchOS将启动它.

根据我在深入WWDC会议和文档后的经验:

  1. 如果应用程序不在Dock中或者当前表面上没有活动复杂功能,watchOS3将不会为您的应用程序提供任何后台执行时间
  2. 对于Dock中的应用程序,后台刷新任务的数量限制为每小时约1次,对于具有活动复杂功能的应用程序,每小时限制为2次
  3. 后台执行的时间也是有限的,如果app超过这个时间,它将被watchOS守护进程终止
  4. 一旦你打电话setTaskCompleted,app就会进入暂停状态,所以locationManager:didUpdateLocations:不应该执行代码中的异步方法