Posts under App & System Services topic

Post

Replies

Boosts

Views

Activity

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
373
Sep ’24
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
346
Sep ’24
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: <key>aps-environment</key> <string>development</string> <key>com.apple.developer.nfc.hce</key> <true/> <key>com.apple.developer.nfc.hce.iso7816.select-identifier-prefixes</key> <array> <string>D2760000850101</string> </array> <key>com.apple.developer.nfc.readersession.formats</key> <array> <string>TAG</string> <string>NDEF</string> </array> </dict> 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?) -> 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?) -> 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 -> 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 & 0xFF00) >> 8) mNdefRecordFile[1] = UInt8(nlen & 0xFF) // Copy the NDEF message data into the data starting at index 2 mNdefRecordFile.replaceSubrange(2..<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...
2
0
985
Sep ’24
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
670
Sep ’24
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
694
Sep ’24
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
1
416
Sep ’24
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
810
Sep ’24
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
532
Sep ’24
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
852
Sep ’24
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
376
Sep ’24
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
992
Sep ’24
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
533
Sep ’24
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
308
Sep ’24
Overlapping Segments and Duplicate Start Times in Workout Data
Hello, We're encountering overlapping segments and discrepancies when analyzing running/workout data for a 5-mile run. The expected splits for the run are: 8:39 9:06 8:30 8:39 8:43 0:08 However, the raw data includes segments where start times begin before the previous segment ends, and there are duplicate start times. Below is a sample of the raw data: "startDate": "2024-09-09T19:32:00.308-0400", "eventType": "segment", "eventTypeInt": 7, "endDate": "2024-09-09T19:37:56.135-0400" }, { "startDate": "2024-09-09T19:32:00.308-0400", "eventType": "segment", "eventTypeInt": 7, "endDate": "2024-09-09T19:41:08.476-0400" },``` // Here's an example of where the second segment start time falls in side the first segments startDate and endDate "startDate": "2024-09-09T19:54:22.658-0400", "eventType": "segment", "eventTypeInt": 7, "endDate": "2024-09-09T19:59:41.215-0400" }, { "startDate": "2024-09-09T19:58:44.624-0400", "eventType": "segment", "eventTypeInt": 7, "endDate": "2024-09-09T20:07:23.216-0400"
8
0
879
Sep ’24
HealthKit ID is the same with another Device
HealthKit tracker Id is the same with another Device, We are using an application to track our health progress and we are trying to connect our HealthKit to monitor our health data (steps and calories) but unfortunately we can't connect to the app (another application) at the same time because two devices is sharing just one health kit tracker ID. Can anyone help me to resolve this issue? Old phone was used by the other person before changing to new phone
1
0
383
Sep ’24
Wake-up detection with HealthKit
Hello HealthKit Experts & Enthusiasts! I am building an app called one sec which forces people to take a deep breath before they can use social media apps (it’s using Shortcuts Automations for that). One important feature of one sec is the Good Morning Countdown: For a specified time after waking up (e.g. 30mins) selected apps are blocked completely. This helps to start the day screen-free. They way it works is, the user grants access to read HKCategoryTypeIdentifier.sleepAnalysis data. I have implemented a HKObserverQuery and enableBackgroundDelivery in order to be informed whenever new HKCategoryTypeIdentifier.sleepAnalysis becomes available. I noticed that when I have my device connected to Xcode, this works as expected. However, when I quit the app and launch it from my Home Screen, my observer query is not informed about new sleep data (except when my app is running in foreground). Any ideas? Furthermore, I have noticed that sometimes sleep data is provided delayed to HealthKit, many minutes (sometimes even longer) after waking up, no sleep samples are to be found in the Health app. Of course, for my app it is crucial to get accurate + timely so apps can be blocked accordingly. Is this an issue that the Apple Watch first needs to send the samples to the phone? Thanks a lot for your help!
1
1
762
Sep ’24
HealthKit bugs related to new workout effort score - heart rate samples take forever to fetch, Health app displays invalid data
I am encountering issues on my device running iOS 18 that fetching heart rate samples associated to a given workout is very slow. Like 10+ seconds slow. This is unacceptable and unexpected. In producing a video to attach to a feedback, I also observed that Apple Health app displays incorrect information if a workout effort score is associated to a workout. In this image, you can see the Health app bug: Total Resting Energy != Estimated Workout Effort Score Here is the same workout after I delete the workout effort score using the Apple Health app: Can anyone else see if attempting to view 'heart rate' data within the workout summary in Apple Health is unbearably slow if that workout also has an effort score associated? My steps: Record workout (Apple Activity app on watchOS) Associate effort score View the workout on Apple Health (iOS) Attempt to view it's heart rate samples Observe very slow loading times Observe the incorrect cell label and value and disappearance of resting energy cell data Remove/disassociate the effort score from the workout by tapping the workout effort row, and swipe to delete the value. Navigate back, navigate back, and then go into the workout detail again At this time the UI fixes itself, but the loading of heart rate data is still super slow FB15269657 - HealthKit: Sample query to fetch heart rate samples associated to a workout is taking over 10 seconds - computing 'time in heart rate zone' FB15278790 - Health: Workout summary 'Total Resting Energy' label has value of 'Estimated Workout Effort Score' for a value, pushed view shows empty
0
0
634
Sep ’24