iOS macOS 地图使用原生demo

iOS中想要定位用户信息,需要向用户申请对应的权限,主要有三种:
NSLocationWhenInUseUsageDescription 应用使用期间
NSLocationAlwaysUsageDescription 始终允许
NSLocationAlwaysAndWhenInUseUsageDescription (始终允许,iOS11新增)
在iOS11时,NSLocationAlwaysAndWhenInUseUsageDescription表示始终允许,NSLocationAlwaysUsageDescription在功能上被降级为为“应用使用期间”。
需要把对应的权限添加在info.plist中

在使用的时候需要用CLLocationManager请求对应的权限
前台获取位置信息授权:requestWhenInUseAuthorization
后台获取位置信息授权:requestAlwaysAuthorization
当你使用的权限大于你所申请的权限是,会出现蓝条,类似高德地图;

下面是一个简单的Objective-C (OC) 示例,演示了如何在iOS应用中集成MapKit和CoreLocation以显示用户当前位置:

首先,确保你的Xcode项目已经链接了MapKit.frameworkCoreLocation.framework

  1. 在你的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
  1. 在你的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文件中添加NSLocationWhenInUseUsageDescriptionNSLocationAlwaysUsageDescription键,以解释为什么你的应用需要访问用户的位置信息。否则,应用将不会请求定位权限。

此外,确保你的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

posted on 2024-05-08 10:24  高彰  阅读(45)  评论(0编辑  收藏  举报

导航