2017-06-20 32 views
5

当应用程序在后台触发任务时更新位置。但无法执行背景模式的任务。与scheduleBackgroundRefreshWithPreferredDate我的示例代码如下在苹果iWatch后台任务没有被调用或触发与计划时间

[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); 
     } 
    }]; 

后计划任务中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]; 
     } 
    } 
} 

后台任务的方法重新安排如下

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

} 
+0

我想发送当前位置(更新监视位置)到iOS应用,即使在后台模式 – Ashish

+0

手表应用使用WatchConnectivity将手表的位置信息发送到手机是没有意义的。如果您想使用WatchConnectivity,应用程序需要至少在手机的后台运行,所以只需在手机上获取位置数据,而不是将手表放在手表上并将其发送给电话。 –

+0

如果我在iPhone上看到的位置比计算iPhone和iWatch之间的距离并触发通知基于它们之间的距离 – Ashish

回答

5

背景执行是以watchOS3非常困难。有很多限制,即使您已经成功安排了后台刷新任务,也无法保证watchOS会启动它。

根据挖掘到WWDC会议和文件后,我的经验:

  1. watchOS3不会给你的应用程序的任何背景的执行时间,如果应用程序是不是在Dock或不会对当前的表盘
  2. 活跃并发症后台刷新任务的数量限制在Dock中的应用每小时约1个,并且活动复杂的应用每小时限制为2个小时
  3. 后台执行的时间也受到限制,并且如果应用超过此时间,它将由watchOS守护进程终止
  4. 一旦你打电话setTaskCompleted,应用程序进入暂停状态,所以异步从你的代码locationManager:didUpdateLocations:方法不应该被执行
相关问题