IOS development-CoreLocation location
Introduction
In the mobile Internet era, mobile apps can solve many things in users' lives, such
Navigation: Go to any unfamiliar location
Nearby: Looking for restaurants, hotels, banks, and cinemas
The map and positioning functions are used in the above applications. In iOS development, to add these two functions, the development must be based on the two frameworks.
Map Kit: used for Map Display
Core Location: used for geographic Location
2 Popular Terms
LBS: Location Based Service
SoLoMo: Social Local Mobile (suo Luo men)
Use of CoreLocation framework
Prerequisites for using CoreLocation framework
Import framework
Import the main header file
#import
Instructions for using CoreLocation framework
In the CoreLocation framework, the prefixes of all data types are CL.
Use the CLLocationManager object in CoreLocation for user locating
CLLocationManager
Common Operations of CLLocationManager // start user location-(void) startUpdatingLocation; // stop user location-(void) stopUpdatingLocation; // After the startUpdatingLocation method is called, the following method of the proxy is frequently called-(void) locationManager :( CLLocationManager *) manager didUpdateLocations :( NSArray *) locations; the locations parameter contains the CLLocation object @ property (assign, nonatomic) CLLocationDistance distanceFilter; // you can locate @ property (assign, nonatomic) CLLocationAccuracy desiredAccuracy once every several meters; // positioning accuracy (more accurate, more power consumption)
CLLocation
CLLocation is used to indicate the geographical information of a location, such as longitude and latitude, altitude, etc.
@ Property (readonly, nonatomic) CLLocationCoordinate2D coordinate; // latitude and longitude @ property (readonly, nonatomic) CLLocationDistance altitude; // elevation @ property (readonly, nonatomic) CLLocationDirection course; // route, course (value range: 0.0 ° ~ 359.9 °, 0.0 ° represents the true north direction) @ property (readonly, nonatomic) CLLocationSpeed speed; // use-(CLLocationDistance) for walking speed (unit: m/s) distanceFromLocation :( const CLLocation *) the distance between two locations can be calculated using the location method.
CLLocationCoordinate2D
CLLocationCoordinate2D is a struct used to represent the longitude and latitude. It is defined as follows: typedef struct {CLLocationDegrees latitude; // latitude CLLocationDegrees longpolling; // longitude} CLLocationCoordinate2D; // generally, longitude
User Privacy Protection
Since iOS 6, Apple has made great improvements in protecting user privacy. The following operations must be authorized by users:
To obtain the user's location
Users who want to access their address book, calendar, camera, album, etc.
When you want to access the user's privacy information, the system automatically displays a dialog box for user authorization.
Developers can set NSLocationUsageDescription in Info. plist to describe the positioning purpose (Privacy-Location Usage Description)
Once you select "Don't Allow", it means that your application will not be able to use the location function in the future.
For the sake of rigor, it is best to determine whether the positioning function of the current application is available before using the positioning function
// CLLocationManager has a class method to determine whether the positioning function of the current application is available
+ (BOOL) locationServicesEnabled;
CLGeocoder
CLGeocoder can be used to complete "geocoding" and "anti-geocoding"
Geographic code: obtains specific location information (such as longitude and latitude, and the full name of the address) based on the given place name)
Anti-Geographic Encoding: obtains the specific location information based on the given longitude and latitude.
// Geocoding method-(void) geocodeAddressString :( NSString *) addressString completionHandler :( CLGeocodeCompletionHandler) completionHandler; // anti-geocoding method-(void) reverseGeocodeLocation :( CLLocation *) location completionHandler :( CLGeocodeCompletionHandler) completionHandler;
CLGeocodeCompletionHandler
// When the geographic anti-geographic code is completed, CLGeocodeCompletionHandlertypedef void (^ CLGeocodeCompletionHandler) (NSArray * placemarks, NSError * error) is called. This block passes two parameter errors: when an Encoding Error occurs (for example, no specific information can be encoded), the value placemarks contains the CLPlacemark object.
Title
CLPlacemark literally refers to a landmark, which encapsulates detailed address location information
@ Property (nonatomic, readonly) CLLocation * location; // geographic location @ property (nonatomic, readonly) CLRegion * region; // region @ property (nonatomic, readonly) NSDictionary * addressDictionary; // detailed address information @ property (nonatomic, readonly) NSString * name; // address name @ property (nonatomic, readonly) NSString * locality; // City
Relationship Diagram
CoreLocation instance
@ Interface ViewController ()
/*** Locate the manager */@ property (nonatomic, strong) CLLocationManager * mgr; @ end @ implementation ViewController-(void) viewDidLoad {[super viewDidLoad]; // 1. create CoreLocation manager CLLocationManager * mgr = [[CLLocationManager alloc] init]; // 2. the position self obtained by the proxy listener of the CoreLocation manager. mgr. delegate = self; // set how often to obtain self. mgr. distanceFilter = 500; // set the accuracy of the obtained location/* kCLLocationAccuracyBestForNavigation best navigation kCLLocationAc CuracyBest; the most accurate kCLLocationAccuracyNearestTenMeters; 10 meters kCLLocationAccuracyHundredMeters; 3 km meters kCLLocationAccuracyKilometer; km; */self. mgr. desiredAccuracy = kCLLocationAccuracyNearestTenMeters; // determines whether iOS8 if ([UIDevice currentDevice]. systemVersion doubleValue]> = 8.0) {NSLog (@ is iOS8); // proactively requires the user to authorize our program. If the authorization status changes, the proxy will be notified. // [self. mgr requestAlwaysAuthorization]; // Request the foreground and background positioning permissions // [self. mgr requestWhenInUseAuthorization]; // request the foreground positioning permission} else {NSLog (@ is iOS7); // 3. start listening (start obtaining location) [self. mgr startUpdatingLocation] ;}}/*** call the ** @ param manager event trigger object ** @ param status current authorization status */-(void) when the authorization status changes) locationManager :( CLLocationManager *) manager didChangeAuthorizationStatus :( clthorizationstatus) status {/* the user has never selected the permission kclthorizationstatusnotdetermined and cannot use the location service. Kclthorizationstatusrestricted the user rejects the application from using the location service, or the location service master switch is disabled. kclthorizationstatusdenied has been authorized (discarded) kclthorizationstatusauthorized users allow the program to use geographic information at any time. kclthorizationstatusauthorizedalways users agree to use geographic locations when the program is visible */if (status = kclthorizationstatusnotdetermined) {NSLog (@ waiting for user authorization);} else if (status = kclthorizationstatusauthorizedalways | status = kC LAuthorizationStatusAuthorizedWhenInUse) {NSLog (@ authorization successful); // locate [self. mgr startUpdatingLocation];} else {NSLog (@ authorization failed);} # pragma mark-CLLocationManagerDelegate //-(void) locationManager :( CLLocationManager *) manager didUpdateToLocation :( CLLocation *) newLocation fromLocation :( CLLocation *) oldLocation/*** it will be called after location information is obtained (the call frequency is very high) ** @ param manager: The Event trigger object * @ param locations: Location obtained */-(void) locati OnManager :( CLLocationManager *) manager didUpdateLocations :( NSArray *) locations {NSLog (@ % s, _ func _); // If you only need to obtain it once, you can get the location and stop it. // [self. mgr stopUpdatingLocation];} # pragma mark-lazy loading-(CLLocationManager *) mgr {if (! _ Mgr) {_ mgr = [[CLLocationManager alloc] init];} return _ mgr;} @ end
/* Note: As long as iOS7 is located, the system automatically requires the user to authorize your application. however, in iOS8, to locate the problem, you must first manually require user authorization in iOS8, not only to actively request authorization, but also to info. the authorization window NSLocationWhenInUseDescription is displayed only when an attribute is configured in the plist file. The NSLocationAlwaysUsageDescription of GPS can be obtained at the foreground, and the GPS description can be obtained at the background */
@ Interface ViewController ()
/*** Locate the manager */@ property (nonatomic, strong) CLLocationManager * mgr; @ end @ implementation ViewController-(void) viewDidLoad {[super viewDidLoad]; // 1. create a CoreLocation manager // CLLocationManager * mgr = [[CLLocationManager alloc] init]; // 2. the position self obtained by the proxy listener of the CoreLocation manager. mgr. delegate = self; // determines whether it is iOS8 if ([[UIDevice currentDevice]. systemVersion doubleValue]> = 8.0) {NSLog (@ is iOS8); // proactively requires the user to authorize our program, When the authorization status changes, the proxy will be notified [self. mgr requestAlwaysAuthorization]; // request the foreground and background positioning permissions} else {NSLog (@ is iOS7); // 3. start listening (start obtaining location) [self. mgr startUpdatingLocation] ;}}/*** call the ** @ param manager event trigger object ** @ param status current authorization status */-(void) when the authorization status changes) locationManager :( CLLocationManager *) manager didChangeAuthorizationStatus :( clthorizationstatus) status {if (status = kclthorizationstatusnotdetermined) {NSLog (@ waiting for user authorization);} el Se if (status = kclthorizationstatusauthorizedalways | status = kclthorizationstatusauthorizedwheninuse) {NSLog (@ authorization successful); // start locating [self. mgr startUpdatingLocation];} else {NSLog (@ authorization failed);} # pragma mark-CLLocationManagerDelegate/*** it will be called after location information is obtained (the call frequency is very high) ** @ param manager: Event trigger object * @ param locations: Location obtained */-(void) locationManager :( CLLocationManager *) manager didUpdateLocations :( NSArray *) Locations {NSLog (@ % s, _ func _); // If you only need to retrieve it once, you can stop it after obtaining the location. // [self. mgr stopUpdatingLocation]; // 1. obtain the last location/* location. coordinate; coordinates, including longitude and latitude location. altitude; the unit of height of the device is meter location. course; set the forward direction to 0, indicating that the North 90 east 180 South 270 West location. horizontalAccuracy; horizontal precision location. verticalAccuracy; vertical precision location. timestamp; specifies the time location returned by the positioning information. speed; the unit of the device's moving speed is meter/second. It is suitable for driving speed but not suitable for use. * // you can set the simulated speed of the simulator. Run and run the freeway drive highway drive */CLLocation * location = [locations lastObject]; NSLog (@ % f, % f speed = % f, location. coordinate. latitude, location. coordinate. longpolling, location. speed) ;}# pragma mark-lazy loading-(CLLocationManager *) mgr {if (! _ Mgr) {_ mgr = [[CLLocationManager alloc] init];} return _ mgr;} @ end
Vehicle Navigation instance
# Import ViewController. h # import
@ Interface ViewController ()
// Create a location manager @ property (nonatomic, strong) CLLocationManager * mgr; // The last location @ property (nonatomic, strong) CLLocation * previuslocation; // total distance @ property (nonatomic, assign) CLLocationDistance sumDistance; // total time @ property (nonatomic, assign) NSTimeInterval sumTime; @ end @ implementation ViewController-(void) viewDidLoad {[super viewDidLoad]; // 1. create a location manager // CLLocationManager * mgr = [[CLLocationManager alloc] Init]; // 2. set proxy self. mgr. delegate = self; // 3. determine whether it is iOS8 if ([[UIDevice currentDevice]. systemVersion doubleValue]> = 8.0) {// actively request authorization [self. mgr requestAlwaysAuthorization];} // 3. start locating [self. mgr startUpdatingLocation];} # pragma mark-CLLocationManagerDelegate-(void) locationManager :( CLLocationManager *) manager didUpdateLocations :( NSArray *) locations {// CLLocation; timestamp current time of obtaining the information/* How far has it been obtained (This time minus the last time) how much time it took to get the path (this time minus the last time) how far it took to get the speed (how far it took/how much time it took) get the total distance (accumulate the distance obtained each time) Get the average speed (total distance/total time) * /// obtain the current location CLLocation * newLocation = [locations lastObject]; if (self. previuslocation! = Nil) {// calculate the distance (in meters). CLLocationDistance distance = [newLocation distanceFromLocation: self. previuslocation]; // calculate the time (in seconds) between two times. NSTimeInterval dTime = [newLocation. timestamp timeIntervalSinceDate: self. previuslocation. timestamp]; // calculation speed (meter/second) CGFloat speed = distance/dTime; // accumulate time self. sumTime + = dTime; // accumulative distance self. sumDistance + = distance; // calculate the average speed CGFloat avgSpeed = self. sumDistance/se Lf. sumTime; NSLog (@ % f time % f speed % f average speed % f total distance % f Total time % f, distance, dTime, speed, avgSpeed, self. sumDistance, self. sumTime);} // records the last position self. previuslocation = newLocation;} // # pragma mark-lazy loading-(CLLocationManager *) mgr {if (! _ Mgr) {self. mgr = [[CLLocationManager alloc] init];} return _ mgr;} @ end
Compass instance
# Import ViewController. h # import
@ Interface ViewController ()
/*** Locate manager */@ property (nonatomic, strong) CLLocationManager * mgr; // compass image @ property (nonatomic, strong) UIImageView * compasspointer; @ end @ implementation ViewController-(void) viewDidLoad {[super viewDidLoad]; // 1. add a compass image UIImageView * iv = [[UIImageView alloc] initWithImage: [UIImage imageNamed: @ bg_compasspointer]; iv. center = CGPointMake (self. view. center. x, self. view. center. y); [self. view addSub View: iv]; self. compasspointer = iv; // 2. the position self obtained by the proxy listener of the CoreLocation manager. mgr. delegate = self; // 3. start to get user location // Note: Obtaining user direction information does not require user authorization [self. mgr startUpdatingHeading];} # pragma mark-CLLocationManagerDelegate // call-(void) locationManager (CLLocationManager *) manager didUpdateHeading :( CLHeading *) when the user is obtained *) newHeading {// NSLog (@ % s, _ func _);/* Relative angle between the magneticHeading device and the magnetic north trueHeading device and the real North. Positioning is used together. iOS needs to set the location to calculate that zhenbei always points to the geographic northern point * // NSLog (@ % f, newHeading. magneticHeading); // 1. convert the obtained angle to degrees = (angle * π)/180; CGFloat angle = newHeading. magneticHeading * M_PI/180; // 2. rotate the image/* Positive and Negative clockwise * // self. compasspointer. transform = CGAffineTransformIdentity; self. compasspointer. transform = CGAffineTransformMakeRotation (-angle) ;}# pragma mark-lazy loading-(CLLocationManager *) mgr {if (! _ Mgr) {_ mgr = [[CLLocationManager alloc] init];} return _ mgr;} @ end
Region check instance
# Import ViewController. h # import
@ Interface ViewController ()
/*** Locate the manager */@ property (nonatomic, strong) CLLocationManager * mgr; @ end @ implementation ViewController-(void) viewDidLoad {[super viewDidLoad]; // 2. the position self obtained by the proxy listener of the CoreLocation manager. mgr. delegate = self; // Note: if it is iOS8 and you want to perform region detection, you must request the user's privacy permission if ([[UIDevice currentDevice]. systemVersion doubleValue]> = 8.0) {[self. mgr requestAlwaysAuthorization];} // 3. start to check the region where the user is located // 3.1 create a region // CLRegion has two sub-classes: The door is used to specify the area // a Bluetooth range can be specified/a circular range can be specified // create the center point CLLocationCoordinate2D center = CLLocationCoordinate2DMake (40.058501, 116.304171 ); // c create a circular area, specify the longitude and latitude of the center, and the radius CLCircularRegion * circular = [[CLCircularRegion alloc] initWithCenter: center radius: 500 identifier: @ Software Park]; [self. mgr startMonitoringForRegion: circular] ;}# pragma mark-CLLocationManagerDelegate // call-(void) locationManager :( CLLocationMa Nager *) manager didEnterRegion :( CLRegion *) region {NSLog (@ called when you enter the listening area);} // call when you leave the listening area-(void) locationManager :( CLLocationManager *) manager didExitRegion :( CLRegion *) region {NSLog (@ called when leaving the listening area);} // # pragma mark-lazy loading-(CLLocationManager *) mgr {if (! _ Mgr) {_ mgr = [[CLLocationManager alloc] init];} return _ mgr;} @ end
Geocode instance
# Import ViewController. h # import
@ Interface ViewController () # pragma mark-geocode/*** listens to the geocode Click Event */-(IBAction) geocodeBtnClick; /*** address container to be encoded */@ property (weak, nonatomic) IBOutlet UITextField * addressField;/*** longitude container */@ property (weak, nonatomic) IBOutlet UILabel * longitudeLabel;/*** latitude container */@ property (weak, nonatomic) IBOutlet UILabel * latitudeLabel;/*** details container */@ property (weak, nonatomic) IBOutlet UILabel * detailAddressLabel ;/ * ** Geocoding object */@ property (nonatomic, strong) CLGeocoder * geocoder; @ end @ implementation ViewController-(void) geocodeBtnClick {// 0. obtain the user input position NSString * addressStr = self. addressField. text; if (addressStr = nil | addressStr. length = 0) {NSLog (@ enter the address); return;} // 1. create a geocode object // 2. use geocoding object encoding // obtain the latitude and longitude information corresponding to the address based on the input Address [self. geocoder geocodeAddressString: addressStr completionHandler: ^ (NSArray * placemar Ks, NSError * error) {if (placemarks. count = 0 | error! = Nil) {return;} // placemarks landmark array, which contains landmarks, each landmark contains the longitude and latitude of the location, the city/region/country code/zip code, and so on... // obtain the first landmark CLPlacemark * placemark = [placemarks firstObject] in the array; // for (CLPlacemark * placemark in placemarks) {// NSLog (%%@% f % f, placemark. name, placemark. addressDictionary, placemark. location. coordinate. latitude, placemark. location. coordinate. longpolling); self. latitudeLabel. text = [NSString stringWithFormat: @ % F, placemark. location. coordinate. latitude]; self. longitudeLabel. text = [NSString stringWithFormat: @ % f, placemark. location. coordinate. longpolling]; NSArray * address = placemark. addressDictionary [@ FormattedAddressLines]; NSMutableString * strM = [NSMutableString]; for (NSString * str in address) {[strM appendString: str];} self. detailAddressLabel. text = strM; //}];}-(CLGeocoder *) geocoder {If (! _ Geocoder) {_ geocoder = [[CLGeocoder alloc] init];} return _ geocoder;} @ end
Anti-geographic code example
# Import ViewController. h # import
@ Interface ViewController ()/*** geocode object */@ property (nonatomic, strong) CLGeocoder * geocoder; # pragma mark-anti-geocode-(IBAction) reverseGeocode; @ property (weak, nonatomic) IBOutlet UITextField * longtitudeField; @ property (weak, nonatomic) IBOutlet UITextField * latitudeField; @ property (weak, nonatomic) IBOutlet UILabel * handle; @ end @ implementation ViewController-(void) reverseGeocode {// 1. obtain the longitude and latitude NSString * longtitude = self. longtitudeField. text; NSString * latitude = self. latitudeField. text; if (longtitude. length = 0 | longtitude = nil | latitude. length = 0 | latitude = nil) {NSLog (@ enter the latitude and longitude); return;} // 2. create a CLLocation object CLLocation * location = [[CLLocation alloc] initWithLatitude: [latitude doubleValue] longpolling: [longtitude doubleValue] According to the latitude and longitude entered by the user; // 3. based on CLLocation Obtain the corresponding landmark information [self. geocoder handle: location completionHandler: ^ (NSArray * placemarks, NSError * error) {for (CLPlacemark * placemark in placemarks) {NSLog (@ % f, placemark. name, placemark. addressDictionary, placemark. location. coordinate. latitude, placemark. location. coordinate. longpolling); self. reverseDetailAddressLabel. text = placemark. locality ;}}] ;}// # pragma mark-lazy loading-(CLGe Ocoder *) geocoder {if (! _ Geocoder) {_ geocoder = [[CLGeocoder alloc] init];} return _ geocoder;} @ end