2013-04-18 37 views
5

Tôi bắt đầu cập nhật vị trí hiện tại khi chế độ xem xuất hiện và dừng cập nhật vị trí bất cứ khi nào locationManager:didUpdateLocations: được gọi. Nhưng tại sao locationManager:didUpdateLocations: luôn được gọi nhiều lần? Tôi đã bỏ lỡ điều gì?locationManager: didUpdateLocations: luôn được gọi nhiều lần

#import "ViewController.h" 

@interface ViewController(){ 
    CLLocationManager *locationManager; // location manager for current location 
} 
@end 

@implementation ViewController 
- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
} 

- (void)viewDidAppear:(BOOL)animated 
{ 
    [super viewDidAppear:animated]; 
    [self startUpdatingCurrentLocation]; 
} 

- (void)startUpdatingCurrentLocation 
{ 
    if (!locationManager) 
    { 
     locationManager = [[CLLocationManager alloc] init]; 
     [locationManager setDelegate:self]; 
     locationManager.distanceFilter = 10.0f; // we don't need to be any more accurate than 10m 
    } 
    [locationManager startUpdatingLocation]; 
} 

-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{ 
    [locationManager stopUpdatingLocation]; 
} 
@end 
+0

http://stackoverflow.com/questions/22292835/how-to-stop -multiple-times-method-calling-of-didupdatelocations-in-ios – Sanju

Trả lời

7

Có thể nó phụ thuộc vào độ chính xác mà bạn đặt cho locationManager. Bạn có 3 loại o nội địa hóa Radio di động, bản đồ WiFi, GPS. Nếu bạn đặt độ chính xác cao nhất thì trình quản lý vị trí sẽ tiếp tục kiểm tra vị trí của bạn, nếu vị trí có độ chính xác tốt hơn nằm ngoài phạm vi của bộ lọc khoảng cách thì phương thức ủy nhiệm sẽ được gọi lại.

+0

lý do [locationManager stopUpdatingLocat ion] không thể ngừng cập nhật vị trí ngay lập tức? –

+1

Có thể không, vì hàng đợi vị trí xuất phát từ bộ đệm phần cứng, nhưng nếu vấn đề là giải pháp đơn giản chỉ cần thêm BOOL tĩnh trước khi bạn dừng và kiểm tra nó. Nếu BOOL của bạn nói rằng bạn đã dừng lại chỉ cần quay trở lại từ phương pháp đó. – Andrea

+0

Vâng, đó là một giải pháp. –

3

SWIFT phiên bản

tôi đã thực hiện một lớp helper như HelperLocationManager và thêm một mẫu notification- observer

import UIKit 
import CoreLocation 



class HelperLocationManager: NSObject { 

    var locationManager = CLLocationManager() 
    static let sharedInstance = HelperLocationManager() 
    var currentLocation :CLLocation? 
    var notGotUserLocation = true 

    override init() { 

     super.init() 

     var code = CLLocationManager.authorizationStatus() 

     if code == CLAuthorizationStatus.NotDetermined { 

      locationManager.requestAlwaysAuthorization() 
      locationManager.requestWhenInUseAuthorization() 

     } 
     locationManager.requestAlwaysAuthorization() 
     locationManager.requestWhenInUseAuthorization() 
     locationManager.delegate = self 
     locationManager.distanceFilter = 100; 

    } 


} 


extension HelperLocationManager: CLLocationManagerDelegate{ 


    func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) { 

      var locValue = locations.last as! CLLocation 
      println(locValue) 
      self.currentLocation = locValue 
      NSNotificationCenter.defaultCenter().postNotificationName("sendCurrentAddressToViewController", object:self.currentLocation) 
      notGotUserLocation = false 


    } 

    func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) { 

     println("Your error is ", error.localizedDescription) 

    } 


} 

Bây giờ nếu lớp Viewcontroller của bạn cần vị trí sau đó đưa một người quan sát có

var helperLocation:HelperLocationManager? 

trong viewDidLoad

 override func viewDidLoad() { 

     helperLocation = HelperLocationManager() 
     NSNotificationCenter.defaultCenter().addObserver(self, selector: "getCurrentAddressToViewController:", name: "sendCurrentAddressToViewController", object: nil) 

    } 

// và quan sát viên như

func getCurrentAddressToViewController(notification: NSNotification) { 

     currentLocation = notification.object as? CLLocation 
     NSNotificationCenter.defaultCenter().removeObserver(self, name: "sendCurrentAddressToViewController", object: nil) 

    } 

// mặc dù didUpdateLocation được gọi là nhiều lần bạn chỉ có được một vị trí thời gian bởi vì loại bỏ observer sau khi bạn có được vị trí.

EDIT: Tôi refractored lớp helper này để bạn không cần phải thêm notificationobserver mẫu

class HelperLocationManager: NSObject { 

    private lazy var locationManager = CLLocationManager() 
    static let sharedInstance = HelperLocationManager() 
    var currentLocation :CLLocation? 

    override init() { 

     super.init() 
     locationManager.desiredAccuracy = kCLLocationAccuracyBest 
     locationManager.delegate = self 
    } 
} 

extension HelperLocationManager: CLLocationManagerDelegate{ 

    func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) { 

     switch status { 

     case CLAuthorizationStatus.NotDetermined: 

      locationManager.requestWhenInUseAuthorization() 


     case CLAuthorizationStatus.Restricted: 

      PrinterHelper.messagePrinter("Restricted Access to location") 

     case CLAuthorizationStatus.Denied: 

      PrinterHelper.messagePrinter("User denied access to location") 

     case CLAuthorizationStatus.AuthorizedWhenInUse: 

      if #available(iOS 9.0, *) { 

       locationManager.requestLocation() 

      } else { 

       locationManager.startUpdatingLocation() 
      } 

     default: 

      PrinterHelper.messagePrinter("default authorization") 

     } 
    } 

    func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { 

     let locValue = locations.last 
     HelperLocationManager.sharedInstance.currentLocation = locValue 
     locationManager.stopUpdatingLocation() 

    } 

    func locationManager(manager: CLLocationManager, didFailWithError error: NSError) { 

     PrinterHelper.errorPrinter(error.localizedDescription) 

    } 
} 

View Controller mà bạn cần để có được sử dụng Giấy phép

var helperLocationManager:HelperLocationManager? 

trong viewDidLoad như

 override func viewDidLoad() { 

     helperLocationManager = HelperLocationManager.sharedInstance 


    } 

Và để có được những vị trí bạn cần phải gọi là tài sản singleton currentLocation như

if let userCurentLoc = HelperLocationManager.sharedInstance.currentLocation{ 

      //userCurrentLoc is the user Location 

     } 
0

Để bổ sung về câu trả lời Anish, nếu bạn muốn biết khi nào lớp helper của bạn đã không gọi cho các cập nhật vị trí (ví dụ: khi bạn đã tắt dịch vụ định vị của bạn), bạn có thể quản lý này sử dụng phương pháp locationManager:didChangeAuthorizationStatus:, và nếu vị trí của bạn không được phép, bạn có thể gọi khác notification- observer

func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) { 
    var shouldIAllow = false 

    switch status { 
    case CLAuthorizationStatus.Restricted: 
     locationStatus = "Restricted Access to location" 
    case CLAuthorizationStatus.Denied: 
     locationStatus = "User denied access to location" 
    case CLAuthorizationStatus.NotDetermined: 
     locationStatus = "Status not determined" 
    default: 
     locationStatus = "Allowed to location Access" 
     shouldIAllow = true 
    } 

    if (shouldIAllow == true) { 
     print("Location to Allowed") 
     // Start location services 
     locationManager!.startUpdatingLocation() 
    } else { 
     print("Denied access: \(locationStatus)") 
     NSNotificationCenter.defaultCenter().postNotificationName("deniedLocation", object:locationStatus) 
    } 
} 
Các vấn đề liên quan