can't write to CBMutableCharacteristic

I'm implementing CoreBluetooth on iOS. I'm using iOS for both the central and the peripheral. My peripheral is running on iPhone 6+ with iOS 11.4 and the central is running on iPhone 8 with iOS 11.4. I know everything is setup correctly as I can read the service's CBMutableCharacteristic when I create it like this:


keyCharacteristic = CBMutableCharacteristic(type: charUUID,
                                           properties: [.read],
                                           value: "test char".data(using: .utf8)!,
                                           permissions: [.readable])


This works - when I start up my central I get the characteristic value when `didUpdateNotificationStateFor characteristic` is called.


Now I change my char to writeable, call peripheral.writeValue() and it returns `<>` as the value:


keyCharacteristic = CBMutableCharacteristic(type: charUUID,
                                           properties: [.read, .write],
                                           value: nil,
                                           permissions: [.readable, .writeable])


writing from central, I get didUpdateValue call, then didUpdateNotificationStateFor, then didWriteValueFor. The characteristic value in didWriteValueFor is `<>` instead of the Data passed in:


    func peripheral(_ peripheral: CBPeripheral,
                    didUpdateValueFor characteristic: CBCharacteristic,
                    error: Error?) {
        print(String(data: characteristic.value!, encoding: .utf8)!)
    }
    
    func peripheral(_ peripheral: CBPeripheral,
                    didUpdateNotificationStateFor characteristic: CBCharacteristic,
                    error: Error?) {
        print("didUpdateNotificationStateFor ")
        print("characteristic VALUE: \(String(data: characteristic.value ?? "nil".data(using: .utf8)!, encoding: .utf8)!)")
        if p2pChar != nil {
            gatewayPeripheral.writeValue("HelloWorldinitialvalue".data(using: .utf8)!,
                                         for: p2pChar!,
                                         type: .withResponse)
        }
    }
    
    func peripheral(_ peripheral: CBPeripheral,
                    didWriteValueFor characteristic: CBCharacteristic,
                    error: Error?) {
        print("didWriteValueFor \(String(data: characteristic.value ?? "nil".data(using: .utf8)!, encoding: .utf8)!)")
    }
   


This is the characterstic print


<CBCharacteristic: 0x1c00a42c0, UUID = F0646A14-B60F-DDDD-DDDD-AC114C9ACACAC, properties = 0x8A, value = <>, notifying = NO>

I also changed characteristic and writeValue() to `.withoutResponse` and this produces same resut and doesn't call didWriteValue of CBPeripheralDelegate.


Any ideas? I called this a few times consecutively while the peripheral was advertising and still same results.


TIA