如何用Swift的MKLookAround.Snapshotter根据经纬度生成并保存快照
批量生成MKLookAround快照实现方案
核心概念快速梳理
MKLookAround.Request:指定查询的经纬度坐标,是获取街景数据的请求载体MKLookAround.Snapshotter:基于获取到的街景场景(MKLookAroundScene)生成静态快照- 必须先确认目标坐标存在可用街景,再生成快照,避免无效操作
完整实现代码
下面是可直接复用的类,包含街景检查、快照生成、本地保存的完整逻辑,支持批量处理:
import MapKit import UIKit import Photos class LookAroundSnapshotManager { // 批量处理用串行队列控制请求速率,避免触发MapKit限制 private let processingQueue = DispatchQueue(label: "com.yourdomain.LookAroundSnapshotQueue") /// 检查坐标是否有可用街景,并生成快照保存 /// - Parameters: /// - coordinate: 目标经纬度 /// - saveToAlbum: 是否保存到系统相册 /// - savePath: 本地文件保存路径(可选,默认存Documents目录) /// - completion: 完成回调,返回成功状态及错误信息 func generateAndSaveSnapshot(for coordinate: CLLocationCoordinate2D, saveToAlbum: Bool = false, savePath: String? = nil, completion: @escaping (Bool, Error?) -> Void) { processingQueue.async { // 1. 创建街景请求 let request = MKLookAroundRequest(coordinate: coordinate) // 2. 查询是否存在可用街景 MKLookAround.fetchScene(for: request) { scene, error in guard let scene = scene else { completion(false, error ?? NSError(domain: "LookAround", code: -1, userInfo: [NSLocalizedDescriptionKey: "无可用街景数据"])) return } // 3. 配置快照生成器 let snapshotter = MKLookAroundSnapshotter(scene: scene) snapshotter.scale = UIScreen.main.scale // 适配屏幕分辨率 // 4. 生成快照 snapshotter.start { snapshot, error in guard let snapshot = snapshot else { completion(false, error ?? NSError(domain: "LookAround", code: -2, userInfo: [NSLocalizedDescriptionKey: "快照生成失败"])) return } // 5. 保存快照 let image = snapshot.image var saveSuccess = true var saveError: Error? // 保存到指定本地路径或默认Documents目录 let targetPath = savePath ?? { let documentsDir = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] return "\(documentsDir)/\(coordinate.latitude)_\(coordinate.longitude).png" }() do { guard let data = image.pngData() else { throw NSError(domain: "LookAround", code: -4, userInfo: [NSLocalizedDescriptionKey: "图片转数据失败"]) } try data.write(to: URL(fileURLWithPath: targetPath)) } catch { saveSuccess = false saveError = error } // 保存到系统相册(如果开启) if saveToAlbum && saveSuccess { PHPhotoLibrary.requestAuthorization { status in guard status == .authorized else { completion(false, NSError(domain: "LookAround", code: -3, userInfo: [NSLocalizedDescriptionKey: "相册权限未授权"])) return } PHPhotoLibrary.shared().performChanges({ PHAssetChangeRequest.creationRequestForAsset(from: image) }) { success, error in completion(success, error ?? saveError) } } } else { completion(saveSuccess, saveError) } } } } } /// 批量处理多个坐标的快照生成 /// - Parameters: /// - coordinates: 经纬度数组 /// - completion: 全部完成后的回调 func batchGenerateSnapshots(for coordinates: [CLLocationCoordinate2D], completion: @escaping () -> Void) { let group = DispatchGroup() for coordinate in coordinates { group.enter() generateAndSaveSnapshot(for: coordinate) { _, _ in group.leave() } } group.notify(queue: .main) { completion() } } }
使用示例
// 初始化管理器 let manager = LookAroundSnapshotManager() // 单个坐标处理(Apple总部) let appleHQ = CLLocationCoordinate2D(latitude: 37.3346, longitude: -122.0090) manager.generateAndSaveSnapshot(for: appleHQ, saveToAlbum: true) { success, error in if success { print("快照保存成功") } else { print("失败原因:\(error?.localizedDescription ?? "未知错误")") } } // 批量处理多个坐标 let locations = [ appleHQ, CLLocationCoordinate2D(latitude: 40.7128, longitude: -74.0060), // 纽约 CLLocationCoordinate2D(latitude: 51.5074, longitude: -0.1278) // 伦敦 ] manager.batchGenerateSnapshots(for: locations) { print("批量处理完成") }
注意事项
- 权限配置:需在
Info.plist中添加NSLocationWhenInUseUsageDescription,MapKit查询街景需要位置权限 - 速率限制:MapKit对街景请求有速率限制,批量处理用串行队列控制,避免请求被拒
- 错误处理:代码包含无街景、生成失败、权限不足等常见错误处理,可按需扩展
- 分辨率控制:通过
snapshotter.scale调整快照清晰度,默认用屏幕分辨率即可
内容的提问来源于stack exchange,提问作者Pooriya Rezaei
相关产品推荐
相关产品推荐

