BLE:使用CoreBluetooth在2个ios设备之间进行图像传输 [英] BLE: image transfer between 2 ios devices using CoreBluetooth

查看:106
本文介绍了BLE:使用CoreBluetooth在2个ios设备之间进行图像传输的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

So i have 2 iOS devices : one is Peripheral and the other Central. I want that the data would be image. I have tried with a string value and it is working fine but with image i get this error:"read_user_chunkIDOT:1221: invalid PNG file: no valid iEnd chunk", also i can see that the bytes are different( Optional(526 bytes)), they are more larger when i get them.

这是外围设备:

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])
    }

这是didUpdateValueFor特性内部的中央:

This is the Central inside didUpdateValueFor characteristic:

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)")
    }

想知道我错了. 在此先谢谢您!

Would like to know where i am wrong. Thanks in advanced!

推荐答案

因此,我已使用以下代码来做到这一点:

So i have managed doing so with this code:

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
        }
    }
}

下面的代码是客户端:

func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
    print(characteristic.value as Any)
    switch characteristic.uuid {
    case Constants.CHAR_UUID:
        imageView.image = nil
        print("Char value: \(String(describing: characteristic.value))")
        guard error == nil else {
            print("Error discovering services: \(error!.localizedDescription)")
            return
        }

        if  let stringFromData = NSString(data: characteristic.value!, encoding: String.Encoding.utf8.rawValue){

            if  (stringFromData.isEqual(to:"EOM")){
                countNumberOfImages += 1
                imageView.image = UIImage(data: data as Data)
               // peripheral.setNotifyValue(false, for: characteristic)
                print("Image number: \(countNumberOfImages)")

                let end = NSDate()   // <<<<<<<<<<   end time
                print("Total data: \(data.length)")

                let start = NSDate() // <<<<<<<<<< Start time

                data.setData(NSData() as Data)
                //totalData.setData(NSData() as Data)
               // centralManager?.cancelPeripheralConnection(peripheral)

            } else {
                // Otherwise, just add the data on to what we already have
                data.append(characteristic.value!)
                totalData.append(characteristic.value!)
                count += 1
               // print("Times: +\(count)")
                // Log it
                print("Received: \(data.length)")
            }
        } else {
            data.append(characteristic.value!)
            totalData.append(characteristic.value!)
            count += 1
          //  print("Times: +\(count)")
            // Log it
            print("Received: \(data.length)")
        }
    default:
        print("Unhandled Characteristic UUID: \(characteristic.uuid)")
    }
}

非常有用的代码,可以帮助您将数据分成多个块,并使用字符串传送最后一个块,以通知中央设备传输已完成.

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.

这篇关于BLE:使用CoreBluetooth在2个ios设备之间进行图像传输的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆