2016-09-17 112 views
7

我所有的代碼是在AppDelegate.m:顯著改變位置委託方法不會被調用

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 
    self.window = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]]; 

    _locationMgr = [[CLLocationManager alloc] init]; 
    [_locationMgr setDelegate:self]; 
    if([_locationMgr respondsToSelector:@selector(setAllowsBackgroundLocationUpdates:)]) 
     [_locationMgr setAllowsBackgroundLocationUpdates:YES]; 
    CLAuthorizationStatus authorizationStatus= [CLLocationManager authorizationStatus]; 

    if([launchOptions valueForKey:UIApplicationLaunchOptionsLocationKey] != nil) { 
     NSLog(@"relaunching because of significant location change - restarting SLC"); 
     [_locationMgr startMonitoringSignificantLocationChanges]; 
    } 
    else 
    { 
     if (authorizationStatus == kCLAuthorizationStatusAuthorizedAlways) { 
      NSLog(@"launching with authorization to always use location - starting SLC"); 
      [_locationMgr startMonitoringSignificantLocationChanges]; 
     } 
     else 
     { 
      NSLog(@"launching with no authorization to always use location - requesting authorization"); 
      if([_locationMgr respondsToSelector:@selector(requestAlwaysAuthorization)]) 
       [_locationMgr requestAlwaysAuthorization]; 
     } 
    } 

    if([userdefaults objectForKey:@"pfuser"] == nil) { 
     NSLog(@"in delegate signup"); 
     SignUpController *signup = [[SignUpController alloc] init]; 
     [self.window setRootViewController:signup]; 
    } 
    else { 
     ViewController *map = [[ViewController alloc] init]; 
     [self.window setRootViewController:map]; 
    } 
    [self.window makeKeyAndVisible]; 

    return YES; 
} 

- (void)startSignificantChangeUpdates 
{ 
    deviceNotFoundAlertController = [UIAlertController alertControllerWithTitle:@"START" message:@"startSignificantChangeUpdates called" preferredStyle:UIAlertControllerStyleAlert]; 

    [deviceNotFoundAlertController addAction:deviceNotFoundAlert]; 
    // Create the location manager if this object does not 
    // already have one. 
    if (nil == _locationMgr) { 
     _locationMgr = [[CLLocationManager alloc] init]; 
     _locationMgr.delegate = self; 
    } 

    [CLLocationManager significantLocationChangeMonitoringAvailable]; 
    [_locationMgr startMonitoringSignificantLocationChanges]; 
} 

-(void)locationManger:(CLLocationManager *)manager didFailWithError:(NSError *)error { 
    NSLog(@"didFailWithError: %@", error); 
    deviceNotFoundAlertController = [UIAlertController alertControllerWithTitle:@"LOCATION FAIL" message:@"didFailWithError" preferredStyle:UIAlertControllerStyleAlert]; 

    [deviceNotFoundAlertController addAction:deviceNotFoundAlert]; 
} 

// Delegate method from the CLLocationManagerDelegate protocol. 
- (void)_locationManager:(CLLocationManager *)manager 
     didUpdateLocations:(NSArray *)locations { 
    deviceNotFoundAlertController = [UIAlertController alertControllerWithTitle:@"LOCATION UPDATE" message:@"didUpdateLocations called" preferredStyle:UIAlertControllerStyleAlert]; 

    [deviceNotFoundAlertController addAction:deviceNotFoundAlert]; 
    // If it's a relatively recent event, turn off updates to save power. 
    CLLocation* location = [locations lastObject]; 
    NSDate* eventDate = location.timestamp; 
    NSTimeInterval howRecent = [eventDate timeIntervalSinceNow]; 
    if (fabs(howRecent) < 15.0) { 
     // If the event is recent, do something with it. 
     NSLog(@"latitude %+.6f, longitude %+.6f\n", 
       location.coordinate.latitude, 
       location.coordinate.longitude); 
    } 
} 

警報都沒有發生,似乎沒有被稱爲委託方法。

UPDATE

現在我有:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 
    self.window = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]]; 

    deviceNotFoundAlert = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]; 

    ... 

} 

// Delegate method from the CLLocationManagerDelegate protocol. 
- (void)locationManager:(CLLocationManager *)manager 
     didUpdateLocations:(NSArray *)locations { 
    deviceNotFoundAlertController = [UIAlertController alertControllerWithTitle:@"LOCATION UPDATE" message:@"didUpdateLocations called" preferredStyle:UIAlertControllerStyleAlert]; 

    [deviceNotFoundAlertController addAction:deviceNotFoundAlert]; 
    // If it's a relatively recent event, turn off updates to save power. 
    CLLocation* location = [locations lastObject]; 
    NSDate* eventDate = location.timestamp; 
    NSTimeInterval howRecent = [eventDate timeIntervalSinceNow]; 
    if (fabs(howRecent) < 15.0) { 
     // If the event is recent, do something with it. 
     NSLog(@"latitude %+.6f, longitude %+.6f\n", 
       location.coordinate.latitude, 
       location.coordinate.longitude); 
    } 
} 

當我測試的應用程序,我打開它在我的房子,然後將其關閉,這樣,當我離開我的房子應該送(或3),但我沒有收到來自任何委託方法(我放置警報的位置)的警報。

我剛剛有一個想法,也許我必須顯示從主UIViewController,而不是AppDelegate警報?

這可能就是爲什麼我沒有看到警報:How do I add a UIAlertController in app delegate (obj-c)

UPDATE

這就是我正在做的警報現在:

deviceNotFoundAlertController = [UIAlertController alertControllerWithTitle:@"START" message:@"startSignificantChangeUpdates called" preferredStyle:UIAlertControllerStyleAlert]; 

[deviceNotFoundAlertController addAction:deviceNotFoundAlert]; 

alertWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 
alertWindow.rootViewController = [[UIViewController alloc] init]; 
alertWindow.windowLevel = UIWindowLevelAlert + 1; 
[alertWindow makeKeyAndVisible]; 
[alertWindow.rootViewController presentViewController:deviceNotFoundAlertController animated:YES completion:nil]; 

UPDATE

警報似乎不是問題,麥芽酒rt startSignificantChangeUpdates從未出現。一旦我離開我的初始位置500米後,它會出現嗎?

UPDATE

誰能幫助我理解?

您的委託對象的方法是從您啓動相應位置服務的線程中調用的。該線程本身必須有一個活動的運行循環,就像在應用程序的主線程中找到的一樣。

UPDATE

我想我想通了什麼,以上報價是說......我有現在這樣 - 我明天將測試。

... 

if([launchOptions valueForKey:UIApplicationLaunchOptionsLocationKey] != nil) { 
     NSLog(@"relaunching because of significant location change - restarting SLC"); 
     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
      [_locationMgr startMonitoringSignificantLocationChanges]; 
     }); 
    } 
    else 
    { 
     if (authorizationStatus == kCLAuthorizationStatusAuthorizedAlways) { 
      NSLog(@"launching with authorization to always use location - starting SLC"); 
      dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
       [_locationMgr startMonitoringSignificantLocationChanges]; 
      }); 
     } 
     else 
     { 
      NSLog(@"launching with no authorization to always use location - requesting authorization"); 
      if([_locationMgr respondsToSelector:@selector(requestAlwaysAuthorization)]) 
       [_locationMgr requestAlwaysAuthorization]; 
     } 
    } 

... 

我認爲代碼是在自己的線程上啓動位置服務。我注意到的一件事是,當我退出應用程序時,右上角的位置消失。我剛剛更新到了iOS 10.在iOS 9中,右上角的位置箭頭將停留在那裏,但當應用程序未運行時,它只會是黑色輪廓。這可能只是他們在iOS 10中改變的東西,或者現在因爲我已更新到10,現在還沒有其他工作。或者當位置服務在自己的線程上運行時會發生什麼情況。從這裏:iOS start Background Thread

UPDATE

也許我沒有正確地使用線程,但正如我所說的,現在當我關閉應用程序,位置服務退出。當我在沒有線程的情況下執行時,位置服務箭頭將保留在右上角,作爲大綱。

UPDATE

,我讀了服務應該在主線程啓動 - 所以我現在:

CLAuthorizationStatus authorizationStatus= [CLLocationManager authorizationStatus]; 

    NSLog(@"launching with no authorization to always use location - requesting authorization"); 
    if([_locationMgr respondsToSelector:@selector(requestAlwaysAuthorization)]) { 
     [_locationMgr requestAlwaysAuthorization]; 
    } 

    if([launchOptions valueForKey:UIApplicationLaunchOptionsLocationKey] != nil) { 
     NSLog(@"relaunching because of significant location change - restarting SLC"); 
     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
      [_locationMgr startMonitoringSignificantLocationChanges]; 
     }); 
    } 
    else if (authorizationStatus == kCLAuthorizationStatusAuthorizedAlways) { 
     NSLog(@"launching with authorization to always use location - starting SLC"); 
     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
      [_locationMgr startMonitoringSignificantLocationChanges]; 
     }); 
    } 
    else { 
     // 
    } 

中不顯示時,應用程序是右側的箭頭關閉,這是iOS 10的新功能,它們不再顯示它嗎?

UPDATE

我不小心刪除:_locationMgr = [[CLLocationManager alloc] init];我把現在的箭頭是永遠存在的,今天要測試。

UPDATE

我測試了,仍然沒有警報。

+0

您是否配置了使用位置服務的plist?如果沒有,那麼你需要做到這一點。有兩個選項requestAlwaysAuthorization和requestWhenInUseAuthorization。讓我知道如果這可以解決您的問題 – Janmenjaya

+0

嗨,是的,我有 - 當我輸入它時,更改爲「隱私 - 位置總是使用說明」,然後我在另一列中輸入消息...現在實際上有些不同了...我想我需要再次測試生病讓你知道 – ewizard

+0

我也有'需要的背景模式'與'Item0'和'應用程序寄存器的位置更新' – ewizard

回答

2

我把我的電腦我在我的車,並觀看了控制檯,我看到顯著位置的變化正在發生,因爲我得到的位置更新每隔500米。警報是唯一不起作用的,但與程序無關 - 他們只是在那裏看看它是否工作。它正在使用此代碼:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 
    self.window = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]]; 

    ... 

    _locationMgr = [[CLLocationManager alloc] init]; 
    [_locationMgr setDelegate:self]; 

    if([_locationMgr respondsToSelector:@selector(setAllowsBackgroundLocationUpdates:)]) 
     [_locationMgr setAllowsBackgroundLocationUpdates:YES]; 

    CLAuthorizationStatus authorizationStatus= [CLLocationManager authorizationStatus]; 

    NSLog(@"launching with no authorization to always use location - requesting authorization"); 
    if([_locationMgr respondsToSelector:@selector(requestAlwaysAuthorization)]) { 
     [_locationMgr requestAlwaysAuthorization]; 
    } 

    if([launchOptions valueForKey:UIApplicationLaunchOptionsLocationKey] != nil) { 
     NSLog(@"relaunching because of significant location change - restarting SLC"); 
     [_locationMgr startMonitoringSignificantLocationChanges]; 
    } 
    else if (authorizationStatus == kCLAuthorizationStatusAuthorizedAlways) { 
     NSLog(@"launching with authorization to always use location - starting SLC"); 
     [_locationMgr startMonitoringSignificantLocationChanges]; 
    } 
    else { 
     // 
    } 

    ... 

    [self.window makeKeyAndVisible]; 

    return YES; 
} 

- (void)startSignificantChangeUpdates 
{ 
    // Create the location manager if this object does not 
    // already have one. 
    if (nil == _locationMgr) { 
     _locationMgr = [[CLLocationManager alloc] init]; 
     _locationMgr.delegate = self; 
    } 

    [CLLocationManager significantLocationChangeMonitoringAvailable]; 

    [_locationMgr startMonitoringSignificantLocationChanges]; 

    deviceNotFoundAlertController = [UIAlertController alertControllerWithTitle:@"START" message:@"startSignificantChangeUpdates called" preferredStyle:UIAlertControllerStyleAlert]; 

} 

-(void)locationManger:(CLLocationManager *)manager didFailWithError:(NSError *)error { 
    NSLog(@"didFailWithError: %@", error); 
} 

// Delegate method from the CLLocationManagerDelegate protocol. 
- (void)locationManager:(CLLocationManager *)manager 
     didUpdateLocations:(NSArray *)locations { 

    // If it's a relatively recent event, turn off updates to save power. 
    CLLocation* location = [locations lastObject]; 
    NSDate* eventDate = location.timestamp; 
    NSTimeInterval howRecent = [eventDate timeIntervalSinceNow]; 
    if (fabs(howRecent) < 15.0) { 
     // If the event is recent, do something with it. 
     NSLog(@"latitude %+.6f, longitude %+.6f\n", 
       location.coordinate.latitude, 
       location.coordinate.longitude); 
    } 
} 
2

它與您的委託方法有問題請及時與

- (void)locationManager:(CLLocationManager *)manager 
     didUpdateLocations:(NSArray *)locations { 
} 

希望它會幫助你更換一個下面

- (void)_locationManager:(CLLocationManager *)manager 
     didUpdateLocations:(NSArray *)locations { 
} 

+0

awesome catch ....都是因爲find + replace。 ..我會盡快嘗試,謝謝 – ewizard

+0

我做了改變 - 但我仍然沒有得到任何警報。另外,我不應該從'startSignificantChangeUpdates'得到警報嗎? – ewizard

+0

我可能已經得到它的工作,我需要再次測試......一個主要問題是,我從來沒有實例化'deviceNotFoundAlert' – ewizard

1
You have written write code, Just add below delegate method in your code. But startMonitoringSignificantLocationChanges for updating location take 10 to 20 min. and also trigger if location channel change. 

-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations 
{ 

} 
1

[_locationMgr startMonitoringSignificantLocationChanges];

重大更改位置服務僅在設備的位置發生重大變化(例如500米或更高)時纔會提供更新。

因此,當您的設備移動超過500米時,您的委託方法會每次調用一次。

確保您的應用具有後臺位置權限。

如果您的應用程序在後臺或前臺,那麼它將調用委託方法 否則應用程序將在AppDelegate文件中啓動位置選項,您必須創建位置管理器對象並再次啓動位置以獲取新位置。

https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/LocationAwarenessPG/CoreLocation/CoreLocation.html

+0

我有背景權限,它不能在500m +後工作 - 我的代碼看起來是否正確? – ewizard

+0

在位置委託方法中調用本地通知,確保新的委託方法。並移動約2公里。它說500+米不叫精確500米,有時需要更多的距離取決於網絡服務。所以你可以識別。它的工作我測試了它 –

相關問題