现在的位置: 首页 > 综合 > 正文

CLLocationManager用法示例

2013年12月20日 ⁄ 综合 ⁄ 共 5047字 ⁄ 字号 评论关闭

MyCLController.h

#import <CoreLocation/CoreLocation.h>
// This is hoping that in the future (beyond SDK 2.0) we can access SystemConfiguration info
#import <SystemConfiguration/SCNetworkConnection.h>

// This protocol is used to send the info for location updates back to another view controller
@protocol MyCLControllerDelegate <NSObject>
@required
-(void)gpsUpdate:(CLLocation *)aLoc;
@end


// Class definition
@interface MyCLController : NSObject <CLLocationManagerDelegate> {
	CLLocationManager *locationManager;
	CLLocation *myCurrentLoc;
	BOOL findShouldStop;
	id delegate;
}

@property (nonatomic, retain) CLLocationManager *locationManager;
@property (nonatomic,assign) id <MyCLControllerDelegate> delegate;
@property (nonatomic, assign) CLLocation *myCurrentLoc;

- (void)locationManager:(CLLocationManager *)manager
	didUpdateToLocation:(CLLocation *)newLocation
		   fromLocation:(CLLocation *)oldLocation;

- (void)locationManager:(CLLocationManager *)manager
	   didFailWithError:(NSError *)error;

+ (MyCLController *)sharedInstance;

@end

MyCLController.m

#import "MyCLController.h"

// This is a singleton class, see below
static MyCLController *sharedCLDelegate = nil;

@implementation MyCLController

@synthesize delegate, locationManager, myCurrentLoc;

- (id) init {
	
	self = [super init];
	if (self != nil) {
		self.locationManager = [[CLLocationManager alloc] init];
		self.locationManager.delegate = self; // Tells the location manager to send updates to this object
		self.myCurrentLoc = [[CLLocation alloc] initWithLatitude:0 longitude:0];
		[self.locationManager startUpdatingLocation];
	}
	return self;
}

// Called when the location is updated
- (void)locationManager:(CLLocationManager *)manager
    didUpdateToLocation:(CLLocation *)newLocation
           fromLocation:(CLLocation *)oldLocation
{	
		
	// Horizontal coordinates
	if (signbit(newLocation.horizontalAccuracy)) {
		// Negative accuracy means an invalid or unavailable measurement
		[self.delegate gpsUpdate:nil];
		return;
	}
    
	//	// Altitude (we don't care about it)
	//	if (signbit(newLocation.verticalAccuracy)) {
	//		// Negative accuracy means an invalid or unavailable measurement
	//	}
    
	// Check the timestamp, see if it's an hour old or more. If so, don't send an update
	if (ABS([newLocation.timestamp timeIntervalSinceNow]) > 3600) {
		[self.delegate gpsUpdate:nil];
		return;
	}
	
	[myCurrentLoc release];
    myCurrentLoc = [newLocation copy]; // TODO: Why does this increment the retain count? We should be manually retaining
	
	// Looks like the loc is good
	[self.delegate gpsUpdate:myCurrentLoc];
	return;
}

// Called when there is an error getting the location
// TODO: Update this function to return the proper info in the proper UI fields
- (void)locationManager:(CLLocationManager *)manager
       didFailWithError:(NSError *)error
{
	
	NSMutableString *errorString = [[[NSMutableString alloc] init] autorelease];
	BOOL shouldQuit;
    
	if ([error domain] == kCLErrorDomain) {
        
		// We handle CoreLocation-related errors here
        
		switch ([error code]) {
                // This error code is usually returned whenever user taps "Don't Allow" in response to
                // being told your app wants to access the current location. Once this happens, you cannot
                // attempt to get the location again until the app has quit and relaunched.
                //
                // "Don't Allow" on two successive app launches is the same as saying "never allow". The user
                // can reset this for all apps by going to Settings > General > Reset > Reset Location Warnings.
                //
			case kCLErrorDenied:
				[errorString appendFormat:@"%@\n", NSLocalizedString(@"LocationDenied", nil)];
				[errorString appendFormat:@"%@\n", NSLocalizedString(@"AppWillQuit", nil)];
				shouldQuit = YES;
				break;
                
                // This error code is usually returned whenever the device has no data or WiFi connectivity,
                // or when the location cannot be determined for some other reason.
                //
                // CoreLocation will keep trying, so you can keep waiting, or prompt the user.
                //
			case kCLErrorLocationUnknown:
				[errorString appendFormat:@"%@\n", NSLocalizedString(@"LocationUnknown", nil)];
				[errorString appendFormat:@"%@\n", NSLocalizedString(@"AppWillQuit", nil)];
				shouldQuit = YES;
				break;
                
                // We shouldn't ever get an unknown error code, but just in case...
                //
			default:
				[errorString appendFormat:@"%@ %d\n", NSLocalizedString(@"GenericLocationError", nil), [error code]];
				shouldQuit = NO;
				break;
		}
	} else {
		// We handle all non-CoreLocation errors here
		// (we depend on localizedDescription for localization)
		[errorString appendFormat:@"Error domain: \"%@\"  Error code: %d\n", [error domain], [error code]];
		[errorString appendFormat:@"Description: \"%@\"\n", [error localizedDescription]];
		shouldQuit = NO;
	}
    
	// TODO: Send the delegate the alert?
	if (shouldQuit) {
		// do nothing
	}
}

#pragma mark ---- singleton object methods ----

// See "Creating a Singleton Instance" in the Cocoa Fundamentals Guide for more info

+ (MyCLController *)sharedInstance {
    @synchronized(self) {
        if (sharedCLDelegate == nil) {
            [[self alloc] init]; // assignment not done here
        }
    }
    return sharedCLDelegate;
}

+ (id)allocWithZone:(NSZone *)zone {
    @synchronized(self) {
        if (sharedCLDelegate == nil) {
            sharedCLDelegate = [super allocWithZone:zone];
            return sharedCLDelegate;  // assignment and return on first allocation
        }
    }
    return nil; // on subsequent allocation attempts return nil
}

- (id)copyWithZone:(NSZone *)zone
{
    return self;
}

- (id)retain {
    return self;
}

- (unsigned)retainCount {
    return UINT_MAX;  // denotes an object that cannot be released
}

- (void)release {
    //do nothing
}

- (id)autorelease {
    return self;
}

@end

在用MKReverseGeocoder的时候是不是经常crash呀,那是因为在同一时刻只能存在一个MKReverseGeocoder实例。

参考资料:

http://evilrockhopper.com/2010/01/iphone-development-reverse-geocoding/

http://www.iphonedevsdk.com/forum/iphone-sdk-development/31883-pbrequestererrordomain-errors-reverse-geocoding.html

抱歉!评论已关闭.