背景
在iOS15版本下,使用final class并继承BMKMapViewDelegate
类是可以直接将UIKit集成至SwiftUI的,但是在iOS16及以上版本,该方法失效,具体表现为程序运行异常。
swift
final class BMView: UIViewController, BMKMapViewDelegate {
private var mapView: BMKMapView?
override func viewDidLoad() {
super.viewDidLoad()
mapView = BMKMapView(frame: self.view.frame)
mapView?.delegate = self
mapView?.zoomLevel = zoomLevel ?? 17
self.view.addSubview(mapView!);
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
mapView?.viewWillAppear()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
mapView?.viewWillDisappear()
}
}
因此需要换一种方式来集成百度地图,在这篇文章中,将会以协调器(Coordinator)来兼容UIKit,并继承百度地图组件。
集成步骤
接下来将会从基础环境的配置,到组件封装来介绍整个集成过程。
百度开发者注册
进入lbsyun.baidu.com/,如果没有账号则注册;在【应用管理】-> 【我的应用】里面点击创建应用,在完成后,获取到列表上的【访问应用(AK)】的值。
配置基础环境
- 确保ruby版本在3.0以上,低于该版本,则需要升级,在这里不做具体阐述
- 安装cocoapods
sudo gem install -n /usr/local/bin cocoapods
- 进入项目后,
pod setup
- 等待安装完成
项目集成百度地图环境
增加百度地图依赖
在项目根目录下编辑Podfile(不存在则创建)
arduino
platform :ios, '17.4' #手机的系统
target 'YourProjectTarget' do
pod 'BaiduMapKit', '6.6.1'
# 可选组件
# pod 'BaiduMapKit/Map', '6.6.1' # 集成地图Map包
# pod 'BaiduMapKit/Search', '6.6.1' # 集成地图Search包
# pod 'BaiduMapKit/Utils', '6.6.1' # 集成地图Utils包
end
执行安装 pod install
在完成后,会在根目录下生成:.xcworkspace
文件
创建桥头文件
在项目根目录下创建Configuration/BMK-Bridge-Header
,将涉及到需要使用的百度地图头文件信息引入
arduino
#ifndef BMKSwift_Bridging_Header_h
#define BMKSwift_Bridging_Header_h
#import <BaiduMapAPI_Base/BMKBaseComponent.h>//引入base相关所有的头文件
#import <BaiduMapAPI_Map/BMKMapComponent.h>//引入地图功能所有的头文件
#import <BaiduMapAPI_Search/BMKSearchComponent.h>//引入检索功能所有的头文件
#import <BaiduMapAPI_Utils/BMKUtilsComponent.h>//引入计算工具所有的头文件
#import <BaiduMapAPI_Map/BMKMapView.h>//只引入所需的单个头文件
#endif /* BMKSwift_Bridging_Header_h */
在 TARGETS->Build Settings->Swift Compiler -> General -> Objective-C Briding Header 中输入桥接文件的路径(该路径要和桥接头文件所在的目录一致),如下图所示:
增加ATS支持
从项目根目录下 Pods -> BiaduMapKit -> BaiduMapKit -> thirdlibs 下,将libssl.a
和 libcrypto.a
两文件复制到项目根路径下 libs
在 TARGETS->Build Phases-> Link Binary With Libaries中点击"+"按钮,在弹出的窗口中点击"Add Other"按钮,选择libssl.a和libcrypto.a添加到工程中。
创建地图组件
swift
import SwiftUI
struct RestaurantMap: UIViewControllerRepresentable {
var zoomLevel: Float?
var width: Int?
var height: Int?
func makeUIViewController(context: Context) -> UIViewController {
return context.coordinator
}
func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
}
func makeCoordinator() -> Coordinator {
Coordinator(zoomLevel: zoomLevel, width: width, height: height)
}
internal class Coordinator: UIViewController, BMKMapViewDelegate {
private var zoomLevel: Float?
private var width: Int?
private var height: Int?
private var mapView: BMKMapView?
init(zoomLevel: Float? = nil, width: Int? = nil, height: Int? = nil) {
super.init(nibName: nil, bundle: nil)
self.zoomLevel = zoomLevel
self.width = width
self.height = height
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
mapView = BMKMapView(frame: CGRect(x: 0, y: 0, width: width ?? Int(self.view.frame.width), height: height ?? Int(self.view.frame.height)))
mapView?.delegate = self
mapView?.zoomLevel = zoomLevel ?? 17
self.view.addSubview(mapView!);
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
mapView?.viewWillAppear()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
mapView?.viewWillDisappear()
}
}
}