2017-06-20 33 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:方法不應該被執行
相關問題