Swift中Mapbox Maps包编译报错:找不到ResourceOptions
解决Mapbox中“Cannot find 'ResourceOptions' in scope”编译错误
问题说明
使用Swift和Mapbox Navigation SDK开发时,代码编译失败,提示“Cannot find 'ResourceOptions' in scope”,已检查包安装和依赖配置但未解决问题。
核心原因及解决方案
1. 缺失必要框架导入
ResourceOptions 属于 MapboxCoreNavigation 模块,而非当前导入的MapboxMaps。需在代码开头补充导入:
import MapboxCoreNavigation
2. 依赖版本不兼容
需确认Mapbox相关包版本是否匹配:
- 保证
MapboxMaps与MapboxCoreNavigation版本一致,避免跨版本API差异 - 使用Swift Package Manager时,检查包的版本约束是否为官方推荐的兼容组合
3. 简化初始化逻辑(适配新版SDK)
部分新版Mapbox SDK已支持直接在MapInitOptions中传入accessToken,无需手动创建ResourceOptions,可替换为:
let mapInitOptions = MapInitOptions(accessToken: accessToken, styleURI: .streets) mapView = MapView(frame: view.bounds, mapInitOptions: mapInitOptions)
4. 清理Xcode缓存
缓存可能导致依赖识别异常,执行以下操作:
- 清理项目:按下
Command + Shift + K - 删除DerivedData:前往
~/Library/Developer/Xcode/DerivedData删除对应项目文件夹 - 重启Xcode后重新构建
修改后的完整代码示例
import UIKit import MapboxMaps import MapboxCoreNavigation // 添加必要导入 /// 管理Mapbox地图标注的视图控制器 class AnnotationsMapViewController: UIViewController { /// Mapbox地图视图 var mapView: MapView! /// 管理地图标注的视图模型 var viewModel: AnnotationsMapViewModel? /// 视图加载完成后调用 override func viewDidLoad() { super.viewDidLoad() // 填入你的Mapbox访问令牌 let accessToken = "Put Access Token Here" // 方案1:使用ResourceOptions(需导入MapboxCoreNavigation) let resourceOptions = ResourceOptions(accessToken: accessToken) let mapInitOptions = MapInitOptions(resourceOptions: resourceOptions, styleURI: .streets) // 方案2:直接传入accessToken(无需手动创建ResourceOptions) // let mapInitOptions = MapInitOptions(accessToken: accessToken, styleURI: .streets) // 初始化地图视图 mapView = MapView(frame: view.bounds, mapInitOptions: mapInitOptions) mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight] view.addSubview(mapView) // 地图样式加载完成后配置标注管理器 mapView.mapboxMap.onNext(event: .styleLoaded) { [weak self] _ in guard let self = self else { return } self.setupAnnotationManagers() self.updateAnnotations() self.setupGestureRecognizers() } } // MARK: - 配置标注管理器 /** 配置点标注和折线标注的管理器 若管理器未初始化,则创建实例,并打印初始化状态到控制台 */ private func setupAnnotationManagers() { guard let mapView = mapView else { return } if viewModel?.pointAnnotationManager == nil { viewModel?.pointAnnotationManager = mapView.annotations.makePointAnnotationManager() print("***** PointAnnotationManager初始化完成: \(viewModel?.pointAnnotationManager != nil)") } if viewModel?.polylineAnnotationManager == nil { viewModel?.polylineAnnotationManager = mapView.annotations.makePolylineAnnotationManager() print("***** PolylineAnnotationManager初始化完成: \(viewModel?.polylineAnnotationManager != nil)") } } // MARK: - 更新标注 /** 通过点标注管理器更新地图上的标注 从视图模型获取标注数据并设置到管理器,同时调用视图模型的折线更新方法 */ func updateAnnotations() { guard let viewModel = viewModel else { return } viewModel.pointAnnotationManager?.annotations = viewModel.annotations viewModel.updatePolylines() // 确保调用此方法应用更新 } // MARK: - 配置手势识别器 /** 配置用于处理标注选择的手势识别器 给地图视图添加点击手势,触发标注点击处理方法 */ private func setupGestureRecognizers() { guard let mapView = mapView else { return } let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleAnnotationTap(_:))) mapView.addGestureRecognizer(tapGestureRecognizer) } // MARK: - 处理标注点击 /** 处理标注的点击手势 查询点击位置的渲染特征,识别并选择对应的标注或折线;若未找到匹配项,则取消折线选中状态 - Parameter sender: 点击手势识别器 */ @objc private func handleAnnotationTap(_ sender: UITapGestureRecognizer) { guard let mapView = mapView, let viewModel = viewModel else { return } let point = sender.location(in: mapView) // 调整点击检测的缓冲范围 let buffer: CGFloat = 1.0 // 屏幕点单位的缓冲大小 let hitbox = CGRect(x: point.x - buffer, y: point.y - buffer, width: 2 * buffer, height: 2 * buffer) // 使用检测范围 // 查询检测范围内的渲染特征 let options = RenderedQueryOptions(layerIds: ["annotations-layer"], filter: nil) mapView.mapboxMap.queryRenderedFeatures(in: hitbox, options: options) { result in switch result { case .success(let features): print("***** 检测到特征数量: \(features.count)") for feature in features { if let userInfo = feature.feature.properties?["userInfo"] as? Turf.JSONValue, case let .object(annotationInfo) = userInfo, let annotationIdValue = annotationInfo["annotation-id"], case let .string(annotationId) = annotationIdValue { if let selectedAnnotation = viewModel.annotations.first(where: { ($0.userInfo?["annotation-id"] as? String) == annotationId }) { viewModel.selectAnnotation(selectedAnnotation) print("***** 选中标注ID: \(annotationId)") return } if let selectedPolyline = viewModel.polylines.first(where: { ($0.userInfo?["annotation-id"] as? String) == annotationId }) { viewModel.selectPolyline(selectedPolyline) print("***** 选中折线ID: \(annotationId)") return } } } // 未找到匹配标注,取消折线选中 viewModel.deselectPolyline() print("***** 未找到匹配标注,取消折线选中") case .failure(let error): viewModel.deselectPolyline() print("***** 查询渲染特征失败: \(error)") } } } // MARK: - 查询渲染特征 /** 处理指定位置的渲染特征查询 查询指定点的渲染特征,并将结果通过完成回调返回 - Parameters: - point: 查询的屏幕点 - options: 查询选项 - completion: 查询结果的回调 */ private func queryRenderedFeatures(at point: CGPoint, options: RenderedQueryOptions, completion: @escaping (Result<[QueriedRenderedFeature], Error>) -> Void) { mapView.mapboxMap.queryRenderedFeatures(with: point, options: options, completion: completion) } }
内容的提问来源于stack exchange,提问作者Roontoon
相关产品推荐
相关产品推荐

