使用 Swift 的 Location BLE GPS 解码 location_and_speed

Posted

技术标签:

【中文标题】使用 Swift 的 Location BLE GPS 解码 location_and_speed【英文标题】:Using Swift's Location BLE GPS To Decode location_and_speed 【发布时间】:2019-03-20 07:28:41 【问题描述】:

我的应用程序目前工作正常,因为我能够从解码 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???
      

任何帮助将不胜感激,谢谢!

【问题讨论】:

您要解码哪个蓝牙特性?你能链接到蓝牙网站上的文档吗? Reading a BLE Peripheral Characteristic and checking its value?的可能重复 【参考方案1】:

感谢 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)
    

【讨论】:

以上是关于使用 Swift 的 Location BLE GPS 解码 location_and_speed的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Swift 中读取 BLE 特征浮点数

如何从 Swift 中的 BLE 外设特征写入回调中提取数据?

如何获取 BLE 广告数据 Swift 2

Swift 3 arduino Uno HM-10 Ble - iPhone 上的通知

当 BLE 在 Swift 中以编程方式连接时,蓝牙设备设置中缺少信息按钮

BLE和2.4G实现通信