ios - 使用 Swift 的 Location BLE GPS 解码 location_and_speed
问题描述
我的应用程序目前可以正常工作,因为我能够从解码location_and_speed特征中检索值。但是,我在从蓝牙读取文档以解码/提取设备中的值时遇到困难。
下面是我的代码:
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor
characteristic: CBCharacteristic, error: Error?) {
print(#function)
print(characteristic.value?.count ?? 0)
guard let data = characteristic.value else {return}
let byteArray = [UInt8](data)
// TODO: decode the value to available gps data???
}
任何帮助将不胜感激,谢谢!
解决方案
多亏了 xdappcactory.com,四处挖掘,我找到了解决方案。这是我想出的结构,只有解码速度和位置,但仍然可用
// MARK: - decode helpers
struct LocationAndSpeed {
enum PositionStatus : Int {
case none
case ok
case estimated
case lastKnown
}
enum SpeedAndDistanceFormat : Int {
case _2D
case _3D
}
enum ElevationSource : Int {
case position
case barometricAirPressure
case databaseService
case other
}
enum HeadingSource : Int {
case movementBased
case magneticCompass
}
let instantaneousSpeedPresent: Bool
let totalDistancePresent : Bool
let locationPressent : Bool
let elevationPressent : Bool
let headingPressent : Bool
let rollingTimePressent : Bool
let utcTimePressent : Bool
let positionStatus : PositionStatus
let speedAndDistanceFormat : SpeedAndDistanceFormat
let elevationSource : ElevationSource
let headingSource : HeadingSource
let speed : CLLocationSpeed?
let distance : CLLocationDistance?
let latitude : CLLocationDegrees
let longitude : CLLocationDegrees
let elevation : CLLocationDistance?
let heading : CLLocationDirection?
let rollingTime : TimeInterval?
let utcTime : Date?
enum LocationAndSpeedError : Error {
case invalidSize
}
init(data: Data) throws {
guard data.count >= 10 else {throw LocationAndSpeedError.invalidSize}
// let byteArray = [UInt8](data)
// handle the flags
let flagsData = data.subdata(in: 0..<2)
let flags = flagsData.withUnsafeBytes { (pointer: UnsafePointer<UInt16>) -> UInt16 in return pointer.pointee }
instantaneousSpeedPresent = (flags & .speed) != 0
totalDistancePresent = (flags & .distance) != 0
locationPressent = (flags & .location) != 0
elevationPressent = (flags & .elevation) != 0
headingPressent = (flags & .heading) != 0
rollingTimePressent = (flags & .rollingTime) != 0
utcTimePressent = (flags & .utcTime) != 0
positionStatus = PositionStatus(rawValue: Int((flags & .position) >> 7)) ?? .none
speedAndDistanceFormat = SpeedAndDistanceFormat(rawValue: Int((flags & .format) >> 9)) ?? ._2D
elevationSource = ElevationSource(rawValue: Int((flags & .elevationSource) >> 10)) ?? .other
headingSource = HeadingSource(rawValue: Int((flags & .headinSource) >> 12)) ?? .movementBased
var index = 2
if (instantaneousSpeedPresent){
let speedData = data.subdata(in: index ..< index + 2)
speed = Double(speedData.withUnsafeBytes { (pointer: UnsafePointer<UInt16>) -> UInt16 in return pointer.pointee }) / 100
index += 2
} else {
speed = -1
}
if (totalDistancePresent) {
distance = 0//Double((UInt32(byteArray[index]) << 16) + (UInt32(byteArray[index + 1]) << 8) + UInt32(byteArray[index + 2])) / 10
index += 3
} else {
distance = -1
}
// I don't know if this is the right data....
let latData = data.subdata(in: index..<index+4)
let lat = latData.withUnsafeBytes { (pointer: UnsafePointer<Int32>) -> Int32 in return pointer.pointee }
latitude = Double(lat) / 10000000.0
index += 4
let lonData = data.subdata(in: index..<index+4)
let lon = lonData.withUnsafeBytes { (pointer: UnsafePointer<Int32>) -> Int32 in return pointer.pointee }
longitude = Double(lon) / 10000000.0
index += 4
elevation = nil
heading = nil
rollingTime = nil
utcTime = nil
}
var coordinate: CLLocationCoordinate2D {
return CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
}
}
推荐阅读
- java - 使用 Proguard 缩小后出现 JRE 致命错误
- nginx - 多个服务器块 - 无法解析主机
- javascript - 创建客户端 Spotify 播放器
- python - 使用上下文管理器复制 Tensorflow - __enter__ 和 __exit__ 错误
- c# - 使用 DependencyProperty 自定义控件的设计器行为
- javascript - 将用户输入保存到 PHP,然后在 Javascript 函数中使用
- boost-spirit-qi - 提升精神,phoenix::push_back 和语义动作中的功能
- geolocation - 在屏幕上加载地图时,地理位置会变慢
- python - 比较两个图像中连接组件的标签
- powershell - Powershell v5.1 Invoke-RestMethod 和绕过代理