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

时间:2017-04-15 15:03:56

标签: ios iphone swift xcode core-bluetooth

我现在已经使用swift编程了一段时间,但我对Core Bluetooth完全不熟悉。有没有办法使用Core Bluetooth将原始数据(整数,字符)从一个iOS设备发送到另一个iOS设备?

提前致谢

2 个答案:

答案 0 :(得分:2)

是。 您需要制作一个设备外围设备和第二个设备外围设备(或两个设备)。 在外围设备中,您需要通告数据(peripheralManager.startAdvertising),并且在中央,您需要通过特性来获取数据。 您可以在https://developer.apple.com/documentation/corebluetooth

中阅读所有相关内容

答案 1 :(得分:1)

以下是与Swift中的CBCentral和CBPeripheral相关的代码。

<强> CBCentral

扫描后&amp;连接

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

<强> CBPeripheral

扫描后&amp;连接

 /** 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()
 }