0

I have successfully managed to get my iOS app (peripheral) send messages to my OSX app (central).

I am now having problems when trying to have the Central update a characteristics value and read it from the Peripheral.

If I change CBCharacteristicProperties to anything other than Notify, my central fails to subscribe to the characteristic with the following error: "Writing is not permitted."

self.transferCharacteristic = CBMutableCharacteristic(type: CBUUID.UUIDWithString(TRANSFER_CHARACTERISTIC_UUID), properties: CBCharacteristicProperties.Read, value: nil, permissions: CBAttributePermissions.Writeable)

To my understanding, in order to have to Central write to the Peripheral, I should use a combination of the line above in the Peripheral, with this event:

func peripheralManager(peripheral: CBPeripheralManager!, didReceiveWriteRequests requests: [AnyObject]!) {}

and this in the Central to update the characteristic's value:

self.discoveredPeripheral?.writeValue(passwordData, forCharacteristic: self.characteristicSubscribed, type: CBCharacteristicWriteType.WithoutResponse)

Please let me know what I am doing wrong. Any sample project showing how to do what I am trying to would be highly appreciated.

Thanks

Paulw11
  • 108,386
  • 14
  • 159
  • 186
Lee Andrew
  • 798
  • 7
  • 28

1 Answers1

1

You need to flag the property as both readable AND writeable by combining the enumeration values -

var cbProperties = CBCharacteristicProperties.Read|CBCharacteristicProperties.Write
var cbPermissions = CBAttributePermissions.Readable|CBAttributePermissions.Writeable

var transferCharacteristic = CBMutableCharacteristic(type: CBUUID.UUIDWithString(TRANSFER_CHARACTERISTIC_UUID), properties: cbProperties, value: nil, permissions: cbPermissions)
Paulw11
  • 108,386
  • 14
  • 159
  • 186
  • Two more questions please. 1- when using this sort of characteristic, do I still have to use: peripheral.setNotifyValue(true, forCharacteristic: characteristic as CBCharacteristic) If so, I am still getting "Writing is not permitted." 2 - How do I deal with data on the Peripheral side after calling self.discoveredPeripheral?.writeValue on the Central? Thanks – Lee Andrew Sep 02 '14 at 22:52
  • If you want notification then you need to add `CBCharacteristicProperties.Notify` to the properties. On the peripheral side you either need to poll the characteristic value or (better) use notification to be notified that the value has changed. – Paulw11 Sep 02 '14 at 22:58
  • Got it working I had to use a dedicated UUID to this characteristic since it was conflicting with another I had previously used, they seem to take a long time to "go away". Thank you very much!!! – Lee Andrew Sep 02 '14 at 23:05
  • Please, what event gets called in CBCentral when a CBPeripheral that has CBCharacteristicProperties.Notify receives data from Central? Ive tried didUpdateNotificationStateForCharacteristic, but since I havent subscribed to it on the central side, I dont think thats gonna work. – Lee Andrew Sep 03 '14 at 03:06
  • Nothing gets called on the CBCentral delegate in that case. If you have enabled notifications on a characteristic then the peripheral's `didUpdateNotificationStateForCharacteristic` delegate method will be called when the remote updates the value. When you write to a value, if you specify a 'write with response' then the peripheral delegates `didWriteValueForCharacteristic` method will be called once the write is complete – Paulw11 Sep 03 '14 at 03:33
  • Ive tried didWriteValueForCharacteristic, which worked perfectly, but for some odd reason it takes a while for callback to come through. Is it supposed to be like that? – Lee Andrew Sep 03 '14 at 03:46
  • It depends on the peripheral you are writing to - The callback is called when a message is received from the peripheral confirming that the write has taken place – Paulw11 Sep 03 '14 at 03:48
  • The Peripheral happens to be an iOS device, Ive found it very strange that it takes about 5secs for the callback to take place. – Lee Andrew Sep 03 '14 at 03:49
  • I want to write message "abc" using method **peripheral.writeValue(data, forCharacteristic: arrCharacteristics!.objectAtIndex(1) as CBCharacteristic , type: CBCharacteristicWriteType.WithResponse)** and then read message from peripheral using method **peripheral.readValueForCharacteristic(arrCharacteristics!.objectAtIndex(0) as CBCharacteristic)** and update method shows the message from this code **var str:NSString = NSString(data: characteristic.value, encoding: NSASCIIStringEncoding)**.I am also facing similar kind of issue that i am not getting message and blank message appears. – Zalak Patel Oct 20 '14 at 07:14
  • Are you seeing a delay in actually entering the delegate method or in displaying the alert? You should make sure you dispatch the alert on the main queue – Paulw11 Oct 20 '14 at 07:58