watchOS get activity data - swift

How can I go about capturing daily activity data from Apple Watch at a high level (gyroscope and accelerometer data) or is that not possible (due to current limitations of the API)?
I am trying to figure out a way to find all occurrences of a custom workout performed during the day by a watch user. User installs the app, grants permissions where applicable. Launches daily to see workouts performed in the last day. The app pulls data, stores it, analyzes it and plots necessary metrics.
I want to know if this is possible - pulling data on launch to run analysis. If so, how?
I see this example from Apple on recording counts swings in a racquet sport but that seems to require instantiating and stopping various CoreMotion events such as startDeviceMotionUpdates and stopDeviceMotionUpdates in order for the app to retrieve them.
Any pointers?

Related

How can apps like Autosleep get days of historical motion sensor data?

I want to replicate some of the functionalities of sleeptrakcing apps like AutoSleep. Apparently I can not open the app for a day or two, and when I open it up, it can accurately access the sensor data on my Apple Watch to see if I'm moving or not at any given 15 minute interval.
I've tried looking at various functionalities of CoreMotion. The closest I've seen is using CMSensorRecorder and call recordAccelerometer to start recording. However, this only allows you to record up to 12 hours. And the user would have to start the app to start recording. This is clearly a limitation that AutoSleep doesn't seem to have, because it seems to get the data out of thin air.
Anyone know how it's possible to get historical Accelerometer data from WatchOS that stretches back a long time without actively recording it?

Access real time Heart Rate data on Apple Watch

Can we access the heart rate directly from the apple watch? I know this is a duplicate question, but no one has asked this in like 5 years. I know you can access it from the Health App but I'm not sure how "real-time" that will be.
If you don't expect 100% real-time.
You can use this one: HKAnchoredObjectQuery. I think it has a 300-500ms delay.
A query that returns changes to the HealthKit store, including a snapshot of new changes and continuous monitoring as a long-running query.

Apple watch complications update limit

I have a complication that may need to update every 5 minutes. this could easily sum up to 120 updates per day. Is there a way to only update when the user wake up the watch?
I belief the answer to your question in NO, there is currently no way to only update the complication when the user wakes up the watch.
The reasons:
The idea of a complication is that the user sees it as soon as he or she raises the watch and activates the display.
There is simply no time to activate or launch an app, nor to download a real-time value to display it as a complication.
Thus, the data must be present before the user watches the watch face with the complication.
In many cases, this can be ensured, if the data don’t change too often:
On watchOS, it is possible to schedule background tasks at certain intervals that download actual data from a server. In your case, you would like to schedule regularly (in your case about every 5 min) a WKApplicationRefreshBackgroundTask to download the actual value, but due to power consumption reasons, the number of tasks is limited:
Background app refresh tasks are budgeted. In general, the system
performs approximately one task per hour for each app in the dock
(including the most recently used app). This budget is shared among
all apps on the dock. The system performs multiple tasks an hour for
each app with a complication on the active watch face. This budget is
shared among all complications on the watch face. After you exhaust
the budget, the system delays your requests until more time becomes
available.
So there is no way to do this at rate of 1 per 5 min on watchOS.
One could try to do this via iOS, and send the new complication data using func transferCurrentComplicationUserInfo(_ userInfo: [String : Any] = [:]) -> WCSessionUserInfoTransfer, but the docs say:
If the complication is on the active watch face, you are given 50
transfers a day.
So I do not see any way to preload complication data at this rate before a user raises the watch.

How can an iOS app run a function in the background in a recurring manner (i.e. once an hour)?

On devices which support multitasking, I'd like my iOS app to run a function in the 'background' when the app is not running (i.e. it's suspended). I know that iOS supports running tasks in the background, but I'm not sure how to make the function recurring (and only when the app is not in the background). What's the best approach?
I'm not interested in running a long-term function in the background but a short-term function to simply update the application badge #. However this number is dynamically based on the app's data, and needs to run a query against core data.
To further clarify, yes, my core data will not be changing, but the badge represents a number of items due. As time progresses, more items will be due, so I want to update the badge to show the proper items due as time progresses. So if 5 items are due now, but half an hour later 3 more items are due, then by the time the next hour comes around, 8 items will be due even though the core data has not changed at all in and of itself.
It can't, the only task allowed to run in background are: audio, voip and location.
Why do you need to update the badge data every hour if the data stored within Core Data is not changing? ie. the app isn't running?
You can do this using push notifications, like previously posted, or you can use a scheduled local notification based on the data when the app is closed or backgrounded. I think those are pretty well your only options.

Ensuring correct date/time

we are creating a location-enabled app where users use this app to record certain events in the field.
The important part of the event data is when an event happened. This is no issue when user is online, but we also support situations when user is offline (by remembering & later syncing events).
There could be situations when users are offline and they change the time on the phone, so that event times are wrongly recorded.
So, what would be the best way to ensure we get a correct time, independent of user actions, given that device could be offline. Some ideas:
GPS time. Is it possible to acquire it?
Tracking system time changes made by user?
Any other idea?
Note: time does need second accuracy, approximately minute accuracy would be ok.
Note2: we are creating mobile apps for Android and iPhone, so I'm interested for generic solutions and also solutions that are specific to any of those two platforms.
I, personally, wouldn't worry so much about this scenario. The liklihood of someone intentionally changing the time on their Android (which periodically throughout the day syncs to a time server automatically) while offline seems low to me. That being said, the only way I could see compensating for this is to keep a service running in the background that keeps a running tally of the seconds passed since recording the location data offline. Once uploaded to your servers you could use the elapsed seconds to calculate a time offset from current UTC time. It's an awful lot to go through, but it would work.
GPS time is an interesting idea, but Android allows users of the SDK to send mock locations to their devices. I'm not sure you could reliably track changes to system time either, and even if you could you'd be capturing them after the fact without the current real time as context.
We use GPS times in our app for very similar reasons. Since our users are in different time zones and we want local times, we define from our server what time zone they are in at installation time (they don't move very far). Hadn't thought of the mock GPS locations, but you would need to be a fairly advanced user to do that.