flutter百度地图集成

1,782 阅读6分钟

在flutter项目中用到了百度地图,但是在集成过程中遇到了问题,所以将解决问题的步骤记录下来。一是为了以后别的项目中用到的话有个参考,还有一个就是给遇到相同问题的小伙伴提供一点点帮助。

百度地图集成官网地址:点击跳转

1.百度地图主要是定位SDK。
2.以下步骤都是以新建项目在iPhone手机上运行为基准。

1. 新建项目

首先是新建项目,通过Android Studio创建flutter Application的时候,默认是没有选择Swift和Kotlin的(这是在我的电脑上是这样,你的就不一定了),也就是iOS和Android默认使用的语言是Objective-C和Java。

注意:如果第三方插件在iOS中使用的是Swift语言,跟项目不一致,则需要将项目通过Xcode打开,然后新建一个swift文件,名字随意,Xcode会自动提示是否创建桥接文件。

使用VS Code创建flutter项目的话,在我的电脑上是默认使用的Swift和Kotlin语言的,如果创建完项目想修改未Objective-C和Java的话,需要将项目目录项的ios和android两个文件夹删除,然后在终端中使用以下命令:flutter create -i objc -a java . 即可。

2. 添加依赖

根据官网的步骤,在pubspec.yaml文件中加入以下依赖:

flutter_bmflocation: ^1.0.2

执行命令flutter package get去加载依赖。 然后执行命令flutter run来运行项目。意外的报错了。 报错信息如下:

CocoaPods' output:
↳
      Preparing

    Analyzing dependencies

    Inspecting targets to integrate
      Using `ARCHS` setting to build architectures of target `Pods-Runner`: (``)

    Finding Podfile changes
      A flutter_bmfbase
      A flutter_bmflocation
      R bdmap_location_flutter_plugin
      - Flutter
      - permission_handler

    Fetching external sources
    -> Fetching podspec for `Flutter` from `Flutter`
    -> Fetching podspec for `flutter_bmfbase` from `.symlinks/plugins/flutter_bmfbase/ios`
    -> Fetching podspec for `flutter_bmflocation` from `.symlinks/plugins/flutter_bmflocation/ios`
    [!] No podspec found for `flutter_bmflocation` in `.symlinks/plugins/flutter_bmflocation/ios`

看到最后一行,在ios目录下打开.symlinks/plugins/flutter_bmflocation/ios路径,发现在该路径下面并没有flutter_bmflocation.podspec,反而是有一个bdmap_location_flutter_plugin.podspec,第一直觉就是这里有问题。 为了验证这个问题,就新建了一个文件,命名为:flutter_bmflocation.podspec,然后将bdmap_location_flutter_plugin.podspec中的内容拷贝一份到flutter_bmflocation.podspec,并将文件内的s.name修改未flutter_bmflocation。再次运行flutter run命令,发现还是报错了。😳😳

不过这次报错的信息跟上次的不同了,内容如下:

CocoaPods' output:
↳
      Preparing

    Analyzing dependencies

    Inspecting targets to integrate
      Using `ARCHS` setting to build architectures of target `Pods-Runner`: (``)

    Fetching external sources
    -> Fetching podspec for `Flutter` from `Flutter`
    -> Fetching podspec for `flutter_bmfbase` from `.symlinks/plugins/flutter_bmfbase/ios`
    -> Fetching podspec for `flutter_bmflocation` from `.symlinks/plugins/flutter_bmflocation/ios`
    -> Fetching podspec for `permission_handler` from `.symlinks/plugins/permission_handler/ios`

    Resolving dependencies of `Podfile`
      CDN: trunk Relative path: CocoaPods-version.yml exists! Returning local because checking is
      only perfomed in repo update
      CDN: trunk Relative path: all_pods_versions_3_7_9.txt exists! Returning local because
      checking is only perfomed in repo update
      CDN: trunk Relative path: Specs/3/7/9/BaiduMapKit/5.4.0/BaiduMapKit.podspec.json exists!
      Returning local because checking is only perfomed in repo update
      CDN: trunk Relative path: Specs/3/7/9/BaiduMapKit/5.4.0/BaiduMapKit.podspec.json exists!
      Returning local because checking is only perfomed in repo update

    Comparing resolved specification to the sandbox manifest
      A BaiduMapKit
      A Flutter
      A flutter_bmfbase
      A flutter_bmflocation
      A permission_handler

    Downloading dependencies

    -> Installing BaiduMapKit (5.4.0)
      > Copying BaiduMapKit from
      `/Users/lixiaokang/Library/Caches/CocoaPods/Pods/Release/BaiduMapKit/5.4.0-40a43` to
      `Pods/BaiduMapKit`

    -> Installing Flutter (1.0.0)

    -> Installing flutter_bmfbase (0.0.1)

    -> Installing flutter_bmflocation (0.0.1)

    -> Installing permission_handler (4.4.0+hotfix.4)
      - Running pre install hooks
    [!] The 'Pods-Runner' target has transitive dependencies that include statically linked
    binaries:
    (/Users/lixiaokang/Desktop/mapdemo1/ios/Pods/BaiduMapKit/BaiduMapKit/thirdlibs/libcrypto.a,
    /Users/lixiaokang/Desktop/mapdemo1/ios/Pods/BaiduMapKit/BaiduMapKit/thirdlibs/libssl.a,
    /Users/lixiaokang/Desktop/mapdemo1/ios/Pods/BaiduMapKit/BaiduMapKit/BaiduMapAPI_Base.framework,
    /Users/lixiaokang/Desktop/mapdemo1/ios/Pods/BaiduMapKit/BaiduMapKit/BaiduMapAPI_Cloud.framework
    ,
    /Users/lixiaokang/Desktop/mapdemo1/ios/Pods/BaiduMapKit/BaiduMapKit/BaiduMapAPI_Map.framework,
    /Users/lixiaokang/Desktop/mapdemo1/ios/Pods/BaiduMapKit/BaiduMapKit/BaiduMapAPI_Search.framewor
    k, and
    /Users/lixiaokang/Desktop/mapdemo1/ios/Pods/BaiduMapKit/BaiduMapKit/BaiduMapAPI_Utils.framework
    )
	...

看到下面,猜测是百度地图的某些库没有添加进去。 画面转到百度地图开放平台,看到iOS端需要手动部署百度iOS定位SDK,具体步骤可参照iOS定位SDK手动部署说明

但是不一样的是,BMKLocationKit.framework下载下来之后要放到Pods目录里面,我是跟其他的framework放到一起了,都在BaiduMapKit目录下。还有一个不同之后是添加BMKLocationKit的不是工程名下的TARGET,而是Pods下的TARGETS,也就是flutter_bmflocation

注意:这时候有可能因为pod install失败而没有Pods,可以先进行下面的步骤。或者先引入别的库进行Pod install之后再删掉。 然后进行下面的步骤,需要引入一些系统库文件。 打开Xcode,选择项目名称,也就是Runner,选择TARGETS->Build Phases->Link Binary With Libraries,点击+,添加以下系统库文件: CoreLocation.framework SystemConfiguration.framework Security.framework libsqlite3.0.tbd(xcode7以前为 libsqlite3.0.dylib) CoreTelephony.framework libc++.tbd(因需适配iOS12,需要将libstdc++.6.0.9.tbd 更新为libc++.tbd) AdSupport.framework

3. 申请权限

  1. 在Info.plist中添加定位权限,这个根据需要去选择相关的方式:
    • NSLocationWhenInUseUsageDescription:表示应用在前台的时候可以搜到更新的位置信息;
    • NSLocationAlwaysUsageDescription:表示应用在前台和后台(suspend 或 terminated)都可以获取到更新的位置数据;
    • NSLocationAlwaysAndWhenInUseUsageDescription:申请永久定位权限,以便应用在前台和后台都可以获取位置数据;

代码如下(文字说明根据项目随意更改):

<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
	<string>请求定位权限,获取当前位置</string>
	<key>NSLocationAlwaysUsageDescription</key>
	<string>请求定位权限,获取当前位置</string>
	<key>NSLocationWhenInUseUsageDescription</key>
	<string>请求定位权限,获取当前位置</string>

2. 在Info.plist中添加网络请求权限:App Transport Security Settings。

  1. 在TARGETS->Build Settings->Other Linker Flags 中添加**-ObjC**。

再次运行flutter run命令,报错信息如下:

Xcode's output:
↳
    /Users/lixiaokang/flutter/.pub-cache/hosted/pub.flutter-io.cn/permission_handler-4.4.0+hotfix.4
    /ios/Classes/strategies/NotificationPermissionStrategy.m:71:5: warning:
    'UIRemoteNotificationType' is deprecated: first deprecated in iOS 8.0 - Use UserNotifications
    Framework's UNAuthorizationOptions for user notifications and registerForRemoteNotifications
    for receiving remote notifications instead. [-Wdeprecated-declarations]
        UIRemoteNotificationType type = [[UIApplication sharedApplication]
        enabledRemoteNotificationTypes];
        ^
    In module 'UIKit' imported from /Users/lixiaokang/Desktop/mapdemo2/ios/Pods/Target Support
    Files/permission_handler/permission_handler-prefix.pch:2:
    /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS1
    3.4.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIApplication.h:69:32: note:
    'UIRemoteNotificationType' has been explicitly marked deprecated here
    typedef NS_OPTIONS(NSUInteger, UIRemoteNotificationType) {
                                   ^
    /Users/lixiaokang/flutter/.pub-cache/hosted/pub.flutter-io.cn/permission_handler-4.4.0+hotfix.4
    /ios/Classes/strategies/NotificationPermissionStrategy.m:71:72: warning:
    'enabledRemoteNotificationTypes' is deprecated: first deprecated in iOS 8.0 - Use
    -[UIApplication isRegisteredForRemoteNotifications] and UserNotifications Framework's
    -[UNUserNotificationCenter getNotificationSettingsWithCompletionHandler:] to retrieve
    user-enabled remote notification and user notification settings [-Wdeprecated-declarations]
        UIRemoteNotificationType type = [[UIApplication sharedApplication]
        enabledRemoteNotificationTypes];
                                                                           ^
    In module 'UIKit' imported from /Users/lixiaokang/Desktop/mapdemo2/ios/Pods/Target Support
    Files/permission_handler/permission_handler-prefix.pch:2:
    /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS1
    3.4.sdk/System/Library/Frameworks/UIKit.framework/Headers/UIApplication.h:229:1: note:
    'enabledRemoteNotificationTypes' has been explicitly marked deprecated here
    - (UIRemoteNotificationType)enabledRemoteNotificationTypes API_DEPRECATED("Use -[UIApplication
    isRegisteredForRemoteNotifications] and UserNotifications Framework's
    -[UNUserNotificationCenter getNotificationSettingsWithCompletionHandler:] to retrieve
    user-enabled remote notification and user notification settings", ios(3.0, 8.0))
    API_UNAVAILABLE(tvos);
    ^
    2 warnings generated.
    /Users/lixiaokang/flutter/.pub-cache/hosted/pub.flutter-io.cn/flutter_bmflocation-1.0.2/ios/Cla
    sses/BdmapLocationFlutterPlugin.m:3:9: fatal error: 'BMKLocationkit/BMKLocationComponent.h'
    file not found
    #import "BMKLocationkit/BMKLocationComponent.h"
            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    1 error generated.
    note: Using new build system
    note: Building targets in parallel
    note: Planning build
    note: Constructing build description
    warning: The iOS deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 7.0, but the range of
    supported deployment target versions is 8.0 to 13.4.99. (in target 'BaiduMapKit' from project
    'Pods')

我这里是在前面没有添加BMKLocationKit.framework,所以报这个错。 看到错误信息是找不到BMKLocationComponent.h。现在就用到前面下载的BMKLocationKit.framework了。 先找到项目的路径,打开ios->Pods目录,看到有个文件夹:BaiduMapKit。这个里面放着百度地图的一些SDK和framework,将下载好的BMKLocationKit.framework拖进去。然后打开Xcode,选中Pods,在TARGETS中选择flutter_bmflocation,选择Build Phases -> Link Binary With Libraries,点击+号,选择Add Other -> Add Files。 如下图所示:

中间有几次明明已经将BMKLocationKit导入进去了,但是却没起作用。导致这一步重复了好几次。

再次运行flutter run命令,项目终于跑起来了。

添加依赖的这几个步骤是必不可少的,但是顺序没有要求。相应的错误信息都有相应的解决办法,多尝试几次总会解决的。

参考文章: flutter 集成百度地图