iOS macOS 地图使用原生demo
iOS中想要定位用户信息,需要向用户申请对应的权限,主要有三种:
NSLocationWhenInUseUsageDescription 应用使用期间
NSLocationAlwaysUsageDescription 始终允许
NSLocationAlwaysAndWhenInUseUsageDescription (始终允许,iOS11新增)
在iOS11时,NSLocationAlwaysAndWhenInUseUsageDescription表示始终允许,NSLocationAlwaysUsageDescription在功能上被降级为为“应用使用期间”。
需要把对应的权限添加在info.plist中
在使用的时候需要用CLLocationManager请求对应的权限
前台获取位置信息授权:requestWhenInUseAuthorization
后台获取位置信息授权:requestAlwaysAuthorization
当你使用的权限大于你所申请的权限是,会出现蓝条,类似高德地图;
下面是一个简单的Objective-C (OC) 示例,演示了如何在iOS应用中集成MapKit和CoreLocation以显示用户当前位置:
首先,确保你的Xcode项目已经链接了MapKit.framework
和CoreLocation.framework
。
- 在你的ViewController头文件中(例如
ViewController.h
),导入必要的框架并声明所需的属性
#import <UIKit/UIKit.h> #import <MapKit/MapKit.h> #import <CoreLocation/CoreLocation.h> @interface ViewController : UIViewController <CLLocationManagerDelegate, MKMapViewDelegate> @property (nonatomic, strong) MKMapView *mapView; @property (nonatomic, strong) CLLocationManager *locationManager; @end
- 在你的ViewController实现文件中(例如
ViewController.m
),设置mapView和locationManager,并请求定位权限:
#import "ViewController.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // 初始化mapView self.mapView = [[MKMapView alloc] initWithFrame:self.view.bounds]; self.mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; self.mapView.delegate = self; self.mapView.mapType = MKMapTypeStandard; // 设置地图类型为标准 self.mapView.showsUserLocation = YES; // 显示用户当前位置(需要用户授权) self.mapView.zoomEnabled = YES; // 允许缩放 self.mapView.scrollEnabled = YES; // 允许滚动 [self.view addSubview:self.mapView]; // 初始化locationManager self.locationManager = [[CLLocationManager alloc] init]; self.locationManager.delegate = self; self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;// 设置精度 self.locationManager.distanceFilter = kCLDistanceFilterNone; // 立即更新位置,不基于距离过滤 // 异步加载数据 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // 检查定位服务是否可用 if ([CLLocationManager locationServicesEnabled]) { // 检查应用是否有权限访问定位服务 [self.locationManager requestWhenInUseAuthorization]; // 如果你需要后台定位权限,可以使用 requestAlwaysAuthorization } // 处理数据... // 回到主线程更新UI dispatch_async(dispatch_get_main_queue(), ^{ // 更新UI,例如: // 开始更新位置 [self.locationManager startUpdatingLocation]; }); }); } #pragma mark - CLLocationManagerDelegate - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations { // 获取最新位置 CLLocation *latestLocation = [locations lastObject]; // 停止更新位置(如果你不需要持续更新) [self.locationManager stopUpdatingLocation]; // 设置mapView的中心坐标和缩放级别 MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(latestLocation.coordinate, 800, 800); [self.mapView setRegion:region animated:YES]; // 如果你还想在地图上添加一个标注来表示用户位置,可以这样做: MKPointAnnotation *point = [[MKPointAnnotation alloc] init]; point.coordinate = latestLocation.coordinate; point.title = @"当前位置"; [self.mapView addAnnotation:point]; } - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error { // 处理定位失败的情况 NSLog(@"定位失败: %@", error); } @end
请注意,在iOS 10及更高版本中,你需要在Info.plist
文件中添加NSLocationWhenInUseUsageDescription
或NSLocationAlwaysUsageDescription
键,以解释为什么你的应用需要访问用户的位置信息。否则,应用将不会请求定位权限。
此外,确保你的ViewController在不再需要时(例如在viewDidDisappear:
方法中)停止更新位置,以节省电池和网络资源。
⚠️注意补充一下设置部分
<key>NSLocationWhenInUseUsageDescription</key> <string>App需要您的同意,才能在使用期间访问位置</string> <key>NSLocationUsageDescription</key> <string>App需要您的同意,才能访问位置</string> <key>NSLocationAlwaysUsageDescription</key> <string>App需要您的同意,才能始终访问位置</string>
到这步界面出来了,但是还不是我们想要的效果
我们需要经纬度坐标控制定位信息
#pragma mark - CLLocationManagerDelegate - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations { // 获取最新位置 CLLocation *latestLocation = [locations lastObject]; // 打印经纬度 NSLog(@"Latitude: %f, Longitude: %f", latestLocation.coordinate.latitude, latestLocation.coordinate.longitude); // 停止更新位置(如果你不需要持续更新)(如果你只需要获取一次位置) [self.locationManager stopUpdatingLocation]; // 设置mapView的中心坐标和缩放级别 MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(latestLocation.coordinate, 800, 800); [self.mapView setRegion:region animated:YES]; // 如果你还想在地图上添加一个标注来表示用户位置,可以这样做: MKPointAnnotation *point = [[MKPointAnnotation alloc] init]; point.coordinate = latestLocation.coordinate; point.title = @"当前位置"; [self.mapView addAnnotation:point]; // 假设你有一个经纬度 CLLocationDegrees latitude = -33.8571126363083; // 悉尼的纬度示例 CLLocationDegrees longitude = 151.2151193250122; // 悉尼的经度示例 CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(22.511973,113.922009); // 深圳的经纬度 // 创建一个CLLocation对象 CLLocation *location = [[CLLocation alloc] initWithCoordinate:coordinate altitude:0 horizontalAccuracy:kCLLocationAccuracyBest verticalAccuracy:kCLLocationAccuracyBest timestamp:nil]; // 初始化CLGeocoder CLGeocoder *geocoder = [[CLGeocoder alloc] init]; // 使用CLGeocoder进行反向地理编码 [geocoder reverseGeocodeLocation:location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) { if (error) { NSLog(@"Geocode failed with error: %@", error); return; } if (placemarks && placemarks.count > 0) { CLPlacemark *placemark = placemarks[0]; // 输出位置信息 NSLog(@"Placemark: %@", placemark); NSLog(@"ISO 国家代号: %@", placemark.ISOcountryCode); NSLog(@"国家: %@", placemark.country); NSLog(@"城市 (City): %@", placemark.locality); NSLog(@"区县 (Suburb, Town, etc.): %@", placemark.subLocality); NSLog(@"邮政编码: %@", placemark.postalCode); NSLog(@"具体地址 (Street Name): %@", placemark.thoroughfare); NSLog(@"街道编号,街道名称扩展 (Street Number, Street Name Extension): %@", placemark.subThoroughfare); // 如果你需要更详细的地址组件,可以遍历placemark的addressComponents数组 // for (CLLocationAddressComponent *component in placemark.addressComponents) { // NSLog(@"Address Component Type: %@, Value: %@", component.type, component.value); // } } }];
运行即可得到国内深圳的当前位置地理信息
如果切换到外国就会报错请看下一篇解决海外地理位置 https://www.cnblogs.com/gaozhang12345/p/18178990