2015-05-17 15 views
8

Tôi đã không thể tìm ra cách xử lý một tình huống mà điện thoại đã ở trong một khu vực khi gọi startMonitoringForRegion? Các câu hỏi khác đã đề xuất gọi requestStateForRegion bên trong didStartMonitoringForRegion điều này sau đó gọi phương thức didDetermineState: forRegion:. Vì vậy, các mã trông giống như sau:iOS Geofence, cách xử lý khi bên trong khu vực khi bắt đầu theo dõi?

- (void)viewDidLoad { 
    //location manager set up etc... 
    for (Object *object in allObjects){ 

     CLRegion *region = [self geofenceRegion:object]; 
     [locationManager startMonitoringForRegion:region]; 
    } 
} 

- (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region { 

    [self.locationManager requestStateForRegion:region]; 
    [self.locationManager performSelector:@selector(requestStateForRegion:) withObject:region afterDelay:5]; 
} 

- (void)locationManager:(CLLocationManager *)manager 
    didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region { 

    if (state == CLRegionStateInside){ 
     [self locationManager:locationManager didEnterRegion:region]; 
    } 
} 

Bây giờ rõ ràng là phương pháp geofenceRegion là của riêng của tôi và nó hoạt động tốt, và các đối tượng có chứa những thứ như lat dài và bán kính và rằng tất cả hoạt động tốt cũng vì vậy đó không phải là vấn đề ở đây.

Dù sao, vấn đề với mã ở trên là nó hoạt động nếu người dùng đã ở trong khu vực khi nó thêm vùng vào thiết bị của họ (ví dụ: didEnterRegion được thực hiện). Tuy nhiên vấn đề là phương pháp didDetermineState: forRegion: còn được gọi là mỗi khi một trong những vùng ranh giới được vượt theo các tài liệu táo:

Vị trí giám đốc gọi phương pháp này bất cứ khi nào có một sự chuyển đổi ranh giới cho một khu vực. Nó gọi phương thức này ngoài việc gọi phương thức locationManager: didEnterRegion: và locationManager: didExitRegion: các phương thức. Trình quản lý vị trí cũng gọi phương thức này để đáp ứng lời gọi đến phương thức requestStateForRegion: của nó, chạy không đồng bộ.

Bây giờ vì điều này mỗi khi một khu vực được nhập vào, didEnterRegion được tự động gọi nhưng sau đó nó được gọi là một lần nữa bởi vì didDetermineState: forRegion: cũng được tự động gọi theo các tài liệu táo và kết quả này trong didEnterRegion được gọi lần nữa để khu vực này là nhập hai lần khi tôi chỉ muốn nó được nhập một lần. Làm thế nào tôi có thể tránh điều này?

Cảm ơn sự giúp đỡ của bạn.

SOLUTION

Các giải pháp thực sự là đơn giản như vậy tôi chỉ cần đi về nó một cách sai lầm. Tôi phải chọn sử dụng 2 phương pháp didEnterRegion:didExitRegion hoặc sử dụng didDetermineState: forRegion và tạo phương pháp riêng để nhập và thoát khỏi khu vực, cả hai không được sử dụng.

Vì vậy, tôi đã chọn để chỉ sử dụng phương pháp didDetermineState: forRegion và mã của tôi bây giờ trông như thế này:

Xin lưu ý rằng với khu vực lối ra phương pháp này sẽ được gọi là đối với khu vực nếu không phải bên trong và nếu, như tôi, bạn chỉ muốn thoát ra sau khi một lần nhập đã xảy ra, bạn sẽ cần một số phương pháp kiểm tra nếu vùng đã được nhập (bản thân tôi đã sử dụng dữ liệu cốt lõi vì tôi đã sử dụng nó để lưu trữ các khía cạnh khác của vùng).

- (void)viewDidLoad { 
    //location manager set up etc... 
    for (Object *object in allObjects){ 

     CLRegion *region = [self geofenceRegion:object]; 
     [locationManager startMonitoringForRegion:region]; 
    } 
} 

- (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region { 

    [self.locationManager performSelector:@selector(requestStateForRegion:) withObject:region afterDelay:5]; 
} 

- (void)locationManager:(CLLocationManager *)manager 
    didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region { 

    if (state == CLRegionStateInside){ 

     [self enterGeofence:region]; 

    } else if (state == CLRegionStateOutside){ 

     [self exitGeofence:region]; 

    } else if (state == CLRegionStateUnknown){ 
     NSLog(@"Unknown state for geofence: %@", region); 
     return; 
    } 
} 

- (void)enterGeofence:(CLRegion *)geofence { 

    //whatever is required when entered 
} 

- (void)exitGeofence:(CLRegion *)geofence { 

    //whatever is required when exit 
} 
+0

Tùy thuộc vào [meta post] này (https://meta.stackoverflow.com/q/262806/5175709). Tốt hơn là không đưa câu trả lời vào chính câu hỏi đó. Hoặc là viết một câu trả lời riêng hoặc chỉ chấp nhận câu trả lời cho trước hoặc viết bình luận. – Honey

Trả lời

4

Chỉ cần không sử dụng locationManager: didEnterRegion: ở tất cả, như locationManager: didDetermineState: forRegion: cung cấp cho bạn tất cả các thông tin mà bạn cần phải kích hoạt mã trên nhập cảnh, trong đó, bằng cách này , không được là locationManager: didEnterRegion:, sử dụng công cụ chọn của riêng bạn, không phải là một phần của CLLocationManagerGiao thức.

Một cách tiếp cận khác là kiểm tra bên trong một vị trí khu vực khi bắt đầu theo dõi một khu vực.Tuy nhiên, bạn cần phải cập nhật vị trí hiện tại bằng cách gọi startUpdatingLocation, vì chỉ đọc thuộc tính vị trí của locationManager có thể sẽ cho bạn đọc cũ hoặc cực kỳ không chính xác.

+0

Whats điểm của API nếu tôi phải theo dõi nó bản thân mình mặc dù? điều đó có vẻ không hợp lý chút nào? –

+0

Mô tả API nêu rõ rằng nó giám sát các sự kiện vào và ra. Bạn muốn nhận được nhiều hơn API, cụ thể là sự kiện nhập cảnh khi bắt đầu theo dõi từ bên trong một khu vực. Có một API gọi lại mức thấp hơn cho điều đó, locationManager: didDetermineState: forRegion: và bạn có thể sử dụng nó, nhưng cố gắng kết hợp nó với các công cụ mức cao hơn là yêu cầu một sự cố. –

+0

Nhưng như tôi đã đề cập trong câu hỏi của tôi didDetermineState cũng được kích hoạt khi một khu vực được nhập hoặc thoát. Vì vậy, những gì bạn đang nói là tôi phải tự nhận vị trí hiện tại khi tôi bắt đầu theo dõi một khu vực và nếu vị trí hiện tại này nằm trong khu vực tôi tự xử lý nó. Bỏ qua requestStateForRegion ?. Tôi khiến tôi không thể nghĩ ra điều gì khác bạn sẽ sử dụng requestStateForRegion nếu không sử dụng theo dõi vùng –

Các vấn đề liên quan