【问题标题】:singleton for location updating multiple views用于位置更新多个视图的单例
【发布时间】:2013-04-09 21:50:44
【问题描述】:

在任何视图中按下导航栏中的 locateButton 后,我想在所有视图中更新用户位置。我从创建一个单例开始。

位置.h

#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
#import <MapKit/MapKit.h>

@interface Location : NSObject <CLLocationManagerDelegate>

@property (nonatomic, strong) CLLocationManager* locationManager;

+ (Location*)sharedSingleton;

@end

位置.m

#import "Location.h"

@implementation Location {
    CLLocationManager *locationManager;
    CLGeocoder *geocoder;
    CLPlacemark *placemark;
}


@synthesize locationManager;

- (id)init {
    self = [super init];

    if(self) {
        self.locationManager = [CLLocationManager new];
        [self.locationManager setDelegate:self];
        [self.locationManager setDistanceFilter:kCLDistanceFilterNone];
        [self.locationManager setHeadingFilter:kCLHeadingFilterNone];
        [self.locationManager startUpdatingLocation];
        self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
        //do any more customization to your location manager
    }

    return self;
}

+ (Location*)sharedSingleton {
    static Location* sharedSingleton;
    if(!sharedSingleton) {
        @synchronized(sharedSingleton) {
            sharedSingleton = [Location new];
        }
    }

    return sharedSingleton;
}

#pragma mark - CLLocationManagerDelegate

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
    NSLog(@"didFailWithError: %@", error);
    UIAlertView *errorAlert = [[UIAlertView alloc]
                               initWithTitle:@"Error" message:@"Failed to Get Your Location" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [errorAlert show];
}

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
    NSLog(@"didUpdateToLocation: %@", newLocation);

    CLLocation *currentLocation = newLocation;

    if (currentLocation != nil) {
        latLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.longitude];
        longLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.latitude];
    }

    // Stop Location Manager
    [locationManager stopUpdatingLocation];

    // Reverse Geocoding
    NSLog(@"Resolving the Address");
    [geocoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placemarks, NSError *error) {
        NSLog(@"Found placemarks: %@, error: %@", placemarks, error);
        if (error == nil && [placemarks count] > 0) {
            placemark = [placemarks lastObject];
            addressLabel.text = [NSString stringWithFormat:@"%@, %@",
                                 placemark.locality,
                                 placemark.administrativeArea];
            addressLabel.numberOfLines = 0;



        } else {
            NSLog(@"%@", error.debugDescription);
        }
    } ];

}

@end

当在当前视图中按下顶部导航栏中的 locationButton 时,我想使用它来更新每个视图上的用户纬度和经度。

- (IBAction)locationPressed:(id)sender { 

    [[Location sharedSingleton].locationManager startUpdatingLocation];

}

NSNotifications 会是最好的吗?如果是这样,我将如何在 Location.m 和视图控制器中实现它们?谢谢。

【问题讨论】:

    标签: ios singleton cllocationmanager nsnotificationcenter


    【解决方案1】:

    我会做的是使用观察者模式。在你的单例中,保留所有观察者的NSMutableArray

    NSMutableArray *observers;
    

    您需要一个所有观察者都遵守的协议:

    @protocol LocationObserver <NSObject>
    
    - (void)locationDidChange:(CLLocation *)updatedLocation;
    
    @end
    

    然后当位置改变时就这样做

    for (id<LocationObserver> observer in observers) {
        [observer locationDidChange:newLocation];
    }
    

    您还应该有一个 addObserver 和 removeObserver 方法,它们采用 id&lt;LocationObserver&gt; 并从数组中添加/删除它。

    【讨论】:

    • 谢谢,我会试一试。
    • CLLocation 应该是 CLLocation*
    • 这对你有什么好处@jacobt?
    【解决方案2】:

    这是我所做的,您可以在 github https://github.com/irfanlone/CLLocationManager-Singleton-Swift 上找到完整的示例

    只需将此文件导入您的项目,然后您可以选择实现 LocationUpdateProtocol 或收听位置更新通知

    import MapKit
    
    protocol LocationUpdateProtocol {
        func locationDidUpdateToLocation(location : CLLocation)
    }
    
    /// Notification on update of location. UserInfo contains CLLocation for key "location"
    let kLocationDidChangeNotification = "LocationDidChangeNotification"
    
    class UserLocationManager: NSObject, CLLocationManagerDelegate {
    
        static let SharedManager = UserLocationManager()
    
        private var locationManager = CLLocationManager()
    
        var currentLocation : CLLocation?
    
        var delegate : LocationUpdateProtocol!
    
        private override init () {
            super.init()
            self.locationManager.delegate = self
            self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
            self.locationManager.distanceFilter = kCLLocationAccuracyHundredMeters
            locationManager.requestAlwaysAuthorization()
            self.locationManager.startUpdatingLocation()
        }
    
        // MARK: - CLLocationManagerDelegate
    
        func locationManager(manager: CLLocationManager, didUpdateToLocation newLocation: CLLocation, fromLocation oldLocation: CLLocation) {
            currentLocation = newLocation
            let userInfo : NSDictionary = ["location" : currentLocation!]
    
            dispatch_async(dispatch_get_main_queue()) { () -> Void in
                self.delegate.locationDidUpdateToLocation(self.currentLocation!)
                NSNotificationCenter.defaultCenter().postNotificationName(kLocationDidChangeNotification, object: self, userInfo: userInfo as [NSObject : AnyObject])
            }
        }
    
    }
    

    用法:

    class ViewController: UIViewController, LocationUpdateProtocol {
    
        var currentLocation : CLLocation!
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            NSNotificationCenter.defaultCenter().addObserver(self, selector: "locationUpdateNotification:", name: kLocationDidChangeNotification, object: nil)
    
            let LocationMgr = UserLocationManager.SharedManager
            LocationMgr.delegate = self
    
        }
    
        // MARK: - Notifications
    
        func locationUpdateNotification(notification: NSNotification) {
            let userinfo = notification.userInfo
            self.currentLocation = userinfo!["location"] as! CLLocation
            print("Latitude : \(self.currentLocation.coordinate.latitude)")
            print("Longitude : \(self.currentLocation.coordinate.longitude)")
    
        }
    
        // MARK: - LocationUpdateProtocol
    
        func locationDidUpdateToLocation(location: CLLocation) {
            currentLocation = location
            print("Latitude : \(self.currentLocation.coordinate.latitude)")
            print("Longitude : \(self.currentLocation.coordinate.longitude)")
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多