2015-01-02 19 views
30

Vào đầu năm 2014, Apple đã cập nhật iOS 7.0 lên 7.1 để cho phép cập nhật vị trí ngay cả khi ứng dụng không hoạt động trên nền trước và không ở chế độ nền. làm sao chúng ta làm việc đó bây giờ?Nhận cập nhật vị trí cho ứng dụng iOS Ngay cả khi bị tạm ngưng

Tôi đã đọc một số bài viết như Apple's iOS 7.1 will fix a geolocation bug. Nhưng Apple đã không cung cấp nhiều thông tin liên lạc liên quan đến đó cũng như bất kỳ mã mẫu nào về cách cập nhật vị trí ngay cả khi ứng dụng bị giết/chấm dứt/tạm ngưng.

Tôi đã đọc số Release Notes for iOS 7.1. Tôi không thể tìm thấy bất cứ điều gì liên quan đến điều đó là tốt.

Vậy, làm cách nào để chúng tôi thực sự cập nhật vị trí cho iOS 7 và 8 ngay cả khi ứng dụng bị tạm ngưng?

Trả lời

73

Sau nhiều tháng thử nghiệm và lỗi bằng cách thử nghiệm Vị trí cốt lõi Framework, tôi đã tìm thấy giải pháp để cập nhật vị trí ngay cả khi ứng dụng bị giết/tạm ngừng. Nó hoạt động tốt cho cả iOS 7 và 8.

Dưới đây là giải pháp: -

Nếu ứng dụng của bạn là một vị trí dựa trên ứng dụng di động mà cần phải theo dõi vị trí của thiết bị khi nó có thay đổi đáng kể, iOS sẽ trả lại cho bạn một số tọa độ vị trí khi thiết bị đã di chuyển hơn 500 mét từ vị trí đã biết cuối cùng. Có, ngay cả khi ứng dụng bị giết/tạm ngưng bởi chính người dùng hoặc iOS, bạn vẫn có thể nhận được các cập nhật vị trí.

Vì vậy, để có được locationManager để nhận cập nhật vị trí ngay cả khi ứng dụng bị giết/tạm ngưng, bạn phải sử dụng phương pháp startMonitoringSignificantLocationChanges, bạn không thể sử dụng startUpdatingLocation.

Khi iOS muốn trả về cập nhật vị trí cho ứng dụng, ứng dụng sẽ giúp bạn khởi chạy lại ứng dụng và trả lại khóa UIApplicationLaunchOptionsLocationKey cho phương thức ủy nhiệm ứng dụng didFinishLaunchingWithOptions.

Khoá UIApplicationLaunchOptionsLocationKey là rất quan trọng và bạn phải biết cách xử lý. Bạn phải tạo một cá thể locationManager mới khi bạn nhận được khóa và bạn sẽ nhận được cập nhật vị trí trên phương thức ủy nhiệm locationManager didUpdateLocations.

Đây là đoạn mã mẫu: -

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ 
    self.shareModel = [LocationShareModel sharedModel]; 

    if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey]) { 
     self.shareModel.anotherLocationManager = [[CLLocationManager alloc]init]; 
     self.shareModel.anotherLocationManager.delegate = self; 
     self.shareModel.anotherLocationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation; 
     self.shareModel.anotherLocationManager.activityType = CLActivityTypeOtherNavigation; 

     if(IS_OS_8_OR_LATER) { 
     [self.shareModel.anotherLocationManager requestAlwaysAuthorization]; 
     } 

    [self.shareModel.anotherLocationManager startMonitoringSignificantLocationChanges]; 

    }  
     return YES; 
} 

Ngoài các phương pháp didFinishLaunchingWithOptions, tôi đã tạo ra thể hiện locationManager khi ứng dụng đang hoạt động. Dưới đây là một số ví dụ mã:

- (void)applicationDidEnterBackground:(UIApplication *)application 
{ 
    [self.shareModel.anotherLocationManager stopMonitoringSignificantLocationChanges]; 

    if(IS_OS_8_OR_LATER) { 
     [self.shareModel.anotherLocationManager requestAlwaysAuthorization]; 
    } 

    [self.shareModel.anotherLocationManager startMonitoringSignificantLocationChanges]; 
} 

- (void)applicationDidBecomeActive:(UIApplication *)application 
{ 
    if(self.shareModel.anotherLocationManager) 
     [self.shareModel.anotherLocationManager stopMonitoringSignificantLocationChanges]; 

    self.shareModel.anotherLocationManager = [[CLLocationManager alloc]init]; 
    self.shareModel.anotherLocationManager.delegate = self; 
    self.shareModel.anotherLocationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation; 
    self.shareModel.anotherLocationManager.activityType = CLActivityTypeOtherNavigation; 

    if(IS_OS_8_OR_LATER) { 
     [self.shareModel.anotherLocationManager requestAlwaysAuthorization]; 
    } 

    [self.shareModel.anotherLocationManager startMonitoringSignificantLocationChanges]; 
} 

Tôi đã viết một bài viết giải thích chi tiết về cách cập nhật vị trí cho iOS 7 và 8 ngay cả khi ứng dụng bị giết/tạm ngưng. Tôi cũng đã tải lên mã nguồn hoàn chỉnh trên GitHub với các bước về cách kiểm tra giải pháp này.

Vui lòng truy cập các URL sau để biết thêm thông tin: -

  1. Getting Location Updates for iOS 7 and 8 when the App is Killed/Terminated/Suspended
  2. Source Code on GitHub - Get the Location Updates Even when the iOS mobile apps is Suspended/Terminated/Killed
+1

"Bạn phải tạo một vị trí mớiManager khi bạn nhận được khóa" - âm thanh hơi khó hiểu, bạn có ý định chính xác "phiên bản locationManager MỚI" không? Tôi có một ví dụ được chia sẻ về locationManager trong dự án của tôi - tôi có thể sử dụng lại nó không? –

+5

Câu hỏi hay. Khi ứng dụng bị tạm ngưng, vị trí được chia sẻQuản lý mà bạn đã tạo trước đó cũng sẽ bị xóa khỏi bộ nhớ. Làm thế nào để bạn tái sử dụng một cá thể không tồn tại trong bộ nhớ? Vì vậy, việc tạo một cá thể mới là cách duy nhất. – Ricky

+0

Xin chào Ricky, câu trả lời tuyệt vời. Chỉ một câu hỏi: Phương pháp tương tự có thể được áp dụng cho người quản lý vị trí chuẩn chứ không chỉ với người quản lý vị trí thay đổi đáng kể? – Pacemaker

0
locationManager = [[CLLocationManager alloc] init]; 
#define IS_OS_8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) 


if(IS_OS_8_OR_LATER) 
{ 
    [locationManager requestWhenInUseAuthorization]; 
} 

locationManager.delegate = self; 
locationManager.distanceFilter = kCLDistanceFilterNone; //whenever we move 
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters; 

[locationManager startUpdatingLocation]; 

rằng mã vị trí người dùng cập nhật chỉ forground ứng dụng đang chạy nhưng không chạy nền

[locationManager requestWhenInUseAuthorization]; 
Các vấn đề liên quan