2

ナビゲーションバーのlocateButtonが任意のビューで押された後、すべてのビューでユーザーの場所を更新したい。シングルトンを作成することから始めました。

Location.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

Location.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 とビュー コントローラーでそれらをどのように実装しますか? ありがとう。

4

2 に答える 2

3

私がすることは、オブザーバーパターンを使用することです。シングルトンではNSMutableArray、すべてのオブザーバーを保持します。

NSMutableArray *observers;

すべてのオブザーバーが準拠するプロトコルが必要になります。

@protocol LocationObserver <NSObject>

- (void)locationDidChange:(CLLocation *)updatedLocation;

@end

そして、場所が変わったらこれを行うだけです

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

addObserver メソッドと removeObserver メソッドも必要です。これらのメソッドは、 を取り、id<LocationObserver>それを配列に追加/削除します。

于 2013-04-09T23:12:52.483 に答える
0

これが私がやったことであり、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)")
    }

}
于 2016-04-12T01:19:17.927 に答える