Post

Replies

Boosts

Views

Activity

Core Bluetooth Characteristic Value mismatch between iOS and macOS
Hi there! I am writing the BLE portion of my iOS application and have run into some strange behaviour while testing with a nordic dev kit (nRF52840) running an in-house dev build. The BLE workflow seems to be flowing correctly however the characteristic value for all characteristics seem to be applying some sort of little-endian byte encoding on a different characteristic's UUID plus 3 additional bytes of random information. I believe this issue lies with the implementation of Core Bluetooth in Swift as reading the same characteristic with Bleak in python on macOS (which uses Core Bluetooth) retrieves the correct characteristic value. I've read through the package and spoken to the developer that wrote the Bleak/Core Bluetooth backend and we both agree that the workflow is identical and as follows: Swift View loads and initializes the BLE Manager. centralManagerDidUpdateState is called and the central state is .poweredOn. Peripheral scan starts. Connect to a peripheral calling centralManager(didConnect) which calls peripheral.discoverServices. Then peripheral(didDiscoverServices) which calls peripheral.discoverCharacteristics(for: service) Then peripheral(didDiscoverCharacteristicsFor: ) which calls peripheral.readValue(for: characteristic) after checking characteristic.properties.contains(.read) Then peripheral(didUpdateValueFor: characteristic) Note: All characteristics are behaving this way in iOS. The specific characteristic used in my code snippets are for a constant, read-only value. Code Snippets python Bleak code (taken from example) async def simple_callback(device: BLEDevice, advertisement_data: AdvertisementData):    if device.address == address:      print(f'Connecting to client {address}')      client = BleakClient(device.address)      try:        await client.connect()        svcs = await client.get_services()        for s in svcs:          print(f"Service: {s}")          value = await client.read_gatt_char(UUID)          print(f"{UUID}: {value}")      except Exception as e:        print(e)      finally:        await client.disconnect() Python output (correct): Read Characteristic 2f1a0004-1edf-47e3-9ea6-423c2c7c2913 : bytearray(b'\xfc\x00\x03\x00') Swift Snippet - my peripheral(didUpdateValueFor: ) func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {            print("didUpdateValueFor characteristic: service=\(characteristic.service!.uuid.uuidString) characteristic=\(characteristic.uuid.uuidString)")            if let data = characteristic.value {        var values = [UInt8](repeating:0, count:data.count)       data.copyBytes(to: &values, count: data.count)        print(characteristic)     } else {        print("ERROR: NO DATA from characteristic")     }  } Xcode console output (incorrect): didUpdateValueFor characteristic: service=2F1A0001-1EDF-47E3-9EA6-423C2C7C2913 characteristic=2F1A0004-1EDF-47E3-9EA6-423C2C7C2913 <CBCharacteristic: 0x283013cc0, UUID = 2F1A0004-1EDF-47E3-9EA6-423C2C7C2913, properties = 0x2, value = {length = 19, bytes = 0x02180013297c2c3c42a69ee347df1e0b001a2f}, notifying = NO> Here the 19 byte value seems to include a UUID for a different characteristic reversed plus 3 bytes. I’ve attempted to sanitize and isolate those additional bytes but that is still incorrect. Strangely enough the nordic nrfConnect iOS application also reads back this same incorrect value but the Android release works correctly. iOS Screenshot Android Screenshot Additional Info I am running Xcode 13.0 beta on my MacBook Pro and deploying onto an iPhone 11 Pro Max. Application is reading all other attributes correctly (RSSI, etc.). Any help is greatly appreciated! Please let me know if I can provide any more information to support. Thanks, Crudough
3
0
2.2k
Aug ’21
'File' couldn’t be moved because you don’t have permission to access 'Documents'
Hi there, I am attempting to move a file to the documents folder programmatically within my iOS app. See below for a code snippet, nothing crazy just simple FileManager interactions. func moveZip(sourceUrl: URL) -> URL? {         let destinationUrl: URL = getDocumentsDirectory().appendingPathComponent(sourceUrl.lastPathComponent)         do {             if FileManager.default.fileExists(atPath: destinationUrl.path) {                 try FileManager.default.removeItem(atPath: destinationUrl.path)             }             try FileManager.default.moveItem(atPath: sourceUrl.path, toPath: destinationUrl.path)                 return destinationUrl         } catch {             print(error.localizedDescription)             return nil         }     } sourceUrl = file:///private/var/mobile/Containers/Shared/AppGroup/XXXXXXXXXXXXXXXXXXXXX/File%20Provider%20Storage/Work/file.zip destinationUrl = file:///var/mobile/Containers/Data/Application/XXXXXXXXXXXXXXXXXXXXX/Documents/file.zip Once I hit the line try FileManager.default.moveItem call I fail out with the following error: “file.zip” couldn’t be moved because you don’t have permission to access “Documents”. I believe I'm accessing everything correctly and have tried to dig into any possible info.plst access privileges but I haven't found anything yet. Running Xcode Version 13.0 beta and targeting an iPhone 11 Pro Max running iOS v14.7. Any help is appreciated! Thanks!
4
0
4.9k
Sep ’21
SwiftUI List Row Background not Rendering Off Screen
Hi there! I've been able to get the .listRowBackground() modifier to work in SwiftUI (with iOS 15) but am experiencing a weird graphical issue where rows that start off screen do not have the correct background colour until they appear on screen then off again. Not sure if there is a way to force all elements to render but as far as I can see I am using the modifier correctly. Any help is greatly appreciated! Anthony Code: var body: some View {         ZStack {             Color.theme.darkTheme                 .edgesIgnoringSafeArea(.all)             VStack {             ForEach(Array(array.keys), id: \.self) { key in                     List {                         ForEach(systemFaults[key]!, id: \.self) { fault in                             GenericItemView(label: "FAULT ID", item: "\(fault.faultID)")                             GenericItemView(label: "IS ACTIVE", item: fault.isActive ? "TRUE" : "FALSE")                             GenericItemView(label: "SET COUNT", item: "\(fault.setCount)")                             GenericItemView(label: "LAST TIMESTAMP", item: "\(fault.timestampSeconds) secs")                         }                         .listRowBackground(Color.theme.darkerAccent)                     }                     Spacer()                 }             }         }     } Generic Item view is a simple HStack to display the text and associated value. Screenshots Initial Sheet being presented Bottom Entries in the List Off Screen after Scrolling Up
3
2
1.3k
Jan ’22