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

Swift 5字符串处理:从CLLocation描述提取GPS相关字段

从CLLocation.description提取GPS信息(Swift 5)

直接访问CLLocation属性(推荐)

首先要明确:直接解析description字符串并非可靠方案,苹果可能随时修改该字符串的格式。更稳妥的方式是直接读取CLLocation的原生属性:

  • 纬度:location.coordinate.latitude
  • 经度:location.coordinate.longitude
  • 海拔:location.altitude
  • 速度:location.speed
  • 航向:location.course
  • 时间戳:location.timestamp

若必须解析description字符串

如果你因特殊需求需要处理给定格式的description字符串,以下是基于Swift 5的正则解析实现:

1. 定义存储结构体

struct GPSInfo {
    var latitude: Double?
    var longitude: Double?
    var altitude: Double?
    var speed: Double?
    var course: Double?
    var date: Date?
}

2. 实现解析函数

func parseGPSDescription(_ description: String) -> GPSInfo {
    var info = GPSInfo()
    
    // 匹配经纬度与海拔(如果存在)
    let coordinateRegex = try? NSRegularExpression(pattern: #"<([+-]?\d+\.\d+),([+-]?\d+\.\d+)(?:,([+-]?\d+\.\d+)m)?>"#, options: [])
    if let match = coordinateRegex?.firstMatch(in: description, range: NSRange(description.startIndex..., in: description)) {
        // 提取纬度
        if let latRange = Range(match.range(at: 1), in: description) {
            info.latitude = Double(description[latRange])
        }
        // 提取经度
        if let lonRange = Range(match.range(at: 2), in: description) {
            info.longitude = Double(description[lonRange])
        }
        // 提取海拔(仅当字符串包含时)
        if match.numberOfRanges > 3, let altRange = Range(match.range(at: 3), in: description) {
            info.altitude = Double(description[altRange])
        }
    }
    
    // 匹配速度
    let speedRegex = try? NSRegularExpression(pattern: #"speed ([+-]?\d+\.\d+) mps"#, options: [])
    if let match = speedRegex?.firstMatch(in: description, range: NSRange(description.startIndex..., in: description)) {
        if let speedRange = Range(match.range(at: 1), in: description) {
            info.speed = Double(description[speedRange])
        }
    }
    
    // 匹配航向
    let courseRegex = try? NSRegularExpression(pattern: #"course ([+-]?\d+\.\d+)"#, options: [])
    if let match = courseRegex?.firstMatch(in: description, range: NSRange(description.startIndex..., in: description)) {
        if let courseRange = Range(match.range(at: 1), in: description) {
            info.course = Double(description[courseRange])
        }
    }
    
    // 匹配日期时间与时区
    let dateRegex = try? NSRegularExpression(pattern: #"@ (\d+/\d+/\d+), (\d+:\d+:\d+ [AP]M) ([\w\s]+)"#, options: [])
    if let match = dateRegex?.firstMatch(in: description, range: NSRange(description.startIndex..., in: description)) {
        guard let dateStrRange = Range(match.range(at: 1), in: description),
              let timeStrRange = Range(match.range(at: 2), in: description),
              let tzStrRange = Range(match.range(at: 3), in: description) else {
            return info
        }
        
        let dateTimeString = "\(description[dateStrRange]) \(description[timeStrRange])"
        let timeZoneIdentifier = description[tzStrRange].replacingOccurrences(of: " ", with: "_")
        
        let formatter = DateFormatter()
        formatter.dateFormat = "MM/dd/yy hh:mm:ss a"
        formatter.timeZone = TimeZone(identifier: timeZoneIdentifier)
        info.date = formatter.date(from: dateTimeString)
    }
    
    return info
}

3. 使用示例

let sampleDesc = "<+37.78583400,-122.40641700> +/- 5.00m (speed -1.00 mps / course -1.00) @ 9/15/22, 10:05:21 AM East Africa Time"
let parsedInfo = parseGPSDescription(sampleDesc)

// 打印结果
print("纬度: \(parsedInfo.latitude ?? 0.0)")
print("经度: \(parsedInfo.longitude ?? 0.0)")
print("海拔: \(parsedInfo.altitude ?? 0.0)") // 示例无海拔,输出0.0
print("速度: \(parsedInfo.speed ?? 0.0)")
print("航向: \(parsedInfo.course ?? 0.0)")
if let date = parsedInfo.date {
    let displayFormatter = DateFormatter()
    displayFormatter.dateStyle = .full
    displayFormatter.timeStyle = .full
    print("日期时间: \(displayFormatter.string(from: date))")
}

注意事项

  • 正则表达式基于你提供的字符串格式编写,若苹果修改CLLocation.description的输出格式,需要同步调整正则规则。
  • 示例字符串未包含海拔信息,当CLLocation有海拔数据时,description会显示类似<+37.78583400,-122.40641700,+15.20m>的格式,代码已兼容这种情况。

内容的提问来源于stack exchange,提问作者donaldjbrewer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 07:50:30