Post

Replies

Boosts

Views

Activity

How to start a legit companion App from iPhone App which uses CoreMotion?
I have an iOS application for the iPhone that works with a companion app on the Apple Watch, using CoreMotion to provide data. How can I launch the Apple Watch companion app from the iPhone app before starting data recording? Can startWatchAppWithWorkoutConfiguration(...) be used for this without registering an actual workout with HealthKit? Or can I register this action as a new custom workout?
1
0
68
1w
iOS 18 didFinishLaunchingWithOptions called during prewaming
Hi, I have seen a lot of answers in different threads Thread 1, Thread 2 that if an app doesn't support scenes, didFinishLaunchingWithOptions shouldn't be called during prewarming. Additionally, DTS Engineer on this Thread 3 mentioned that starting from late iOS 15, didFinishLaunchingWithOptions definitely won't be called during prewarming. However, we are still seeing in our logs, that didFinishLaunchingWithOptions is called during prewarming, for some users, even on iOS 18. Our app doesn't support scenes, and our AppDelegate is completely Objective-C. The problem is that in didFinishLaunchingWithOptions we set up our CoreData and Networking stack then we make a network request to fetch data and store it in database. When the app is launching in a prewarming state, CoreData stack can't load the persistent stores because the protected data isn't accessible during prewarming. We are setting the FileProtectionType to completeUnlessOpen for NSPersistentStoreDescription, which means the Core Data files are considered protected data. When user eventually launches app, network request resumes and crashes when trying to store data in database because Persistent Stores not loaded. What would you recommend to resolve this issue? Rewriting the Core Data stack for lazy initialization is quite challenging since we're using an old library (RestKit) for networking and Core Data caching. Thanks.
1
0
83
1w
HKLiveWorkoutBuilder only reporting heart rate - No other measurements
I'm using Healthkit with the following H/W specs: Apple Watch, series 8, OS: 10.6.1 (21U580) iPhone 11 Pro, OS: 17.6.1 Mac Studio M1 Xcode ver: 16.0 (16A242d) I am trying to get Apple Watch to report heart rate, HRV, respiratory rate, and body temperature using Healthkit's HKLiveWorkoutBuilder implementing HKLiveWorkoutBuilderDelegate's workoutBuilder method. However, the only reported value that is found from the workoutBuilder method's collectedTypes (a Set of HKSampleType objects) is HKQuantityTypeIdentifierHeartRate. Nothing for HRV, respiratory rate, or body temperature. All entitlements are set up, the plist filled in, and capabilities in place. Not sure why only the heart rate is reported from the watch but nothing else. I've scoured StackOverflow, Apple developer forums, even ChatGPT but none of the solutions work. Any help most appreciate! The model code is: import Foundation import HealthKit class WatchModel: NSObject, HKLiveWorkoutBuilderDelegate, HKWorkoutSessionDelegate { private let healthStore = HKHealthStore() private var workoutSession: HKWorkoutSession! private var workoutBuilder: HKLiveWorkoutBuilder! override init() { super.init() requestAuthorization() startWorkoutSession() } private func requestAuthorization() { let heartRateType = HKQuantityType.quantityType(forIdentifier: .heartRate)! let respiratoryRateType = HKQuantityType.quantityType(forIdentifier: .respiratoryRate)! let HRVRateType = HKQuantityType.quantityType(forIdentifier: .heartRateVariabilitySDNN)! let temperatureRateType = HKQuantityType.quantityType(forIdentifier: .bodyTemperature)! let healthDataTypes: Set = [heartRateType, respiratoryRateType, HRVRateType, temperatureRateType] healthStore.requestAuthorization(toShare: healthDataTypes, read: healthDataTypes) { (success, error) in if !success { print("Authorization failed") } } } func workoutSession(_ workoutSession: HKWorkoutSession, didChangeTo toState: HKWorkoutSessionState, from fromState: HKWorkoutSessionState, date: Date) { } func workoutSession(_ workoutSession: HKWorkoutSession, didFailWithError error: any Error) { } func workoutBuilderDidCollectEvent(_ workoutBuilder: HKLiveWorkoutBuilder) { } func startWorkoutSession() { let configuration = HKWorkoutConfiguration() configuration.activityType = .other configuration.locationType = .indoor do { workoutSession = try HKWorkoutSession(healthStore: healthStore, configuration: configuration) workoutBuilder = workoutSession.associatedWorkoutBuilder() workoutBuilder.delegate = self workoutBuilder.dataSource = HKLiveWorkoutDataSource(healthStore: healthStore, workoutConfiguration: configuration) let dataSource = HKLiveWorkoutDataSource(healthStore: healthStore, workoutConfiguration: configuration) let respiratoryRate = HKQuantityType(.respiratoryRate) dataSource.enableCollection(for: respiratoryRate, predicate: nil) let bodyTemp = HKQuantityType(.bodyTemperature) dataSource.enableCollection(for: bodyTemp, predicate: nil) let hrv = HKQuantityType(.heartRateVariabilitySDNN) dataSource.enableCollection(for: hrv, predicate: nil) workoutSession.delegate = self workoutSession.startActivity(with: Date()) workoutBuilder.beginCollection(withStart: Date(), completion: { (success, error) in if let error = error { print("Error starting collection: \(error.localizedDescription)") } }) } catch { print("Failed to start workout session: \(error.localizedDescription)") } } func workoutBuilder(_ workoutBuilder: HKLiveWorkoutBuilder, didCollectDataOf collectedTypes: Set<HKSampleType>) { print("collected types: \(collectedTypes)") for type in collectedTypes { if let quantityType = type as? HKQuantityType { if quantityType == HKQuantityType.quantityType(forIdentifier: .heartRate) { if let heartRateQuantity = workoutBuilder.statistics(for: quantityType)?.mostRecentQuantity() { let heartRateUnit = HKUnit(from: "count/min") let heartRateValue = heartRateQuantity.doubleValue(for: heartRateUnit) print("heart rate: \(heartRateValue)") } } if quantityType == HKQuantityType.quantityType(forIdentifier: .heartRateVariabilitySDNN) { if let hrvQuantity = workoutBuilder.statistics(for: quantityType)?.mostRecentQuantity() { let hrvUnit = HKUnit.secondUnit(with: .milli) let hrvValue = hrvQuantity.doubleValue(for: hrvUnit) print("HRV: \(hrvValue)") } } if quantityType == HKQuantityType.quantityType(forIdentifier: .bodyTemperature) { if let bodyTempQuantity = workoutBuilder.statistics(for: quantityType)?.mostRecentQuantity() { let tempUnit = HKUnit.degreeCelsius() let tempValue = bodyTempQuantity.doubleValue(for: tempUnit) print("body temp: \(tempValue)") } } if quantityType == HKQuantityType.quantityType(forIdentifier: .respiratoryRate) { if let respRateQuantity = workoutBuilder.statistics(for: quantityType)?.mostRecentQuantity() { let respRateUnit = HKUnit(from: "count/min") let respRateValue = respRateQuantity.doubleValue(for: respRateUnit) print("breathing: \(respRateValue)") } } } } } }
6
0
253
1w
Questions regarding PIN code pairing in AccessorySetupKit
Hi, we are trying out AccessorySetupKit on our app for pairing with an IoT device via Bluetooth. I can see from this WWDC2024 talk Meet AccessorySetupKit that ASK supports BLE pairing methods with a PIN code. Is that enabled through this bluetoothPairingLE option on ASAccessory.SupportOptions? Is it correctly understood that this is referring to the Secure Simple Pairing feature in the BLE specs? This might be due to my unfamiliarity with Secure Simple Pairing, but does it require the PIN code again after it has been paired but disconnected and then re-connected? Any help here would be greatly appreciated.
1
0
91
6d
recoverActiveWorkoutSession() inaccurate for paused sessions
When a workout session is being recovered, if it is paused, the elapsed time will be incorrect. It will seem like that workout never was paused. The recovery works fine if the workout was never paused. Steps to reproduce: Implement recoverActiveWorkoutSession Start workout Pause session and print the elapsed time Stop simulator / cause crash When recoverActiveWorkoutSession is called the elapsed time will not equal the elapsed time when the session was paused. Here is my implementation. I haven't seen any examples online. guard let recovered = try? await healthStore.recoverActiveWorkoutSession() else {return} self.session = recovered self.builder = recovered.associatedWorkoutBuilder() self.session?.delegate = self self.builder?.delegate = self self.builder?.dataSource = HKLiveWorkoutDataSource(healthStore: healthStore, workoutConfiguration: recovered.workoutConfiguration) self.sessionState = recovered.state
1
0
122
6d
AW10 and iPhone 16 notifications not working while using CarPlay
I just switched back to Apple Watch from Garmin, and in the time away I got both work and personal vehicles with CarPlay. I've noticed that my AW10 does not get ANY notifications pushed to it while I am using CarPlay, which is annoying because only texts and calls get pushed to my CarPlay screen, so i miss everything else. Additionally, and this may be a bug issue with iOS18, but I also just noticed that my phone (16) does not light up/make sounds for notifications while using CarPlay - so it doesn't light up, nor do the vehicle speakers make sound with IG/snapchat/etc notifications, and even the screen "lock" sound doesn't audibly go off. I've only had CarPlay for a few months, but I typically keep my phone on Silent anyway, so maybe I'm just noticing this now and its not necessarily a new issue? it does make the sound when i get a text, so logically everything else should make a noise. I've made sure that my general focus and car focus modes are OFF. Sound is ON. Sound volume setting is all the way up. Have also restarted both phone and watch, and “forgot“ the phone from the vehicle and reconnected Am I doing something wrong here? is there a solution for either problem? From what I've seen, some people say that the AW not getting notifications at the same time as Carplay is a built-in safety feature, which most people do not want... maybe its the same with the phone not alerting to non-text/call notifications?
1
0
101
6d
Simulating & tools for testing pre-warming state
Hi there I have a large codebase with many dependencies. I have a bug which I suspect is caused by accessing the keychain when the app has launched for pre-warming and as a result the keychain is inaccessible. Are there any recommendations for simulating or testing this app state, and for identifying any static initialisers in my dependencies that could be contributing to my issue? Thanks
3
0
136
2w
How to cache CloudKit records efficiently in SwiftUI
I'm building a SwiftUI social photo-sharing app that uses CloudKit, where user profiles (including a CKAsset for profile pictures) are displayed throughout the app. To reduce redundant fetching of profiles across multiple views, I’m trying to implement a cache for the profile CKRecord into a custom model. (Important for handling the CKAsset for a user’s profile picture, ensuring it’s moved from the CloudKit fileURL staging area) Here's my current approach: struct UserProfileModel: Identifiable { let id: String let displayUsername: String var profilePicture: UIImage? = nil } class UserProfileCache: ObservableObject { static let shared = UserProfileCache() @Published var cache: [UserProfileModel] = [] } Is this a solid approach for caching CKRecords, or is there a more efficient way to structure this for performance and memory management? I'd appreciate any input or advice on improving this architecture for performance, memory management, and handling profile updates. Thanks in advance for your help!
0
0
110
6d
CKModifyBadgeOperation is no longer working?
Whilst all current answers to this question indicate the depreciation of CKModifyBadgeOperation, all of them had advised up until 2022 that it could still be used due to Apple not having a replacement Api. Upon running the following code: badgeReset.modifyBadgeCompletionBlock = { (error) -> Void in if error != nil { print("Error resetting badge: \(error!)") } } CKContainer.default().add(badgeReset) When run I receive the following error: Error resetting badge: <CKError 0x3001ddf50: "Invalid Arguments" (12/1017); "CKModifyBadgeOperation is no longer supported"> And from testing following this, the badge count incrementation issue continues, indicating that this has been completely invalidated and cannot be used at all. Even with UNUserNotificationCenter.current().setBadgeCount(0) this only clears the badge count temporarily. I'm aware of the proposed "workaround" of creating an extension that manually keeps track of notification count & sets the badge accordingly when a notification is received. However I'm trying to ascertain if as of this current point in time there is now no way whatsoever to clear the badge count on the Cloudkit sever level?
3
0
324
Aug ’24
How to use notification to notify shared container changes in cloudkit?
I would like to create a private container and share a zone between two users with different iCloud accounts. All changes made by one would be notified with push notifications to the other user's db. Both could change the same information. Exactly as it is done in this apple project. https://developer.apple.com/documentation/cloudkit/shared_records/sharing_cloudkit_data_with_other_icloud_users However, I have been reading this code for days and I am stuck on it, it is extremely complicated for my level. I would really like to know if there is any simple project that uses the same idea to build this logic with swiftui.
2
0
119
6d
USBDriverKit driver not showing up in settings on iPadOS 18
In iPadOS 17.7 my driver shows up in settings just fine. After recompiling with Xcode 16 and installing my app (containing my driver) on iPadOS 18, the app shows up in settings but the driver-enable button is missing from Settings. When I plug-in my custom USB device, the app cannot detect it and I am left with no way to manually enable the driver, as I did in the previous version of iPadOS.
1
0
87
6d
Host Card Emulation / Card Session for payment URL
We have a financial application where we want to use NFC to broadcast a Payment URL to another iPhone or Android device when initiating a payment transaction. This will then open the banking application installed on the recipient’s device, allowing the transaction to be completed. We have already made the necessary requests to Apple and configured the entitlements file as follows: &lt;key&gt;aps-environment&lt;/key&gt; &lt;string&gt;development&lt;/string&gt; &lt;key&gt;com.apple.developer.nfc.hce&lt;/key&gt; &lt;true/&gt; &lt;key&gt;com.apple.developer.nfc.hce.iso7816.select-identifier-prefixes&lt;/key&gt; &lt;array&gt; &lt;string&gt;D2760000850101&lt;/string&gt; &lt;/array&gt; &lt;key&gt;com.apple.developer.nfc.readersession.formats&lt;/key&gt; &lt;array&gt; &lt;string&gt;TAG&lt;/string&gt; &lt;string&gt;NDEF&lt;/string&gt; &lt;/array&gt; &lt;/dict&gt; I've tried to use CardSession with the sample code provided by Apple on their site: Card Session The connection between the devices (two iPhones, OS is above iOS 17.4) is established, the event stream's case .received(let cardAPDU): works, however, when I send the response, nothing really happens Initial APDU response: CLA | 0x00 INS | 0xA4 P1 | 0x04 P2 | 0x00 DATA | 0x7D2760000850101 (guess this is the AID) Le | 00 Sending the apdu response in the event stream via: do { guard let request = APDUUtil.createAPDURequest(from: paymentUrl) else { return } try await cardAPDU.respond(response: request) await cardSession.stopEmulation(status: .success) } static func createAPDURequest(from paymentUrl: URL?) -&gt; Data? { guard let paymentUrl else { return nil } let ndefMessage = APDUUtil.createNDEFMessage(from: paymentUrl) APDUUtil.updateNdefRecordFile(ndefMessage: ndefMessage) let data = Data(mNdefRecordFile) let apdu = NFCISO7816APDU(instructionClass: 0x00, instructionCode: 0xA4, p1Parameter: 0x04, p2Parameter: 0x00, data: data, expectedResponseLength: -1) // Tried with different values return apdu.data } static func createNDEFMessage(from url: URL?) -&gt; NFCNDEFMessage? { guard let url, let payload = NFCNDEFPayload.wellKnownTypeURIPayload(url: url) else { return nil } return NFCNDEFMessage(records: [payload]) } static func updateNdefRecordFile(ndefMessage: NFCNDEFMessage?) { guard let ndefMessage else { return } // Convert the NFCNDEFMessage to Data let ndefMessageData = ndefMessage.records.reduce(Data()) { result, record -&gt; Data in var result = result result.append(record.payload) return result } let nlen = ndefMessageData.count mNdefRecordFile = [UInt8](repeating: 0, count: nlen + 2) // Store the length in the first two bytes (big-endian format) mNdefRecordFile[0] = UInt8((nlen &amp; 0xFF00) &gt;&gt; 8) mNdefRecordFile[1] = UInt8(nlen &amp; 0xFF) // Copy the NDEF message data into the data starting at index 2 mNdefRecordFile.replaceSubrange(2..&lt;mNdefRecordFile.count, with: ndefMessageData) } Could someone please help? I also tried to send the payment url as Data made from url. We have a working Android application, which uses HCE too (they use NDEF message and byte arrays in communication). As I've seen, the NFCNDEFReaderSessionDelegate and NFCTagReaderSessionDelegate is not suitable for communication between two iOS devices...
1
0
141
1w
Bluetooth State Restoration: Relaunch app after update?
Hi. Background: We have an app acting as central, keeping a persistent connection to a peripheral body worn sensor, in order to ensure that the sensor behaves as expected. We've managed make a robust system, that stays connected while the peripheral is in range. When the peripheral gets out of range we're fine with the app being suspended, as long as it's revived when the sensor gets back in range. This works fine using the Restoration Identifier This revival works also works fine after a phone restart. Now for the question: It doesn't work when upgrading the app. (tested in testflight) As the App Upgrade case isn't specified in: https://developer.apple.com/library/archive/qa/qa1962/_index.html we'd like to know if this case is supported. If it is supported, we'd be happy if you could provide some additional insights. Best Regards Rasmus Tønnesen UNEEG medical
2
0
80
1w
How to allow my app to receive BLE data from sensor while running in background?
I have a sensor that communicates via BLE periodically. The intention is for it to be a set it and forget it kind of thing. The user will check the app periodically but won't be doing so frequently. I need the app to be able to still receive the BLE data from the sensor even if it's running in the background so that when the user does check the app, they can see everything that's been happening. I've read a lot from 2020 - 2021 where it seems many developers are struggling with the same issue. Is there a supported way to do this now? How to have my app run in the background and still be able to receive BLE data?
1
0
111
1w
Live Caller ID Lookup Extension - No option in phone settings
iOS 18 (22A3354) will not offer a option in settings (> Apps > Phone) after calling openSettings to enable live caller id lookup extension. iPhone and MacBook are in the same network. The PIRService runs on MacBook and is reachable via iPhone Safari (via http://MacBookPro:8080/). Hummingbird print log: hb_method=GET hb_uri=/ [Hummingbird] Request. After deploying the application via Xcode to the iPhone no requests are printed in the terminal. The extension was added like documented and bundle id is also checked multiple times. issuerRequestUri in service-config.json is http://MacBookPro:8080/issue. As far as I can tell, everything has been set up in accordance with the Testing Live Caller ID instructions. Is there something missing?
7
0
259
2w
SwiftData ignore changes on App Intents
Hello everyone, Xcode 16.0 SwiftData project. CloudKit. WidgetConfigurationIntent. For some reason, I see a really weird behavior. I have a shared ModelContainer and an interactive widget where I update the model data through an app intent. This is my model - @MainActor class ItemsContainer { static let shared = ItemsContainer() var sharedModelContainer: ModelContainer! init() { self.sharedModelContainer = container() } func container() -> ModelContainer? { if let sharedModelContainer { return sharedModelContainer } let schema = Schema([ Session.self, ]) let modelConfiguration: ModelConfiguration modelConfiguration = ModelConfiguration(schema: schema, isStoredInMemoryOnly: false, cloudKitDatabase: .automatic) do { let container = try ModelContainer(for: schema, configurations: [modelConfiguration]) self.sharedModelContainer = container return container } catch { fatalError("Could not create ModelContainer: \(error)") } } } And this is how I get the model context across the app and the app intent - let modelContext = ModelContext(ItemsContainer.shared.sharedModelContainer) The problem is that somehow, when I update the model context in the app and then in the widget (I save the context after every change), the data is synced between the app and the widget, but then, the data is changed back to the previous state and kind of ignores the widget changes. Didn't happen before iOS 18/Xcode 16. Any idea? Thanks a lot!
2
0
178
1w