Core location is a framework for providing device locations in the iOS SDK. You can use three techniques to get a location: GPS, cellular, or WiFi. In these technologies, GPS is the most accurate, and if you have GPS hardware, the Core location will use it first. If the device does not have GPS hardware (such as WiFi iPad) or if it fails to get the current position using GPS, the Core location will be back and then choose to use cellular or WiFi.
Most features of Core location are provided by the position Manager (Cllocationmanager), which can be used to specify the frequency and accuracy of location updates, and to start and stop receiving these updates.
To use the Location manager, you must first add the framework core location to your project and then import its interface files:
#import <CoreLocation/CoreLocation.h>
Next, you need to assign and initialize a location manager instance, specify the delegate that will receive the location update, and start the update:
Cllocationmanager *locmanager = [[Cllocationmanager alloc] init];locmanager.delegate = self; [Locmanager Startupdatinglocation];//[locmanager stopupdatinglocation];
the Location Manager delegate (Cllocationmanagerdelegate) has two location-related methods:
-(void) Locationmanager: (Cllocationmanager *) Manager didupdatelocations: (Nsarray *) locations{ }-(void) Locationmanager: (Cllocationmanager *) Manager didfailwitherror: (nserror *) error{ }
The first method handles the positioning success, the manager parameter represents the location manager instance, and the locations is an array, which is a collection of positional changes that are stored in the order of time changes. If you want to get the current location of the device, you only need to access the last element of the array. Each object type in the collection is Cllocation, which contains the following properties:
coordinate-coordinates. A structure that encapsulates the longitude and latitude.
altitude-altitude. A positive number is expressed above sea level, while negative numbers are below sea level.
The precision (RADIUS) of the horizontalaccuracy-position. Positional accuracy is represented by a circle, where the actual position may be located anywhere within the circle. This circle is determined by coordinate (coordinate) and horizontalaccuracy (RADIUS), the larger the value of the horizontalaccuracy, the larger the circle is defined, so the position accuracy is lower. If the value of horizontalaccuracy is negative, it indicates that the value of coordinate is invalid.
verticalaccuracy-the accuracy of the altitude. A positive value indicates an elevation error of the corresponding number of meters, and a negative representation of altitude (altitude) is invalid.
speed-speed. This property is calculated by comparing the current position and the previous position, and comparing the time difference and distance between them. Because of the frequency of core location updates, the value of the speed attribute is not very precise unless the movement velocity changes very little
-(void) Locationmanager: (Cllocationmanager *) Manager didupdatelocations: (Nsarray *) locations{ cllocation * curlocation = [Locations lastobject]; if (curlocation.horizontalaccuracy > 0) { NSLog (@ "Current position:%.0f,%.0f +/-%.0f meters", CurLocation.coordinate.longitude, curLocation.coordinate.latitude, curlocation.horizontalaccuracy); } if (curlocation.verticalaccuracy > 0) { NSLog (@ "Current altitude:%.0f +/-%.0f meters", Curlocation.altitude, curlocation.verticalaccuracy);} }
When the application starts to track the user's location, a prompt box is displayed on the screen to allow positioning. If the user disables location services, iOS does not prevent the application from running, but the location manager generates an error.
The second method handles this failure, and the parameter of the method indicates the reason for the failure. If the user prohibits the application from locating, the error parameter will be kclerrordenied, and if the core location fails to confirm the position, the error parameter will be kclerrorlocationunknown, if there is no source available to get the location, The error parameter will be kclerrornetwork.
Typically, the Core location will continue to attempt to determine the position after an error occurs, but it will not do so if the user disables positioning, in which case the location manager should be stopped using the method stopupdatinglocation.
-(void) Locationmanager: (Cllocationmanager *) Manager didfailwitherror: (nserror *) error{ if (Error.code = = Kclerrorlocationunknown) { NSLog (@ "Currently unable to retrieve location."); else if (Error.code = = kclerrornetwork) { NSLog (@ "Network used to retrieve location is unavailable.") ; else if (Error.code = = kclerrordenied) { NSLog (@ "Permission to retrieve location is denied."); [Manager stopupdatinglocation];} }
position accuracy can be specified according to the actual situation. For example, there is no need to require a core location with a precision of 10 meters for an application that simply determines which country the user is in. To specify precision, you can set the location manager's desiredaccuracy before starting the location update. There are 6 enumeration values that represent different precision
extern const Cllocationaccuracy Kcllocationaccuracybestfornavigation;extern const CLLOCATIONACCURACY Kcllocationaccuracybest;extern Const Cllocationaccuracy Kcllocationaccuracynearesttenmeters;extern const Cllocationaccuracy Kcllocationaccuracyhundredmeters;extern const cllocationaccuracy KCLLocationAccuracyKilometer; extern const Cllocationaccuracy Kcllocationaccuracythreekilometers;
after the update is started on the location manager, the update is passed on to the location manager delegate until the update is stopped. You cannot directly control the frequency of these updates, but you can use the Location Manager's property Distancefilter for indirect control. Set the property distancefilter before starting the update, which specifies how many meters (horizontal or vertical) the device will move before sending another update to the delegate. The following code launches the location manager using the settings that are appropriate for tracking the traveler's Trek:
Cllocationmanager *locmanager = [[Cllocationmanager alloc] init];locmanager.delegate = self; Locmanager.desiredaccuracy = Kcllocationaccuracyhundredmeters;locmanager.distancefilter = 200; [Locmanager startupdatinglocation];
P.S. The higher the accuracy of the positioning requirements and the smaller the value of the attribute Distancefilter, the greater the application power consumption.
The location manager has a Headingavailable property that indicates whether the device is equipped with a magnetic compass. If this property is yes, you can use the core location to get the heading (heading) information. Receive heading updates are very similar to receive location updates, to begin receiving heading updates, you can specify the Location manager delegate, set the property headingfilter to specify at what frequency (measured in degrees of change in course) to receive updates, and call method startupdatingheading to the location Manager:
The Location Manager delegation protocol defines a method for receiving a heading update. The Protocol has two course-related methods:
-(BOOL) Locationmanagershoulddisplayheadingcalibration: (Cllocationmanager *) manager{ return YES; -(void) Locationmanager: (Cllocationmanager *) Manager didupdateheading: (clheading *) newheading{ }
The first method specifies whether the location manager displays a calibration hint to the user. This prompt will automatically rotate the device 360°. Since the compass is always self-calibrating, this tip is only helpful if the compass readings fluctuate violently. When set to Yes, the hint may distract the user or affect the user's current action.
The second method's parameter, newheading, is a Clheading object. Clheading provides heading readings through a set of properties: Magneticheading and Trueheading. These values are in degrees, with a type of cllocationdirection, which is a double-precision floating-point number. This means that:
If the heading is 0.0, the forward direction is north;
If the heading is 90.0, the forward direction is east;
If the heading is 180.0, the forward direction is south;
If the heading is 270.0, the forward direction is west.
The Clheading object also contains attribute headingaccuracy (precision), timestamp (measurement time for readings), and description (a description that is more appropriate for writing to the log rather than displaying to the user). The following illustrates the process of handling a course update using this method:
-(void) Locationmanager: (Cllocationmanager *) Manager didupdateheading: (clheading *) newheading{ if ( Newheading.headingaccuracy >=0) { NSString *headingdesc = [NSString stringwithformat:@ "%.0f degrees (True) ,%.0f degrees (magnetic) ", newheading.trueheading,newheading.magneticheading]; NSLog (@ "%@", Headingdesc); }}
Trueheading and magneticheading represent true heading and magnetic heading respectively. If the location service is turned off, GPS and WiFi will only get magneticheading (magnetic field heading). Trueheading (True heading) can only be obtained if the location service is turned on.
The code below shows that when there is a location that determines the latitude and longitude, the distance from the location and the correct course for the current position:
#import "ViewController.h" #define KDESTLONGITUDE 113.12//Precision # define Kdestlatitude 22.23//Latitude # define KRAD2DEG 57.2957795 180/π#define Kdeg2rad 0.0174532925//π/180@interface viewcontroller () @property (Strong, nonatomic) iboutlet UILabel * Lblmessage; @property (Strong, nonatomic) Iboutlet Uiimageview *imgview; @property (Strong, nonatomic) Cllocationmanager *locationmanager; @property (Strong, Nonatomic) cllocation *recentlocation;-(Double) Headingtolocation: ( CLLOCATIONCOORDINATE2D) Desired Current: (cllocationcoordinate2d) current; @end @implementation viewcontroller-(void) viewdidload{[Super Viewdidload]; Self.locationmanager = [[Cllocationmanager alloc] init]; Self.locationManager.delegate = self; Self.locationManager.desiredAccuracy = kcllocationaccuracythreekilometers; Self.locationManager.distanceFilter = 1609; 1 miles ≈ 1609 m [Self.locationmanager Startupdatinglocation]; if ([Cllocationmanager headingavailable]) {self.locationManager.headingFilter = 10; 10°[self.locationmanager startupdatingheading]; }}/* * According to movable Type Scripts * http://mathforum.org/library/drmath/view/55417.html * Javascript: * * var y = Math.sin (Dlon) * Math.Cos (LAT2); * var x = Math.Cos (LAT1) *math.sin (LAT2)-* Math.sin (LAT1) *math.cos (LAT2) *math.cos (Dlon); * var brng = math.atan2 (y, x). Todeg (); */-(Double) Headingtolocation: (cllocationcoordinate2d) Desired current: (cllocationcoordinate2d) current{double LAT1 = Current.latitude*kdeg2rad; Double lat2 = Desired.latitude*kdeg2rad; Double lon1 = current.longitude; Double lon2 = desired.longitude; Double Dlon = (lon2-lon1) *kdeg2rad; Double y = sin (dlon) *cos (LAT2); Double x = cos (LAT1) *sin (lat2)-sin (lat1) *cos (LAT2) *cos (Dlon); Double heading=atan2 (y,x); Heading=heading*krad2deg; heading=heading+360.0; Heading=fmod (heading,360.0); return heading;} Process heading-(void) Locationmanager: (Cllocationmanager *) Manager didupdateheading: (clheading *) newheading{if (Self.recentlocation!=nil && newheading.headingaccuracy>=0) {cllocation *destlocation = [[CLLocati] On alloc] Initwithlatitude:kdestlatitude longitude:kdestlongitude]; Double course = [self headingToLocation:destLocation.coordinate current:self.recentLocation.coordinate]; Double delta = newheading.trueheading-course; if (delta) <= {self.imgView.image = [UIImage imagenamed:@ "Up_arrow.png"]; } else {if (Delta > +) {self.imgView.image = [UIImage imagenamed : @ "Right_arrow.png"]; } else if (Delta > 0) {self.imgView.image = [UIImage imagenamed:@ "Left_arrow.png" ]; } else if (Delta > -180) {self.imgView.image = [UIImage imagenamed:@ "Right_arrow. PNG "]; } else {self.imgView.image = [UIImage imagenamed:@ "Left_arrow.png"]; }} Self.imgView.hidden = NO; } else {self.imgView.hidden = YES; }}//Processing location succeeded-(void) Locationmanager: (Cllocationmanager *) Manager didupdatelocations: (Nsarray *) locations{cllocation * curlocation = [Locations Lastobject]; if (curlocation.horizontalaccuracy >= 0) {self.recentlocation = curlocation; Cllocation *destlocation = [[Cllocation alloc] Initwithlatitude:kdestlatitude longitude:kdestlongitude]; Cllocationdistance distance = [destlocation distancefromlocation:curlocation]; if (distance<500) {[Self.locationmanager stopupdatinglocation]; [Self.locationmanager stopupdatingheading]; Self.lblMessage.text = @ "You have reached your destination!";} else {self.lblMessage.text = [NSString stringwithformat:@ "is also%f m from the destination", distance]; }}//Processing location failed-(void) Locationmanager: (Cllocationmanager *) Manager Didfailwitherror: (nserror *) error{if (Error.code = = Kclerrorlocationunknown) {NSLog (@ "currently Una ble to retrieve location. ");} else if (Error.code = = kclerrornetwork) {NSLog (@ "Network used to retrieve location is unavailable."); else if (Error.code = = kclerrordenied) {NSLog (@ "Permission to retrieve location is denied."); [Self.locationmanager stopupdatinglocation]; Self.locationmanager = nil; }}-(void) didreceivememorywarning{[Super didreceivememorywarning]; Dispose of any resources the can be recreated.} @end
iOS targeting new features----enabling positioning in your program