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
相关产品推荐
相关产品推荐

