IOS接入百度地图SDK,百度定位SDK记录

地图显示

  1. Xcode新建一个项目,我取名叫BaiduMapIOSAgain,包名为com.unity.BaiduMapIOSAgain.
  2. 在百度SDK的控制台创建应用,过程略,跟着官方说明即可在这里插入图片描述
    首先先显示地图,跟着官方文档做即可,有些许步骤补充一下,建议使用Pods自动配置,使用objective-c的话我第一次做的时候总是莫名其妙报错说明找不到文件,后来使用Pods配置没有这个问题,安装Pods百度即可
    ------这里说明一下,到这一步我使用这个指令没有效果,建议使用touch Podfile
    在这里插入图片描述
    之后的文件夹应该是这样的
    在这里插入图片描述
    编辑Podfile内容时还有一点要注意,文档要这么写
platform :ios, '7.0' #手机的系统
target 'BaiduMapIOSAgain' do #工程名字
  pod “BaiduMapKit” #百度地图SDK
end 

把do放到上一行,不然会报错

  1. 这里的配置建议添加一下,指不定是哪个地方就有影响了在这里插入图片描述
    打开工程之后把AppDelegate.m名字改成AppDelegate.mm,下面的ViewController.m也是改成ViewController.mm
  2. 依旧跟着官方文档的显示地图这一步,这一整页的内容都是放在AppDelegate脚本里在这里插入图片描述直接复制官方代码,会报两个错误,如下在这里插入图片描述
    第一个错误直接点下红点或者在变量前面加个下划线即可,第二个错误需要在上面添加一行
    @property (nonatomic, strong) UINavigationController *navigationController;
    然后还会出现红点,点一下fix即可
    另外不要忘了填入AK
  3. 在创建BMKMapView这一步中的代码是在ViewController.mm进行,复制代码,出现一个报错在这里插入图片描述
    这个报错目前我没有发现解决方案,就直接给注释掉了,如果有哪个大神知道怎么解决欢迎评论
  4. 官方文档到这就结束了,按理说可以出现地图了,但是一运行坑爹的地方就来了,白屏,后来发现是少了一行代码self.view = _mapView;
- (void)viewDidLoad {
    [super viewDidLoad];
    _mapView = [[BMKMapView alloc]initWithFrame:self.view.bounds];
    _mapView.delegate = self;
    [_mapView setMapType:BMKMapTypeStandard]; //切换为标准地图
    //设置为GCJ02坐标
    [BMKMapManager setCoordinateTypeUsedInBaiduMapSDK: BMK_COORDTYPE_COMMON];
    //[self.view addSubView:_mapView];
    self.view = _mapView;
}

这样还不够,在Info.plist文件里没有填Bundle identifier,需要填上
到这地图就可以显示了,默认定位在北京

定位显示

在跟着官方文档之前继续看地图SDK 的文档,下面有显示定位,将代码添加

  1. 同样跟着官方文档
  2. 导入定位的Pods之后重新打开工程
  3. 在单次定位的配置AK这一步复制代码之后会报错在这里插入图片描述
    解决方法是
@interface ViewController ()<BMKMapViewDelegate,BMKLocationAuthDelegate>
  1. viewDidLoad方法里添加第三步(设置期望定位精度)的代码
    依然会报错在这里插入图片描述
    解决方法是上面添加一行
@property (nonatomic, strong) BMKLocationManager *locationManager;

同时修改

@interface ViewController ()<BMKMapViewDelegate,BMKLocationAuthDelegate,BMKLocationManagerDelegate>
  1. 下面到第四步(请求定位并拿到结果),复制官方代码,还是会报错在这里插入图片描述
    解决方法是加一行
@property (nonatomic, strong) BMKLocatingCompletionBlock completionBlock;

然后在大括号后面加个分号 ;


官方文档到这应该就能实现定位了,但是运行之后还是定位在北京,同时打印台说

BaiduMapIOSAgain[3354:843521] [NetworkInfo] Signal strength query returned error: Error Domain=NSPOSIXErrorDomain Code=13 "Permission denied", descriptor: <CTServiceDescriptor 0x281602ec0, domain=1, instance=1>

权限不够,那就加上权限呗

6.打开info.plist,右键Add Row添加三个权限 NSLocationWhenInUseUsageDescription,NSLocationAlwaysUsageDescription,NSLocationAlwaysAndWhenInUseUsageDescription

再次运行,还是不行,那继续跟着官方走,连续定位也加上,反正咱头一次搞iOS啥也不懂跟着官方就完事了
7. 把连续定位的代码加上之后,运行,控制台说can not start loc in locationg!
再看下代码,连续定位第五步(接受位置更新)的代码和地图SDK的方法有些重复,合并一下

// 接收位置更新
- (void)BMKLocationManager:(BMKLocationManager * _Nonnull)manager didUpdateLocation:(BMKLocation * _Nullable)location orError:(NSError * _Nullable)error

{
    if (error)
    {
        NSLog(@"locError:{%ld - %@};", (long)error.code, error.localizedDescription);
    } if (location) {//得到定位信息,添加annotation
        
        if (location.location) {
            NSLog(@"LOC = %@",location.location);
        }
        if (location.rgcData) {
            NSLog(@"rgc = %@",[location.rgcData description]);
        }
        
        if (location.rgcData.poiList) {
            for (BMKLocationPoi * poi in location.rgcData.poiList) {
                NSLog(@"poi = %@, %@, %f, %@, %@", poi.name, poi.addr, poi.relaiability, poi.tags, poi.uid);
            }
        }
        
        if (location.rgcData.poiRegion) {
            NSLog(@"poiregion = %@, %@, %@", location.rgcData.poiRegion.name, location.rgcData.poiRegion.tags, location.rgcData.poiRegion.directionDesc);
        }
        
    }
    else{
        return;
    }
    if (!self.userLocation) {
        self.userLocation = [[BMKUserLocation alloc] init];
    }
    self.userLocation.location = location.location;
    [self.mapView updateLocationData:self.userLocation];
    
}

到这文档基本就结束了,但是定位还在北京并且控制台还在报错,没办法只能去百度,一番查找后代码为这样ViewController.mm

//
//  ViewController.m
//  BaiduMapIOSAgain
//
//  Created by 007 on 2019/10/30.
//  Copyright © 2019年 007. All rights reserved.
//

#import "ViewController.h"
#import <BaiduMapAPI_Base/BMKBaseComponent.h>//引入base相关所有的头文件
#import <BaiduMapAPI_Map/BMKMapComponent.h>//引入地图功能所有的头文件
#import <BMKLocationkit/BMKLocationComponent.h>
@interface ViewController ()<BMKMapViewDelegate,BMKLocationAuthDelegate,
BMKLocationManagerDelegate,CLLocationManagerDelegate>
@property (nonatomic, strong) BMKMapView *mapView;
@property (nonatomic, strong) BMKLocationManager *locationManager;
@property (nonatomic, strong) BMKLocatingCompletionBlock completionBlock;
@property (nonatomic, strong) BMKUserLocation *userLocation; //当前位置对象
@property(retain, nonatomic) CLLocationManager* cLLocationManager;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [[BMKLocationAuth sharedInstance] checkPermisionWithKey:@"R7zxHCt4s3CrgIuYQf1OV692b4aZAFl2" authDelegate:self];
    _mapView = [[BMKMapView alloc]initWithFrame:self.view.bounds];
    _mapView.delegate = self;
    
    //显示定位图层
    _mapView.showsUserLocation = YES;
    //[self.view addSubView:_mapView];
    //设置为GCJ02坐标
    [BMKMapManager setCoordinateTypeUsedInBaiduMapSDK: BMK_COORDTYPE_COMMON];
    // 定位方向模式
    _mapView.userTrackingMode = BMKUserTrackingModeFollow;
    //切换为标准地图
    [_mapView setMapType:BMKMapTypeStandard];
    
    // 开启持续定位
    [self.locationManager startUpdatingLocation];
    // 持续定位返回地址信息
    [self.locationManager setLocatingWithReGeocode:YES];
    [self.locationManager startUpdatingLocation];
    
    // 打开获取权限弹窗
    self.cLLocationManager = [[CLLocationManager alloc] init];
    [_cLLocationManager requestAlwaysAuthorization];
    [_cLLocationManager requestWhenInUseAuthorization];
    
    //初始化实例
    _locationManager = [[BMKLocationManager alloc] init];
    //设置delegate
    _locationManager.delegate = self;
    //设置返回位置的坐标系类型
    _locationManager.coordinateType = BMKLocationCoordinateTypeBMK09LL;
    //设置距离过滤参数
    _locationManager.distanceFilter = kCLDistanceFilterNone;
    //设置预期精度参数
    _locationManager.desiredAccuracy = kCLLocationAccuracyBest;
    //设置应用位置类型
    _locationManager.activityType = CLActivityTypeAutomotiveNavigation;
    //设置是否自动停止位置更新
    _locationManager.pausesLocationUpdatesAutomatically = NO;
    //设置是否允许后台定位
    _locationManager.allowsBackgroundLocationUpdates = YES;
    //设置位置获取超时时间
    _locationManager.locationTimeout = 10;
    //设置获取地址信息超时时间
    _locationManager.reGeocodeTimeout = 10;
    
    
    self.completionBlock = ^(BMKLocation *location, BMKLocationNetworkState state, NSError *error)
    {
        if (error)
        {
            NSLog(@"单次定位 本地错误:{%ld - %@};", (long)error.code, error.localizedDescription);
        }
        if (location) {//得到定位信息,添加annotation
            
            if (location.location) {
                NSLog(@"本地 = %@",location.location);
            }
            if (location.rgcData) {
                NSLog(@"rgc = %@",[location.rgcData description]);
            }
            
            if (location.rgcData.poiList) {
                for (BMKLocationPoi * poi in location.rgcData.poiList) {
                    NSLog(@"坐标= %@, %@, %f, %@, %@", poi.name, poi.addr, poi.relaiability, poi.tags, poi.uid);
                }
            }
            
            if (location.rgcData.poiRegion) {
                NSLog(@"坐标地区 = %@, %@, %@", location.rgcData.poiRegion.name, location.rgcData.poiRegion.tags, location.rgcData.poiRegion.directionDesc);
            }
            
        }
    };
    

    self.view = _mapView;
}

//由于以下代理方法中分别且仅只返回heading或location信息,请开发者务必将该对象定义为全局类型,避免在以下回调用使用局部的BMKUserLocation对象,导致出现定位显示错误位置的情况。
// 定位SDK中,方向变更的回调
- (void)BMKLocationManager:(BMKLocationManager *)manager didUpdateHeading:(CLHeading *)heading {
    if (!heading) {
        return;
    }
    if (!self.userLocation) {
        self.userLocation = [[BMKUserLocation alloc] init];
    }
    self.userLocation.heading = heading;
    [self.mapView updateLocationData:self.userLocation];
}

// 接收位置更新
- (void)BMKLocationManager:(BMKLocationManager * _Nonnull)manager didUpdateLocation:(BMKLocation * _Nullable)location orError:(NSError * _Nullable)error

{
    if (error)
    {
        NSLog(@"locError:{%ld - %@};", (long)error.code, error.localizedDescription);
    } if (location) {//得到定位信息,添加annotation
        
        if (location.location) {
            NSLog(@"LOC = %@",location.location);
        }
        if (location.rgcData) {
            NSLog(@"rgc = %@",[location.rgcData description]);
        }
        
        if (location.rgcData.poiList) {
            for (BMKLocationPoi * poi in location.rgcData.poiList) {
                NSLog(@"poi = %@, %@, %f, %@, %@", poi.name, poi.addr, poi.relaiability, poi.tags, poi.uid);
            }
        }
        
        if (location.rgcData.poiRegion) {
            NSLog(@"poiregion = %@, %@, %@", location.rgcData.poiRegion.name, location.rgcData.poiRegion.tags, location.rgcData.poiRegion.directionDesc);
        }
        
    }
    else{
        return;
    }
    if (!self.userLocation) {
        self.userLocation = [[BMKUserLocation alloc] init];
    }
    self.userLocation.location = location.location;
    [self.mapView updateLocationData:self.userLocation];
    
}
- (void)BMKLocationManager:(BMKLocationManager *)manager doRequireLocationAuth:(CLLocationManager*)locationManager
{
    [locationManager requestAlwaysAuthorization];
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

-(void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [_mapView viewWillAppear];
    _mapView.delegate=self;//此处记得不用的时候置nil,否则影响内存的释放
    NSLog(@"显示");
}
-(void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    [_mapView viewWillDisappear];
    _mapView.delegate=nil;//不用时,置nil
    // 不需要定位时停止持续定位
    [self.locationManager stopUpdatingLocation];
    NSLog(@"隐藏");
}

@end


下面是AppDelegate.mm

//
//  AppDelegate.m
//  BaiduMapIOSAgain
//
//  Created by 007 on 2019/10/30.
//  Copyright © 2019年 007. All rights reserved.
//

#import "AppDelegate.h"
#import <BaiduMapAPI_Base/BMKBaseComponent.h>//引入base相关所有的头文件
@interface AppDelegate ()
@property (nonatomic, strong) UINavigationController *navigationController;
@property(assign, nonatomic) CLLocationAccuracy desiredAccuracy;
@property(assign, nonatomic) CLLocationManager* cLLocationManager;
@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // 要使用百度地图,请先启动BaiduMapManager
    BMKMapManager *mapManager = [[BMKMapManager alloc] init];
    // 如果要关注网络及授权验证事件,请设定generalDelegate参数
    BOOL ret = [mapManager start:@"R7zxHCt4s3CrgIuYQf1OV692b4aZAFl2"  generalDelegate:nil];
    if (!ret) {
        NSLog(@"m百度地图启动失败");
    }else   {
        NSLog(@"m百度地图启动成功");
    }
    
    /**
     全局设置地图SDK与开发者交互时的坐标类型。不调用此方法时,
     
     设置此坐标类型意味着2个方面的约定:
     1. 地图SDK认为开发者传入的所有坐标均为此类型;
     2. 所有地图SDK返回给开发者的坐标均为此类型;
     
     地图SDK默认使用BD09LL(BMK_COORDTYPE_BD09LL)坐标。
     如需使用GCJ02坐标,传入参数值为BMK_COORDTYPE_COMMON即可。ß
     本方法不支持传入WGS84(BMK_COORDTYPE_GPS)坐标。
     
     @param coorType 地图SDK全局使用的坐标类型
     @return 设置成功返回YES,设置失败返回False
     */
    [self.window addSubview:_navigationController.view];
    [self.window makeKeyAndVisible];
    //设置为GCJ02坐标
    [BMKMapManager setCoordinateTypeUsedInBaiduMapSDK: BMK_COORDTYPE_COMMON];
    return YES;
}

/**
 获取位置验证权限(作用域: 地图 & 定位相关)
 @param vc 当前视图控件
 */
- (void)YHGetLocationPermissionVerifcationWithController:(UIViewController *)vc {
    BOOL enable = [CLLocationManager locationServicesEnabled];
    NSInteger state = [CLLocationManager authorizationStatus];
    
    if (!enable || 2 > state) {// 尚未授权位置权限
        if (8 <= [[UIDevice currentDevice].systemVersion floatValue]) {
            NSLog(@"系统位置权限授权弹窗");
            if ([CLLocationManager instancesRespondToSelector:@selector(requestAlwaysAuthorization)])
            {
                // 系统位置权限授权弹窗
                self.cLLocationManager = [[CLLocationManager alloc] init];
                [_cLLocationManager requestAlwaysAuthorization];
                [_cLLocationManager requestWhenInUseAuthorization];
                
            }
        }
    }
    else {
        if (state == kCLAuthorizationStatusDenied) {// 授权位置权限被拒绝
            NSLog(@"授权位置权限被拒绝");
            UIAlertController *alertCon = [UIAlertController alertControllerWithTitle:@"提示"
                                                                              message:@"访问位置权限暂未授权"
                                                                       preferredStyle:UIAlertControllerStyleAlert];
            [alertCon addAction:[UIAlertAction actionWithTitle:@"暂不设置" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
                
            }]];
            
            [alertCon addAction:[UIAlertAction actionWithTitle:@"设置" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
                dispatch_after(0.2, dispatch_get_main_queue(), ^{
                    NSURL *url = [[NSURL alloc] initWithString:UIApplicationOpenSettingsURLString];// 跳转至系统定位授权
                    if( [[UIApplication sharedApplication] canOpenURL:url]) {
                        [[UIApplication sharedApplication] openURL:url];
                    }
                });
            }]];
            
            [vc presentViewController:alertCon animated:YES completion:^{
                
            }];
        }
    }
}



- (void)applicationWillResignActive:(UIApplication *)application {
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}


- (void)applicationDidEnterBackground:(UIApplication *)application {
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}


- (void)applicationWillEnterForeground:(UIApplication *)application {
    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}


- (void)applicationDidBecomeActive:(UIApplication *)application {
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}


- (void)applicationWillTerminate:(UIApplication *)application {
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}


@end

出现定位了,但是定位显示在几内亚湾,头疼,后面还没解决完

此篇博客为我自己摸索iOS接入百度的SDK记录,可能有步骤或代码是错的,如有发现不吝赐教

发布了57 篇原创文章 · 获赞 22 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/Mediary/article/details/102821170