If anyone at Apple is looking, or others are curious and want to try and reproduce this and share, I believe I figured out the cause.
Background:
So my app captures MetricKit payloads and saves them into CoreData / SwiftData locally. After a period of time, I ship the payloads to CloudKit. This works for all of my other apps as I mentioned, my container entitlements are setup just fine, this new app has worked in the past, etc.
Cause:
It appears that when I use Xcode to download the container of my app, and then restore it, that there is some residual data in this process that causes the issue. In the container I found a few directories called MMCS in CloudKit and deleted them, then restore the container to my device(s). After doing this, it worked.
It looked something like this:
Container > AppData > CloudKit > Random Folder Identifier 1 > MMCS
Container > AppData > CloudKit > Random Folder Identifier 2 > MMCS
For safe measure I deleted other directories which was likely an unnecessary action as they appear to be artifacts of other frameworks, such as WeatherKit (Caches/weather-data.db and Caches/geocode_wk.db).
This is still an issue however, because many developers will take snapshots of their files this way to perform Core Data / Swift Data migration tests on their devices.
Post
Replies
Boosts
Views
Activity
Checkout this sample code: https://developer.apple.com/documentation/corelocation/monitoring-location-changes-with-core-location
Associated with the talk here: https://developer.apple.com/videos/play/wwdc2023/10147
Referenced from Adam's WWDC24 talk here: https://developer.apple.com/videos/play/wwdc2024/10212
Code change necessary
Add NSLocationRequireExplicitServiceSession as a Boolean to your app's Info.plist as the sample code shows.
I haven't been able to find any supporting evidence that this is possible given the current API.
FWIW, Apple likes Feedback. @alpennec @michael.h I suggest you file your own, feel free to mention mine so they can mark as related.
Here is my Feedback #
FB16218331 - Core Location: CLLocationUpdate doesn't have mechanism for influencing the 'filter accuracy' like CLLocationManager does - add functionality to API
FB16226614 - Core Location: CLLocationUpdate doesn't have mechanism for influencing the 'filter distance' like CLLocationManager does - add functionality to API
This is still an issue for me.
Has anyone else encountered indexes not updated in CloudKit public database? I'd hate to just burn a DTS for this.
This was an issue on my end that I didn't catch until now. In adding Shortcuts support earlier this summer I had to rename my Product Name to include a space due to how the system renders things. So my filters needed updating.
I have noticed a significant drop out in metric payloads on my local test devices since iOS 18. I am not reliably getting payloads either. I plan to visualize my payload reports over the last 6 months to show the count for my devices bottoming out around mid September.
FB15461298 - MetricKit: Production issue / regression with iOS 18 - Significant dropout or metric payloads being generated since 18.0 - nearly no reports
I will share my visuals here too as a reference once I have them.
Apple added some more new features related to sleep apnea without any documentation:
Sleep Apnea Event
Apple Sleep Breathing Disturbances
Hopefully all of these types get documented soon before they exit beta and clean up the types that were launched in September.
As for which types support this capability, check out the HKLiveWorkoutDataSource and inspect the types to collect property. You'll find that the types described by @DTS Engineer are consistent with this approach to double check.
Looking at a workout that Apple Activity app recorded, the 'effort sample' start and stop date are consistent with the workout duration.
Estimated effort score (3).
Start 9:08:21 PM
End 9:32:15 PM
Saved 9:32:15 PM
Workout
Start 9:08:20 PM
End 9:32:15 PM
Saved 9:32:20 PM
If I find some time I'll inspect the milliseconds for these dates and identify the exact order.
I'm curious of there is a timing issue between stopping a workout session, stopping the builder, and ending the session. Like it generates a sample AFTER the builder collection has completed and then gets dropped. It is not exactly easy to record a real workout with the debugger attached or firing up console to sniff out logs. I plan to rewrite all of my code using the async flavor of the APIs where possible instead of nested closures to see if that makes a difference. I can't wait for HKWorkoutSession and HKWorkoutBuilder to be actors and fully async (hopefully in the future)!
FB15315876 - Documentation / HealthKit: Publish documentation about .workoutEffortScore and .estimatedWorkoutEffortScore
Since it was introduced last summer, it hasn't worked for me on the simulator like it does on real devices. I have defaulted to just developing with this capability on real devices.
June 2023
FB12328242 - Health / Simulator: New mirrored workout session sendData throwing 'host device not connected' for watchOS and iOS simulators
July 2024
FB14310200 - HealthKit / Simulator: workoutSessionMirroringStartHandler function is not invoked when mirroring Apple Watch simulator to iPhone simulator in Xcode 15
@PurrProgramming officially voice your feature request to read (and write) this data via Feedback Assistant.
Apple, here is my feedback #
FB15382945 - HealthKit: Give third party developers access to the internal heart rate zones recorded and associated with Activity app workouts
I want this too. Apple, we like making workout apps for your platform, clearly, you like to tell us each year how many health and fitness apps there are. Open up heart rate zone APIs and management with respect to workouts to third party developers. It has been a few years for you to stabilize the feature and internal API to make ready for public!
The speed of which Apple Fitness on iPhone can calculate heart rate zones is within a moment, at present, fetching all heart rate samples associated to a workout and computing the time in each zone is an order of seconds. Evidently, Apple is writing this data privately in HealthKit because you wouldn't be saving health and fitness data outside of HealthKit db, right?
FB15382945 - HealthKit: Give third party developers access to the internal heart rate zones recorded and associated with Activity app workouts
Years ago, I found via printing metadata on workouts saved by Apple's Activity app on Apple Watch that they were saving metadata keys and structures using _HKPrivateMetadata***. I have a feedback I wrote years ago about workout splits, but I can't find anything about heart rate zones, but it still feels familiar from the summer they introduced it.
For the time being, @ravdamani @simonfromhelix and any other third party developer, do you have interest in contributing to an open source 'third party metadata' keys swift package? The issue with metadata, custom keys that is, is other apps including Apple's Health app can't know about localization or appropriate meaning. For example, I allow my users to differentiate between canoeing and kayaking, and for the time being until Apple decides to split them into two different activity types (FB7807902 - June 2020). I wanted to use a key 'HKMetadataKeyPaddleSportsType' BUT, that doesn't localize at all and is confusing to users in other apps. I balanced this with usability for English by declaring the key name as 'Paddle Sports Type'. The first feedback below would mitigate that, but it isn't really in the spirit of sharing that Apple teaches health developers to follow. The second additional feedback is related to those private metadata. Just try saving any of these keys:
_HKPrivateMetadataSplitActiveDurationQuantity
_HKPrivateMetadataSplitDistanceQuantity
_HKPrivateMetadataSplitMeasuringSystem
Private API? No, it is a string value provided to a dictionary that should accept any string. Private Usage? Yes, this will crash your code at runtime.
Related:
FB15053061 - HealthKit: Allow third party developers to create hidden metadata that can only be read by apps that belong to the same TeamID that generated the sample
FB15052902 - HealthKit: Custom metadata keys are being rejected with an undocumented error
@Quappi did you make sure to enable HealthKit Background Delivery in your Signing & Capabilities tab? I don't remember off hand if you try to enable via code and don't have this setting enabled if you get errors or not.
This would be the first thing that I would double check. You should also check the docs about background delivery, not all types deliver in the background immediately.
@lemessurier I would follow the practices outlined in this video: Testing Tips & Tricks
If your goal is to test your logic, this is the way to do it. If your goal is to exercise radio functionality and transmit and receive packets, you should use UI Tests and have your physical device in proximity to your CI machine.
As you have likely found out, you cannot instantiate a CBPeripheral, nor can you instantiate CBService, CBCharacteristic, and CBDescriptor.
If you're really motivated, you could explore using the mac's Bluetooth to emulate your device. You'd need to create a mechanism to control that 'Mac app' from your XCTest suite. FYI, Process isn't available on iOS, thus you can't run command line tools from an iOS XCTest suite to control your Mac app. Maybe you could get it to work with a local HTTP Server and drive it that way.
@Kenn25 Which API are you referring to as the 'HealthKit tracker Id'?
@sgonser which application is the source of the workout?
Some apps save segments for both kilometer and miles so that it is quick and easy to fetch later based on the users preference and locale. To your earlier comments and question, this might be why you are seeing segments overlap of segments.
Namely the Apple Activity app on watchOS does this. I recorded a walk on a beach in Ireland earlier this year. You can see my pace wasn't very high...there were many interesting shells, rocks, and sealife.
So from the image above, the first segment is the first 1 KM, the second is the first 1 MI, third is 2nd KM (remainder), and the fourth is the 2nd MI (remainder).
The HKStatisticsQuery API is very powerful. Another approach you could take, given another workout apps segments, compute the sum distance of that segment interval. If it is near 1-mi, you know the segment is a mile, otherwise if it is near 1-km, you know it is kilometers. In terms of determining that last segment, look at the segment before which has an end date that matches or roughly matches the start date of the last segment. Don't do math that looks exactly for 1-KM or 1-MI because the odds of the sample data generating exactly a round number are slim at best.