You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 08:20:26