核心蓝牙:在2台iOS设备之间发送数据

核心蓝牙:在2台iOS设备之间发送数据,ios,iphone,swift,xcode,core-bluetooth,Ios,Iphone,Swift,Xcode,Core Bluetooth,我已经用swift编程一段时间了,但我对核心蓝牙是完全陌生的。有没有一种方法可以使用核心蓝牙将原始数据(整数、字符)从一个iOS设备发送到另一个iOS设备 提前谢谢是的。 您需要将一个设备设置为外围设备,第二个设备设置为中央设备(或两者都设置)。 在外围设备中,您需要公布数据(peripheraldmanager.startAdvertising),在中央设备中,您需要根据特征获取数据。 您可以在中阅读所有相关信息,以下是Swift中与CBCentral和CBPeripal相关的代码 CBCen

我已经用swift编程一段时间了,但我对核心蓝牙是完全陌生的。有没有一种方法可以使用核心蓝牙将原始数据(整数、字符)从一个iOS设备发送到另一个iOS设备

提前谢谢

是的。 您需要将一个设备设置为外围设备,第二个设备设置为中央设备(或两者都设置)。 在外围设备中,您需要公布数据(peripheraldmanager.startAdvertising),在中央设备中,您需要根据特征获取数据。
您可以在

中阅读所有相关信息,以下是Swift中与CBCentral和CBPeripal相关的代码

CBCentral

扫描和连接后

      /** We've connected to the peripheral, now we need to discover the services and characteristics to find the 'transfer' characteristic.
         */
        func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
            print("Peripheral Connected")

            // Stop scanning
            centralManager?.stopScan()
            print("Scanning stopped")

            // Clear the data that we may already have
            data.length = 0

            // Make sure we get the discovery callbacks
            peripheral.delegate = self

            // Search only for services that match our UUID
            peripheral.discoverServices([transferServiceUUID])
        }

        /** The Transfer Service was discovered
         */
        func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
            guard error == nil else {
                print("Error discovering services: \(error!.localizedDescription)")
                cleanup()
                return
            }

            guard let services = peripheral.services else {
                return
            }

            // Discover the characteristic we want...

            // Loop through the newly filled peripheral.services array, just in case there's more than one.
            for service in services {
                peripheral.discoverCharacteristics([transferCharacteristicUUID], for: service)
            }
        }

        /** The Transfer characteristic was discovered.
         *  Once this has been found, we want to subscribe to it, which lets the peripheral know we want the data it contains
         */
        func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
            // Deal with errors (if any)
            guard error == nil else {
                print("Error discovering services: \(error!.localizedDescription)")
                cleanup()
                return
            }


            guard let characteristics = service.characteristics else {
                return
            }

            // Again, we loop through the array, just in case.
            for characteristic in characteristics {
                // And check if it's the right one
                if characteristic.uuid.isEqual(transferCharacteristicUUID) {
                    // If it is, subscribe to it
                    peripheral.setNotifyValue(true, for: characteristic)
                }
            }
            // Once this is complete, we just need to wait for the data to come in.
        }

        /** This callback lets us know more data has arrived via notification on the characteristic
         */
        func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
            guard error == nil else {
                print("Error discovering services: \(error!.localizedDescription)")
                return
            }

            guard let stringFromData = NSString(data: characteristic.value!, encoding: String.Encoding.utf8.rawValue) else {
                print("Invalid data")
                return
            }

            // Have we got everything we need?
            if stringFromData.isEqual(to: "EOM") {
                // We have, so show the data,
                textView.text = String(data: data.copy() as! Data, encoding: String.Encoding.utf8)

                // Cancel our subscription to the characteristic
                peripheral.setNotifyValue(false, for: characteristic)

                // and disconnect from the peripehral
                centralManager?.cancelPeripheralConnection(peripheral)
            } else {
                // Otherwise, just add the data on to what we already have
                data.append(characteristic.value!)

                // Log it
                print("Received: \(stringFromData)")
            }
        }
 /** Catch when someone subscribes to our characteristic, then start sending them data
  */
 func peripheralManager(_ peripheral: CBPeripheralManager, central: CBCentral, didSubscribeTo characteristic: CBCharacteristic) {
    print("Central subscribed to characteristic")

    // Get the data
    dataToSend = textView.text.data(using: String.Encoding.utf8)

    // Reset the index
    sendDataIndex = 0;

    // Start sending
    sendData()
 }

 /** Recognise when the central unsubscribes
  */
 func peripheralManager(_ peripheral: CBPeripheralManager, central: CBCentral, didUnsubscribeFrom characteristic: CBCharacteristic) {
    print("Central unsubscribed from characteristic")
 }

 // First up, check if we're meant to be sending an EOM
 fileprivate var sendingEOM = false;

 /** Sends the next amount of data to the connected central
  */
 fileprivate func sendData() {
    if sendingEOM {
        // send it
        let didSend = peripheralManager?.updateValue(
            "EOM".data(using: String.Encoding.utf8)!,
            for: transferCharacteristic!,
            onSubscribedCentrals: nil
        )

        // Did it send?
        if (didSend == true) {

            // It did, so mark it as sent
            sendingEOM = false

            print("Sent: EOM")
        }

        // It didn't send, so we'll exit and wait for peripheralManagerIsReadyToUpdateSubscribers to call sendData again
        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.
    // Can't be longer than 20 bytes

    var didSend = true

    while didSend {
        // Make the next chunk

        // Work out how big it should be
        var amountToSend = dataToSend!.count - sendDataIndex!;


        // Copy out the data we want
        let chunk = dataToSend!.withUnsafeBytes{(body: UnsafePointer<UInt8>) in
            return Data(
                bytes: body + sendDataIndex!,
                count: amountToSend
            )
        }

        // Send it
        didSend = peripheralManager!.updateValue(
            chunk as Data,
            for: transferCharacteristic!,
            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: \(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 = peripheralManager!.updateValue(
                "EOM".data(using: String.Encoding.utf8)!,
                for: transferCharacteristic!,
                onSubscribedCentrals: nil
            )

            if (eomSent) {
                // It sent, we're all done
                sendingEOM = false
                print("Sent: EOM")
            }

            return
        }
    }
 }

 /** This callback comes in when the PeripheralManager is ready to send the next chunk of data.
  *  This is to ensure that packets will arrive in the order they are sent
  */
 func peripheralManagerIsReady(toUpdateSubscribers peripheral: CBPeripheralManager) {
    // Start sending again
    sendData()
 }
cb外围设备

扫描和连接后

      /** We've connected to the peripheral, now we need to discover the services and characteristics to find the 'transfer' characteristic.
         */
        func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
            print("Peripheral Connected")

            // Stop scanning
            centralManager?.stopScan()
            print("Scanning stopped")

            // Clear the data that we may already have
            data.length = 0

            // Make sure we get the discovery callbacks
            peripheral.delegate = self

            // Search only for services that match our UUID
            peripheral.discoverServices([transferServiceUUID])
        }

        /** The Transfer Service was discovered
         */
        func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
            guard error == nil else {
                print("Error discovering services: \(error!.localizedDescription)")
                cleanup()
                return
            }

            guard let services = peripheral.services else {
                return
            }

            // Discover the characteristic we want...

            // Loop through the newly filled peripheral.services array, just in case there's more than one.
            for service in services {
                peripheral.discoverCharacteristics([transferCharacteristicUUID], for: service)
            }
        }

        /** The Transfer characteristic was discovered.
         *  Once this has been found, we want to subscribe to it, which lets the peripheral know we want the data it contains
         */
        func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
            // Deal with errors (if any)
            guard error == nil else {
                print("Error discovering services: \(error!.localizedDescription)")
                cleanup()
                return
            }


            guard let characteristics = service.characteristics else {
                return
            }

            // Again, we loop through the array, just in case.
            for characteristic in characteristics {
                // And check if it's the right one
                if characteristic.uuid.isEqual(transferCharacteristicUUID) {
                    // If it is, subscribe to it
                    peripheral.setNotifyValue(true, for: characteristic)
                }
            }
            // Once this is complete, we just need to wait for the data to come in.
        }

        /** This callback lets us know more data has arrived via notification on the characteristic
         */
        func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
            guard error == nil else {
                print("Error discovering services: \(error!.localizedDescription)")
                return
            }

            guard let stringFromData = NSString(data: characteristic.value!, encoding: String.Encoding.utf8.rawValue) else {
                print("Invalid data")
                return
            }

            // Have we got everything we need?
            if stringFromData.isEqual(to: "EOM") {
                // We have, so show the data,
                textView.text = String(data: data.copy() as! Data, encoding: String.Encoding.utf8)

                // Cancel our subscription to the characteristic
                peripheral.setNotifyValue(false, for: characteristic)

                // and disconnect from the peripehral
                centralManager?.cancelPeripheralConnection(peripheral)
            } else {
                // Otherwise, just add the data on to what we already have
                data.append(characteristic.value!)

                // Log it
                print("Received: \(stringFromData)")
            }
        }
 /** Catch when someone subscribes to our characteristic, then start sending them data
  */
 func peripheralManager(_ peripheral: CBPeripheralManager, central: CBCentral, didSubscribeTo characteristic: CBCharacteristic) {
    print("Central subscribed to characteristic")

    // Get the data
    dataToSend = textView.text.data(using: String.Encoding.utf8)

    // Reset the index
    sendDataIndex = 0;

    // Start sending
    sendData()
 }

 /** Recognise when the central unsubscribes
  */
 func peripheralManager(_ peripheral: CBPeripheralManager, central: CBCentral, didUnsubscribeFrom characteristic: CBCharacteristic) {
    print("Central unsubscribed from characteristic")
 }

 // First up, check if we're meant to be sending an EOM
 fileprivate var sendingEOM = false;

 /** Sends the next amount of data to the connected central
  */
 fileprivate func sendData() {
    if sendingEOM {
        // send it
        let didSend = peripheralManager?.updateValue(
            "EOM".data(using: String.Encoding.utf8)!,
            for: transferCharacteristic!,
            onSubscribedCentrals: nil
        )

        // Did it send?
        if (didSend == true) {

            // It did, so mark it as sent
            sendingEOM = false

            print("Sent: EOM")
        }

        // It didn't send, so we'll exit and wait for peripheralManagerIsReadyToUpdateSubscribers to call sendData again
        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.
    // Can't be longer than 20 bytes

    var didSend = true

    while didSend {
        // Make the next chunk

        // Work out how big it should be
        var amountToSend = dataToSend!.count - sendDataIndex!;


        // Copy out the data we want
        let chunk = dataToSend!.withUnsafeBytes{(body: UnsafePointer<UInt8>) in
            return Data(
                bytes: body + sendDataIndex!,
                count: amountToSend
            )
        }

        // Send it
        didSend = peripheralManager!.updateValue(
            chunk as Data,
            for: transferCharacteristic!,
            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: \(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 = peripheralManager!.updateValue(
                "EOM".data(using: String.Encoding.utf8)!,
                for: transferCharacteristic!,
                onSubscribedCentrals: nil
            )

            if (eomSent) {
                // It sent, we're all done
                sendingEOM = false
                print("Sent: EOM")
            }

            return
        }
    }
 }

 /** This callback comes in when the PeripheralManager is ready to send the next chunk of data.
  *  This is to ensure that packets will arrive in the order they are sent
  */
 func peripheralManagerIsReady(toUpdateSubscribers peripheral: CBPeripheralManager) {
    // Start sending again
    sendData()
 }
/**当有人订阅我们的特征时捕获,然后开始向他们发送数据
*/
func外围设备管理器(外围设备:CBPeripheralManager,中心设备:CBCentral,didSubscribeTo特征:CBCharacteristic){
打印(“中央订阅特征”)
//获取数据
dataToSend=textView.text.data(使用:String.Encoding.utf8)
//重置索引
sendDataIndex=0;
//开始发送
sendData()
}
/**识别中央服务器何时取消订阅
*/
func外围设备管理器(外围设备:CBPeripheralManager,中心设备:CBCentral,取消订阅特征:CBCharacteristic){
打印(“中心取消订阅特征”)
}
//首先,检查我们是否打算发送EOM
fileprivate var sendingEOM=false;
/**将下一个数据量发送到连接的中心服务器
*/
fileprivate func sendData(){
如果发送EOM{
//发送它
让didSend=外围设备管理器?.updateValue(
“EOM”。数据(使用:String.Encoding.utf8)!,
对于:传输特性!,
已订阅中心:无
)
//它发了吗?
if(didSend==true){
//是的,所以标记为已发送
sendingEOM=false
打印(“已发送:EOM”)
}
//它没有发送,因此我们将退出并等待外围设备管理器ReadyToUpdatesSubscribers再次调用sendData
返回
}
//我们没有发送EOM,所以我们发送的是数据
//还有什么要寄的吗?
guard sendDataIndex=dataToSend!.count){
//它是-发送EOM
//设置此选项,以便在发送失败时,我们将在下次发送
sendingEOM=true
//发送它
让eomSent=peripheralManager!.updateValue(
“EOM”。数据(使用:String.Encoding.utf8)!,
对于:传输特性!,
已订阅中心:无
)
如果(eomSent){
//它发出了,我们都完成了
sendingEOM=false
打印(“已发送:EOM”)
}
返回
}
}
}
/**当外围设备管理器准备好发送下一个数据块时,会出现此回调。
*这是为了确保数据包按照发送顺序到达
*/
func外围设备管理器就绪(toUpdateSubscribers外围设备:CBPeripheralManager){
//重新开始发送
sendData()
}

如何确定
transferServiceUUID
transferCharacteristicUUID
的值?