1. Map (CoreLocation and MapKit)

  • CoreLocation framework

    • CoreLocation
    • CLLocation
    • Privacy protection for ios Map Development (How to Add Authorization)
    • CLGeocoder
    • CLPlacemark
  • MapKit framework

    • MKMapView
    • MKCoordinateRegion
    • MKMapView agent
    • MKUserLocation
    • A pin
    • annotation
    • Custom pin
    • MKAnnotationView
    • MKPinAnnotationView
    • MKMapItem calls the system APP to navigate
    • MKMapCamera Map street view
    • MKMapSnapshotter map screenshot

Second, the big framework

MapKit: used for map display, such as pins, routes, overlay display, etc. (focus on interface display)Copy the code

Use of the CoreLocation framework

CLLocationManager

The CoreLocation framework uses the CLLocationManager object to do user location creation (initialization)

CLLocationManager *lM = [[CLLocationManager alloc] init];
Copy the code

Commonly used attributes

  • Locate every number of meters

    @property(assign, nonatomic) CLLocationDistance distanceFilter;
    Copy the code
  • Positioning accuracy (more accurate, more power consumption)

    @property(assign, nonatomic) CLLocationAccuracy desiredAccuracy;
    Copy the code
  • How many degrees are called when the orientation changes

    @property(assign, nonatomic) CLLocationDegrees headingFilter
    Copy the code
  • Locate every few meters

    _lM.distanceFilter = 100; / * * kCLLocationAccuracyBestForNavigation / / the most suitable for navigation kCLLocationAccuracyBest; / / the best kCLLocationAccuracyNearestTenMeters; // 10m kCLLocationAccuracyHundredMeters; // 100m kCLLocationAccuracyKilometer; // 1000m kCLLocationAccuracyThreeKilometers; // 3000m */ / the higher the accuracy, the more power consumption, the longer the positioning time _lm. desiredAccuracy = kCLLocationAccuracyBest;Copy the code

Commonly used method

  • Start updating the user location
- (void)startUpdatingLocation;
Copy the code
  • When the startUpdatingLocation method is called, the user’s location is continuously requested, refreshed, and the following method of the proxy is invoked once the user’s location is requested
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations;
Copy the code

The locations parameter contains the CLLocation object

  • Stop updating the user location
- (void) stopUpdatingLocation;
Copy the code

Determine whether the location function is available (for rigor’s sake, it is best to determine before using the location function)

+ (BOOL)locationServicesEnabled;
Copy the code

Monitoring device Orientation

-(void)startUpdatingHeading(as in the compass implementation in the sample code)Copy the code

Area listening (listening to enter and exit an area)

-(void)requestStateForRegion:region;
Copy the code
// Use the location manager to start updating the user location. // By default, you can only get the user location in the foreground, // Check background mode location updates [self.lm startUpdatingLocation];Copy the code
// The listener heading [self.lm startUpdatingHeading];Copy the code
- the area to monitor (listening in and out of an area) [self. LM requestStateForRegion: region];Copy the code

Proxy method

  • Called after updating the location
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations;
Copy the code
  • Called when authorization status changes
-(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
Copy the code
  • Called when getting the orientation of the phone
-(void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
Copy the code
  • Proxy method for zone listening

    • Call when entering a region:
      -(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
      Copy the code
    • Call when leaving a region:
      -(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
      Copy the code
    • Monitor whether the state is in a region:
      -(void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state
      Copy the code
** @param * @param locations */ -(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { NSLog(@"Got a location."); // stop update // [manager stopUpdatingLocation]; }Copy the code
/** * call ** @param manager locationManager * @param status status */ -(void)locationManager:(CLLocationManager *)manager DidChangeAuthorizationStatus (CLAuthorizationStatus) status {switch (status) {/ / user hasn't been decidedcase kCLAuthorizationStatusNotDetermined:
        {
            NSLog(@"User has not decided yet");
            break; } // Ask restrictedcase kCLAuthorizationStatusRestricted:
        {
            NSLog(@"Access restricted");
            break; } // called when locating closed and when this APP is authorized to nevercaseKCLAuthorizationStatusDenied: {/ / positioning is available (whether the orientation of whether to support or open)if([CLLocationManager locationServicesEnabled])
            {
                NSLog(@"Location enabled, but rejected.");
            }else
            {
                NSLog(@"Location closed, unavailable.");
            }
//            NSLog(@"Rejected");
            break; } // Obtain the front and back location authorizationcase kCLAuthorizationStatusAuthorizedAlways:
            //        case{kCLAuthorizationStatusAuthorized: / / failure, not recommended NSLog (@"Obtain front and back location authorization");
            break; } // Obtain foreground location authorizationcase kCLAuthorizationStatusAuthorizedWhenInUse:
        {
            NSLog(@"Obtain front desk positioning authorization");
            break;
        }
        default:
            break; }}Copy the code
/** * Simple compass implementation ** Calls when the phone orientation changes ** @param Manager position manager * @param newHeading orientation object */ -(void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading { /** * CLHeading * MagneticHeading: Magnetic north Angle *trueHeading: true north */ NSLog(@"%f", newHeading.magneticHeading); CGFloat angle = newHeading.magneticHeading; CGFloat angleR = Angle / 180.0 * M_PI; / / rotating images (compass) [UIView animateWithDuration: 0.25 animations: ^ {self.com passView. Transform = CGAffineTransformMakeRotation(-angleR); }]; }Copy the code
-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region {NSLog(@)"Enter zone --%@", region.identifier); } // leave the region -(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region {NSLog(@)"Leave area --%@", region.identifier); } // listen if the state is in a region -(void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)stateforRegion:(CLRegion *) Region {//state value //CLRegionStateUnknown, //CLRegionStateInside, //CLRegionStateOutside NSLog(@)"%zd", state);   
}
Copy the code

CLLocation

  • CLLocation is used to represent geographic information about a location, such as longitude, latitude, altitude, etc

  • Commonly used attributes

    • Latitude and longitude
    @property(readonly, nonatomic) CLLocationCoordinate2D coordinate;
    Copy the code
    • At an altitude of
    @property(readonly, nonatomic) CLLocationDistance altitude;
    Copy the code
    • Route, heading (value range: 0.0° to 359.9°, 0.0° represents true north)
    @property(readonly, nonatomic) CLLocationDirection course;
    Copy the code
    • Speed of movement (in m/s)
    @property(readonly, nonatomic) CLLocationSpeed speed;
    Copy the code
  • Commonly used method

    • Calculate the distance between two positions:
    - (CLLocationDistance)distanceFromLocation:(const CLLocation *)location
    Copy the code
Example: Print the moving direction and distance according to the moving direction
** @param manager location manager * @param Locations array * is kind of */  -(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations { // NSLog(@"Got a location."); /** * CLLocation detail * coordinate: latitude * altitude * course * speed; */ CLLocation *location = [locations lastObject]; // NSLog(@"% @", location); /** * Scenario demonstration: print the current user's walking direction, deviation Angle and corresponding walking distance, for example: "30 degrees north by east, moved 8 meters" */ // 1. Get direction bias NSString *angleStr = nil; switch ((int)location.course / 90) {case 0:
            angleStr = @"North by East";
            break;
        case 1:
            angleStr = @"East by South";
            break;
        case 2:
            angleStr = @"South by West";
            break;
        case 3:
            angleStr = @"West by North";
            break;
            
        default:
            angleStr = @"In the ditch!!";
            break; } // 2. Angle NSInteger = 0; angle = (int)location.course % 90; // represents the positive directionif (angle == 0) {
        NSRange range = NSMakeRange(0, 1);
        angleStr = [NSString stringWithFormat:@Is "% @", [angleStr substringWithRange:range]]; } // 3. Double distance = 0;if(_oldL) { distance = [location distanceFromLocation:_oldL]; } _oldL = location; // for example: "30 degrees north by EAST, moved 8 meters" NSString *noticeStr = [NSString stringWithFormat:@"%@% Zd direction, moved %f meters", angleStr, angle, distance];
    NSLog(@"% @", noticeStr);
}
Copy the code

Privacy protection for ios Map Developers (Authorization)

Ios6 +

  • When using location, the system will automatically pop up a dialog box for user authorization.
    • Once the user opts out, it means that the application cannot use location in the future.
  • Developers can in the Info. The purpose of setting the NSLocationUsageDescription shows that locate in the plist (Privacy – the Location the Usage Description)

Ios8.0 +

  • Starting with ios8.0, apple has further strengthened its privacy protections.

  • When the app wants to access the user’s privacy, the system will no longer automatically pop up a dialog box asking the user to authorize it.

The solution

  • (1) Call the ios8.0 API. Proactively request user authorization

    • – (void) requestAlwaysAuthorization / / request permission can obtain the authorization of user’s location in Taiwan before and after
    • – (void) requestWhenInUseAuthorization / / request permission at the front desk to obtain the authorization of user’s location (note: when authorization is set to the front desk, by setting the background mode: Location updates are also available in the background, but a blue bar will appear at the top of the screen.)
  • (2) The corresponding key value must be configured in the info.plist file; otherwise, the above authorization method will not take effect

    • Get the description of the GPS NSLocationAlwaysUsageDescription: allow in Taiwan before and after
    • NSLocationWhenInUseDescription: allow at the front desk for the description of the GPS

ios9.0

  • Ios9.0 if the current status is in the foreground authorization, the default is that the background can not obtain the user location. You can set the following property to YES to continue to get the location in the background, but with a blue bar at the top of the screen

    • @property(assign, nonatomic) BOOL allowsBackgroundLocationUpdates
    • Note: You must set the corresponding background mode: Location Updates
  • Ios9.0 can request a user’s location once

    • -(void)requestLocation
    • -(void)locationManager:(nonnull CLLocationManager *)manager didUpdateLocations:(nonnull NSArray

      *)locations // Successful call
    • -(void)locationManager:(nonnull CLLocationManager *)manager didFailWithError:(nonnull NSError *)error // failed to call

CLGeocoder

  • You can do geocoding and anti-geocoding using CLGeocoder

    • Geocoding: Obtaining specific location information (latitude and longitude, full name of address, etc.) based on a given place name
    • Inverse geocoding: obtaining specific location information based on a given latitude and longitude
  • Corresponding methods

    • Geocoding method
    -(void)geocodeAddressString:(NSString *)addressString completionHandler:(CLGeocodeCompletionHandler)completionHandler;
    Copy the code
    • Anti-geocoding methods
    -(void)reverseGeocodeLocation:(CLLocation *)location completionHandler:(CLGeocodeCompletionHandler)completionHandler;
    Copy the code
  • CLGeocodeCompletionHandler: reverse geocoding is complete, is called CLGeocodeCompletionHandler

    • typedef void (^CLGeocodeCompletionHandler)(NSArray *placemarks, NSError *error);

      • Error: Has a value if the encoding fails (for example, no specific information is encoded)
      • Placemarks: Contains CLPlacemark objects

Implementation of geocoding

// geoCoder - (IBAction)geoCoder {// Return if the value passed in is 0if ([self.addressDetailTV.text length] == 0) {
        return; } // Geocoding scheme 1: Geocoding directly by address (more than one result may be returned, Because a site with a moniker) [self geoC geocodeAddressString: self. AddressDetailTV. Text completionHandler: ^ (NSArray < > CLPlacemark * * __nullable placemarks, NSError * __nullable error) { CLPlacemark *placemark = [placemarks firstObject]; // City name // NSString *city = placemark.locality; // NSString *street = placemark.thoroughfare;  self.addressDetailTV.text = [NSString stringWithFormat:@"% @", name];
        self.latitudeTF.text = [NSString stringWithFormat:@"%f", placemark.location.coordinate.latitude];
        self.longtitudeTF.text = [NSString stringWithFormat:@"%f", placemark.location.coordinate.longitude]; }]; / / geographic encoding scheme 2: two conditions according to address and area geocoding (more accurate) / / [self. GeoC geocodeAddressString: self. AddressDetailTV. The textinRegion:nil completionHandler:^(NSArray<CLPlacemark *> * __nullable placemarks, NSError * __nullable error) {
//        // 包含区,街道等信息的地标对象
//        CLPlacemark *placemark = [placemarks firstObject];
//        self.addressDetailTV.text = placemark.description;
//        self.latitudeTF.text = [NSString stringWithFormat:@"%f", placemark.location.coordinate.latitude];
//        self.longtitudeTF.text = [NSString stringWithFormat:@"%f", placemark.location.coordinate.longitude]; / /}]; NSDictionary *addressDic = @{// (__bridge NSString *)kABPersonAddressCityKey: @"Beijing",
//                                 (__bridge NSString *)kABPersonAddressStreetKey : @Tong Ha Street/ /}; // [self.geoC geocodeAddressDictionary:addressDic completionHandler:^(NSArray<CLPlacemark *> * __nullable placemarks, NSError * __nullable error) { // CLPlacemark *placemark = [placemarks firstObject];  // self.addressDetailTV.text = placemark.description; // self.latitudeTF.text = [NSString stringWithFormat:@"%f", placemark.location.coordinate.latitude];
//        self.longtitudeTF.text = [NSString stringWithFormat:@"%f", placemark.location.coordinate.longitude];
//    }];
}
Copy the code

Implementation of anti-geocoding

// Reverse geocoding - (IBAction)decode {// Filter empty dataif ([self.latitudeTF.text length] == 0 || [self.longtitudeTF.text length] == 0) {
        return; CLLocation *location = [[CLLocation alloc] initWithLatitude:[self.latitudetf.text doubleValue] longitude:[self.longtitudeTF.text doubleValue]]; / / based on reverse geocoding CLLocation object [self. GeoC reverseGeocodeLocation: location completionHandler: ^ (NSArray < > CLPlacemark * * __nullable placemarks, NSError * __nullable error) { CLPlacemark *placemark = [placemarks firstObject]; // City name // NSString *city = placemark.locality; // NSString *street = placemark.thoroughfare;  self.addressDetailTV.text = [NSString stringWithFormat:@"% @", name];
    }];

}
Copy the code

CLPlacemark

  • CLPlacemark literally means landmark, encapsulating common attributes for detailed address location information

    • The geographical position
    @property (nonatomic, readonly) CLLocation *location;
    Copy the code
    • area
    @property (nonatomic, readonly) CLRegion *region;
    Copy the code
    • Detailed address information
    @property (nonatomic, readonly) NSDictionary *addressDictionary;
    Copy the code
    • Address name
    @property (nonatomic, readonly) NSString *name;
    Copy the code
    • city
    @property (nonatomic, readonly) NSString *locality;
    Copy the code

Use of the MapKit framework

MapKit uses MKMapView to display maps

  • Commonly used attributes

    • Map matching :mapType

      • MKMapTypeStandard: Normal map (left)
      • MKMapTypeSatellite: Satellite cloud images
      • MKMapTypeHybrid: Hybrid mode (overlay of normal map on top of satellite image)
      • MKMapTypeSatelliteFlyover: 3 d satellite (iOS9.0)
      • MKMapTypeHybridFlyover: 3D stereoscopic blending (iOS9.0)
  • Action items

    • Whether zoomEnabled can be zoomed
    • Whether scrollEnabled is available
    • Whether rotateEnabled can be rotated
  • According to item

    • ShowsCompass (iOS9.0)
    • ShowsScale (iOS9.0)
    • Whether to show traffic showsTraffic (iOS9.0)
    • Whether to show showsBuildings
  • Tracking shows the user’s location (ios8- maps will not automatically roll to the user’s location, ios8+ maps will automatically zoom to the appropriate scale, and show the user’s location)

    • MKUserTrackingModeNone: does not track the user’s location
    • MKUserTrackingModeFollow: Tracks and displays the user’s current location on the map
    • MKUserTrackingModeFollowWithHeading: track and display the user’s current location on the map, the map will follow the direction of rotation of the user
  • Sets the area and location of the map display

    • Sets the center point position of the map

      • @property (nonatomic) CLLocationCoordinate2D centerCoordinate;
      • -(void)setCenterCoordinate:(CLLocationCoordinate2D)coordinate animated:(BOOL)animated;
    • Set the display area of the map

      • @property (nonatomic) MKCoordinateRegion region;
      • -(void)setRegion:(MKCoordinateRegion)region animated:(BOOL)animated;

MKCoordinateRegion

  • MKCoordinateRegion is a structure that is used to represent a region
typedef struct { CLLocationCoordinate2D center; // The center of the region is mkatespan span; // the span of the region} MKCoordinateRegion;Copy the code
  • MKCoordinateSpan
typedef struct { CLLocationDegrees latitudeDelta; // longitudeDelta; // Longitude span} MKCoordinateSpan;Copy the code

MKMapView agent

  • -(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation;

    • A location change is invoked only once by default, constantly monitoring the user’s current location
    • With each call, the user’s latest location (the userLocation parameter) is passed in
  • -(void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated;

    • Called when the map’s display area is about to change
  • -(void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated;

    • Called when the map’s display area has changed

MKUserLocation

  • @property (nonatomic, copy) NSString *title;
    • The title shown on the pin
  • @property (nonatomic, copy) NSString *subtitle;
    • The subtitle displayed on the pin
  • @property (readonly, nonatomic) CLLocation *location;
    • Geo-location information (where is the pin?)

A pin

  • Add pins

    • Add a pin
      • -(void)addAnnotation:(id )annotation;
    • Add multiple pins
      • -(void)addAnnotations:(NSArray *)annotations;
  • Remove the pin

    • Remove a pin
      • -(void)removeAnnotation:(id )annotation;
    • Remove multiple pins
      • -(void)removeAnnotations:(NSArray *)annotations;

annotation

  • Pin model object
#import <MapKit/MapKit.h>@interface TestAnnotation : NSObject <MKAnnotation> /** Coordinate position */ @property (nonatomic, assign) CLLocationCoordinate2D coordinate; /** title */ @property (nonatomic, copy) NSString *title; /** subtitle */ @property (nonatomic, copy) NSString subtitle; @endCopy the code

Custom pin

  • Set up the MKMapView agent

    • -(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id )annotation;
      • Create and return the corresponding pin control based on the (ID)annotation parameter passed in
      • Note: If nil is returned, the pins displayed take the system’s default style
      • A blue glowing dot that identifies the user’s location, which is also a pin, and when this pin is displayed, the proxy method is also invoked
      • Therefore, it needs to be clear in the proxy method whether the (ID)annotation parameter represents a custom pin or a blue glowing dot
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {// determine the type of annotationif(! [annotation isKindOfClass:[TestAnnotation class]])returnnil; // create MKAnnotationView static NSString *ID = @"tuangou";
    MKAnnotationView *annoView = [mapView dequeueReusableAnnotationViewWithIdentifier:ID];
    if (annoView == nil) {
        annoView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:ID];
        annoView.canShowCallout = YES;
    }
Copy the code

MKAnnotationView

The pin control on the map is mk NotationView

  • attribute

    • @property (nonatomic, strong) id annotation;
      • Pin model
    • @property (nonatomic, strong) UIImage *image;
      • Picture displayed
    • @property (nonatomic) BOOL canShowCallout;
      • Whether to show annotations
    • @property (nonatomic) CGPoint calloutOffset;
      • The offset of the annotation
    • @property (strong, nonatomic) UIView *rightCalloutAccessoryView;
      • What controls are displayed to the right of the annotation
    • @property (strong, nonatomic) UIView *leftCalloutAccessoryView;
      • What controls are displayed to the left of the annotation
    • @property (nonatomic, strong) UIView *detailCalloutAccessoryView
      • Annotate what controls to display below (iOS9.0)

MKPinAnnotationView

MKPinAnnotationView is a subclass of MKAnnotationView

  • MKPinAnnotationView has two more attributes than MKAnnotationView

    • @property (nonatomic) MKPinAnnotationColor pinColor;
      • Pin color
    • @property (nonatomic) BOOL animatesDrop;
      • Whether the pin fell from the sky when it first appeared

MKMapItem calls the system APP to navigate

/ / call system according to two landmark object navigation - (void) beginNavWithBeginPlacemark: (CLPlacemark *) beginPlacemark andEndPlacemark: (CLPlacemark MKPlacemark *itemP1 = [[MKPlacemark alloc] initWithPlacemark:beginPlacemark]; MKMapItem *item1 = [[MKMapItem alloc] initWithPlacemark:itemP1]; MKPlacemark *itemP2 = [[MKPlacemark alloc] initWithPlacemark:endPlacemark]; MKMapItem *item2 = [[MKMapItem alloc] initWithPlacemark:itemP2]; NSDictionary * launchDic = @ {/ / set the navigation model parameters MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsMapTypeKey MKLaunchOptionsDirectionsModeDriving, / / set the map type: @ (MKMapTypeHybridFlyover), / / set whether to display traffic MKLaunchOptionsShowsTrafficKey: @ (YES),}; [MKMapItem openMapsWithItems:@[item1, Item2] launchOptions:launchDic]; }Copy the code

MKMapCamera Map street view

/ / create the perspective center coordinates CLLocationCoordinate2D center = CLLocationCoordinate2DMake (23.132931, 113.375924); / / create the 3 d view camera MKMapCamera * = [MKMapCamera cameraLookingAtCenterCoordinate: center FromEyeCoordinate: CLLocationCoordinate2DMake (center. Latitude + 0.001, center longitude + 0.001) eyeAltitude: 1); // Set the map to self.mapView.camera = camera;Copy the code

MKMapSnapshotter map screenshot

MKMapSnapshotOptions *options = [[MKMapSnapshotOptions alloc] init]; // Set the screenshot region (the region on the map, applied on the map) options.region = self.mapview.region; // options.mapRect = self.mapView.visibleMapRect; // Set the size of the image after the screenshot (applied to the output image) options.size = self.mapView.frame.size; Options. scale = [[UIScreen mainScreen] scale]; MKMapSnapshotter *snapshotter = [[MKMapSnapshotter alloc] initWithOptions:options]; [snapshotter startWithCompletionHandler:^(MKMapSnapshot * _Nullable snapshot, NSError * _Nullable error) {if (error) {
            NSLog(@"Screenshot error: %@",error.localizedDescription);
        }else{/ / set the screen picture show the self. The snapshootImageView. Image = the snapshot. The image; NSData *data = UIImagePNGRepresentation(snapshot.image); NSData *data = UIImagePNGRepresentation(snapshot.image); [data writeToFile:@"/Users/wangshunzi/Desktop/snap.png"atomically:YES]; }}];Copy the code

IOS development – map development (CoreLocation and MapKit)