Home Articles

BLE:使用CoreBluetooth在2个ios设备之间传输图像

Asked
Viewed 284 times
0

所以我有2个iOS设备:一个是Peripheral,另一个是Central . 我希望数据是图像 . 我尝试了一个字符串值,它工作正常,但有图像我得到这个错误:“read_user_chunkIDOT:1221:无效的PNG文件:没有有效的iEnd块”,我也可以看到字节是不同的(可选(526字节) ),当我得到它们时它们会更大 .

这是外围设备:

if let img = UIImage(named: "maiden") {
        let data = UIImagePNGRepresentation(img)
        let base64 = data?.base64EncodedData(options: .lineLength64Characters)
        let char = CBMutableCharacteristic(type: CHAR_UUID, properties: [.read], value: base64!, permissions: [.readable])
        let myRoei = CBMutableService(type: RX_UUID, primary: true)

        myRoei.characteristics = [char]
        cameraPeripheralManager.add(myRoei)
        cameraPeripheralManager.startAdvertising([CBAdvertisementDataServiceUUIDsKey:[RX_UUID], CBAdvertisementDataLocalNameKey: advertisementData])
    }

这是Central里面的didUpdateValueFor特性:

print(characteristic.value as Any)
    switch characteristic.uuid {
    case CHAR_UUID:
        let image = UIImage(data: Data(base64Encoded: characteristic.value!, options: .ignoreUnknownCharacters)!)

        self.imageView.image = image
        _ = bodyLocation(from: characteristic)
    case RX_UUID: break
       // onHeartRateReceived(bpm)
    default:
        print("Unhandled Characteristic UUID: \(characteristic.uuid)")
    }

想知道我哪里错了 . 提前致谢!

1 Answer

  • 1

    所以我用这段代码管理了这样做:

    func sendData() {
        if sendingEOM {
            // send it
            let didSend = cameraPeripheralManager?.updateValue(
                "EOM".data(using: String.Encoding.utf8)!,
                for: char!,
                onSubscribedCentrals: nil
            )
            // Did it send?
            if (didSend == true) {
                // It did, so mark it as sent
                sendingEOM = false
                print("Sent: EOM")
            }
            return
        }
    
        // We're not sending an EOM, so we're sending data
    
        // Is there any left to send?
        guard sendDataIndex! < (dataToSend?.count)! else {
            // No data left.  Do nothing
            return
        }
    
        // There's data left, so send until the callback fails, or we're done.
        var didSend = true
    
        while didSend {
            // Make the next chunk
    
            // Work out how big it should be
            var amountToSend = dataToSend!.count - sendDataIndex!;
    
            // Can't be longer than 20 bytes
            if (amountToSend > NOTIFY_MTU) {
                amountToSend = NOTIFY_MTU;
            }
    
            // Copy out the data we want
            let chunk = dataToSend!.withUnsafeBytes{(body: UnsafePointer<UInt8>) in
                return Data(
                    bytes: body + sendDataIndex!,
                    count: amountToSend
                )
            }
    
            // Send it
            didSend = cameraPeripheralManager!.updateValue(
                chunk as Data,
                for: char!,
                onSubscribedCentrals: nil
            )
    
            // If it didn't work, drop out and wait for the callback
            if (!didSend) {
                return
            }
    
            let stringFromData = NSString(
                data: chunk as Data,
                encoding: String.Encoding.utf8.rawValue
            )
    
            print("Sent: \(String(describing: stringFromData))")
    
            // It did send, so update our index
            sendDataIndex! += amountToSend;
    
            // Was it the last one?
            if (sendDataIndex! >= dataToSend!.count) {
    
                // It was - send an EOM
    
                // Set this so if the send fails, we'll send it next time
                sendingEOM = true
    
                // Send it
                let eomSent = cameraPeripheralManager!.updateValue(
                    "EOM".data(using: String.Encoding.utf8)!,
                    for: char!,
                    onSubscribedCentrals: nil
                )
    
                if (eomSent) {
                    // It sent, we're all done
                    sendingEOM = false
                    print("Sent: EOM")
                }
    
                return
            }
        }
    }
    Very useful code that helps you break the data into chunks and deliver the last chunk with a string to notify the central device that the transfer finished.
    

Related