0

I want my app to get current location when user taps a button. I initialize locationManager object in init method.

First question: is this good if I'm going to need currentlocation every time I press button? Or should I initialize it even in viewDidLoad?

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];

    if (self)
    {
        // Create location manager object
        locationManager = [[CLLocationManager alloc] init];
        locationManager.delegate = self;

        // Best accuracy as posibble
        [locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
    }
    return self;
}

In my delegate method I stopUpdatingLocation as soon as I got my currentLocation.

// Delegate method
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray        
*)locations   
{
    CLLocation *currentLocation = [locations lastObject];

    [locationManager stopUpdatingLocation];
}

Here I startUpdatingLocation with button:

- (IBAction)getCurrentLocation:(id)sender
{
    [locationManager startUpdatingLocation];
}

Second question is: when I press button 1st time, I get right location, but when I change location in simulator and press again it shows the 1st one. Again, when I press the button, then it shows the right one. I have tried to initialize locationManager every time button is pressed but it doesn't work that way neither.

I read on other post that its because of location cache or something like that. How do I remove that cache ? Because I'm going to store that location somewhere else in DB anyways so I don't need old one..

4

2 回答 2

1

init问题 1:我应该在 in还是 in初始化我的位置管理器viewDidLoad

我会选择viewDidLoad,只是因为这样可以确保所有依赖项都已加载。

问题2:用户位置没有被更新。

用户位置没有改变,因为您在第一次收到位置信息后停止收听位置更新:

[locationManager stopUpdatingLocation];

但是当用户按下getCurrentLocation按钮时,您会再次开始收听。如果您愿意,您仍然可以使用这种方法,但我会在getCurrentLocation操作中设置一个标志,以便在找到新位置时更新 UI。

例子:

// Delegate method
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray        
*)locations   
 {
     CLLocation *currentLocation = [locations lastObject];

     [locationManager stopUpdatingLocation];

     if (self.updateUIOnNextLocation) {
         [self updateUIWithLocation:currentLocation];
         self.updateUIOnNextLocation = NO;
     }
}

...

- (IBAction)getCurrentLocation:(id)sender
{
     self.updateUIOnNextLocation = YES;
     [locationManager startUpdatingLocation];
}
于 2013-04-17T23:03:44.340 回答
0

如果每次按下按钮只需要更新当前位置,为什么不创建一个单例类(下面显示基于 iOS 8 的示例),并缓存当前位置,然后添加一个在用户按下时调用的“重新触发”方法一个按钮,告诉位置管理器再次开始更新位置,缓存结果,然后关闭更新(再次)?这样,您就不会浪费资源来获取不必要的更新。您仍然必须以某种方式同步演示文稿,以便在位置尚不可用或当前不可用时显示或处理。

import Foundation
import CoreLocation

class CurrentLocation : NSObject, CLLocationManagerDelegate {

    enum InitPhase {
        case RequestingAuthorization, StartUpdatingLocation, ReverseGeocoding
    }

    var locationManager : CLLocationManager?
    var placemark : CLPlacemark?
    var initializationPhase : InitPhase = .RequestingAuthorization

    override init() {
        super.init()
        placemark = nil
        locationManager = CLLocationManager()
        locationManager!.delegate = self
        locationManager!.requestWhenInUseAuthorization()
    }

    func nonull(s : String?) -> String {
        if (s == nil) {
            return ""
        }
        return s!
    }

    // Handle all NSErrors here (not just from location manager)
    func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
        switch(initializationPhase) {
        case .RequestingAuthorization:
            println("CurrentLocation class - App not authorized by user to use location services")
        case .StartUpdatingLocation:
            println("CurrentLocation class - StartUpdatingLocation\n   ClLocationManager reported error to delegate:\n      \(error.localizedDescription)")
        case .ReverseGeocoding:
            println("CurrentLocation class - ReverseGeocoding\n   CLGeocoder().reverseGeocodeLocation() error:\n      \(error.localizedDescription)")
        default:
            println("CurrentLocation class - Unknown basis\n   ClLocationManager reported error to delegate:\n      \(error.localizedDescription)")

        }
    }

    func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
        if (status == .AuthorizedAlways || status == .AuthorizedWhenInUse) {
            println("CurrentLocation class - App authorized to use location services")
            initializationPhase = .StartUpdatingLocation
            locationManager!.startUpdatingLocation()
        } else {
            println("CurrentLocation class - App not authorized by user to use location services")

        }
    }

    func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
        var location = locations.last as CLLocation
        println("CurrentLocation class - CLLocation delagate received loocation update\n")
        locationManager?.stopUpdatingLocation()
        CLGeocoder().reverseGeocodeLocation(location, completionHandler: { (placemarks, error) in
            if (error == nil) {
                println("   Latitude/Longitude: \(location.coordinate.latitude) \(location.coordinate.longitude)")
                if placemarks.count > 0 {
                    self.placemark = CLPlacemark(placemark: placemarks[0] as CLPlacemark)
                    println(String(format:"   subThoroughfare:    %@\n   thoroughfare:       %@\n   locality:           %@\n   postalCode:         %@\n   administrativeArea: %@\n   country:            %@",
                                self.nonull(self.placemark!.subThoroughfare),
                                self.nonull(self.placemark!.thoroughfare),
                                self.nonull(self.placemark!.locality),
                                self.nonull(self.placemark!.postalCode),
                                self.nonull(self.placemark!.administrativeArea),
                                self.nonull(self.placemark!.country)))
                } else {
                    println("No placemarks located")
                }

            } else {
                self.locationManager(manager, didFailWithError: error)
            }
        })
    }
}
于 2014-12-29T16:44:56.613 回答