Post

Replies

Boosts

Views

Activity

Reply to how can i make a ios bluetooth classic program? is this Mission Impossible?
Pro tip: when posting code, use the “code block” formatting feature to make it readable, like this: void Bt_Status (esp_spp_cb_event_t event, esp_spp_cb_param_t *param) { if (event == ESP_SPP_SRV_OPEN_EVT) { Serial.println ("Bluetooth: Connected"); /* ... */ } } That doesn't look promising. Indeed. That code is using Bluetooth as a plain old serial port, which isn’t compatible with Core Bluetooth on iOS.
Topic: App & System Services SubTopic: Hardware Tags:
Jul ’23
Reply to Bluetooth MAC address (RemoteID) has been changed after iOS 16.x
I use the MAC address (RemoteId / UUID) of the bluetooth device Note that the CBPeer.identifier (link) property is not the MAC address (or any other intrinsic property) of the peripheral. It’s just a random UUID assigned by Core Bluetooth. Searching the web turns up other cases of developers reporting that this identifier doesn’t always stay the same. And if you parse that documentation very carefully, it doesn’t actually promise that the identifier won’t change at some point. It’s probably safest to treat the identifier as a key for caching local state, but where such caching isn’t critical to your functionality. If you need a truly persistent identifier, consider your peripheral’s Serial Number String characteristic.
Topic: App & System Services SubTopic: Core OS Tags:
Jul ’23
Reply to Bluetooth MAC address (RemoteID) has been changed after iOS 16.x
why did it need to be changed in the last update[? ...] why doesn't iOS give us the fixed MAC address? Trust me, it’s not productive to ask (or worry about) why Apple does anything the way they do. ;-) I have never seen this UUID change in any update (just as it should). You may have gotten bit by unintentionally relying on undefined behavior. Maybe it used to be the same across devices because it was just (for example) based on a hash of the peripheral's MAC address. And maybe now it’s generated differently. (Why? See comment above.) But either way conforms to the documentation, which doesn’t define this behavior at all. I think iOS also needs to provide this uniqueID to us developers. You should submit a feedback requesting this feature.
Topic: App & System Services SubTopic: Core OS Tags:
Jul ’23
Reply to Convert SQLite Julian date to a specific date string format for display
Is there a more direct way to do this? Definitely. Currently it’s doing all this: calling datetime() within SQLite to convert a stored Julian value to a string; using one DateFormatter to parse that string into a Date value; using a second DateFormatter to convert that Date value back to a string. You can eliminate 1 and 2. Just project the raw Julian value in your query (fetching it via sqlite3_column_double) and then construct your Date value directly using init(timeIntervalSinceReferenceDate:). It just requires simple math to convert from Julian (days since 4713 BC) to Apple reference date (seconds since 2001). Also this will help your ORDER BY clause a little, since now it will be sorting by a number rather than a string. And (basic “code review” comment) you can construct mediumDateFormatter just once, before the loop. No need to do it inside the loop.
Topic: Programming Languages SubTopic: Swift Tags:
Aug ’23
Reply to Custom Sequence, use `for` index don't change, but `while` is normal. why?
The for loop starts by calling your makeIterator() under the covers and then mutates that iterator, leaving your original box instance unchanged. The while loop is doing basically the same thing, except the makeIterator() call is explicit. If you changed that loop to print fib.currentIndex instead of iter.currentIndex then you would get the same output as the for loop.
Topic: Programming Languages SubTopic: Swift Tags:
Aug ’23
Reply to iOS 17 DateFormatter produces unknown characters instead of space for format "MMM dd, yyyy hh:mm a"
Is this an expected behavior in iPadOS 17 It would have to be a bug in Xamarin.iOS. It may be related to the original issue in this thread, but that’s not a bug in iOS per se. expected to be resolved in a future [...] Xamarin.iOS update? There’s not much Xamarin expertise in this Apple forum. But a quick web search suggests that Xamarin is at EOL with no iOS 17 support coming. You’ll need to migrate to .NET MAUI to support iOS 17 and later.
Topic: App & System Services SubTopic: Core OS Tags:
Aug ’23
Reply to Data equality checks have changed in iOS 17
In iOS 17, Data has changed how it performs equality. Actually what apparently changed is the behavior of JSON encoding, which now produces Data objects that are indeed different in your example. Remember that a Data object is just a blob of bytes with no concept of JSON keys. I've noticed if I modify the test case to use a JSONEncoder setting of encoder.outputFormatting = .sortedKeys, then it passes. That’s the crucial clue. If you don’t use .sortedKeys then the order of the keys after encoding is undefined. And it’s important to never make assumptions about undefined behavior. Unfortunately this test case makes such an assumption: that the undefined key order will happen to be the same if you perform the same encoding twice. So in iOS 16 and earlier it (apparently) just so happens that the keys are ordered the same when encoding twice in row, but in iOS 17 it just so happens that they are not. Both behaviors conform to the documented behavior. The bug is the test case’s unintentional reliance on the undefined key order. I noticed that in WWDC, Apple said they rewrote the entire JSONEncoder & JSONDecoder implementations [in Swift]. This may be the root of the behavior change. Swift's Dictionary can have different (undefined) key orderings even between dictionaries that have identical contents, whereas this may not be the case for Objective-C’s NSDictionary. And if the new JSONEncoder implementation in Swift uses Dictionary internally, well, there you go.
Topic: App & System Services SubTopic: General Tags:
Aug ’23
Reply to Usage of CKQueryOperation.recordMatchedBlock and .queryResultBlock
For the record block, let’s compare their signatures (adding some handy names and spacing for clarity): typealias OldRecordFetchedBlock = ( CKRecord ) -> Void typealias NewRecordMatchedBlock = (CKRecord.ID, Result<CKRecord, Error>) -> Void The main change is the CKRecord is now wrapped in a Result, so it can indicate that either a record was successfully fetched, or if an error occurred. You just need to unpack the record from the Result in order to use it: operation.recordMatchedBlock = { id, result in switch result { case .success(let record): self.saveToCoreData(record: record) case .failure(let error): // handle the error in some way } } The change from queryCompletionBlock to queryResultBlock is similar. The cursor and error are now wrapped in a Result rather than being separate parameters.
Aug ’23