watchOS Complications: How to add context-based deep-links? - deep-linking

I want to create complications that when tapped open the watch app to a specific section in the app. I am using CloudKit and CLKComplicationDataSource.
Apple documentation even recommends deep-linking, but I haven't been able to find out how to do this. There is another similar question but no correct answer.
Note: I need to support watchOS versions below 9, so I cannot use widgetKit and I must use ClockKit (in case that makes a difference)
Here is what Apple says:

Related

Detect user's watchOS version from iOS app

I have an iOS app where I have some settings in the iOS app related to the watch. I only want to show them if the user has an Apple Watch that's compatible with my app.
In WatchConnectivity I can query WCSession's isPaired property to see if the user has a watch but I can't figure out how to determine the watchOS version (it needs to be >5.0 to use my app).
Is there a way to determine the watchOS version from the iOS app?
If the settings only apply if the user has your watch app installed, you probably just want to check that directly using WCSessions isWatchAppInstalled property.
Things get much trickier if you want to get the paired watch's OS version regardless of whether your app is installed. If the user runs the watch app, you could just grab the version on the watch side and send it over (with updateApplicationContext(_:)). Otherwise, there's no way that I know of to get the watchOS version -- and that kind of makes sense. From a platform security perspective, if the user hasn't installed your app then the details of their watch are kind of none of your business.
Here are two possible solutions. Number 1 checks for the OS which if I understand your question you already know, but then 2 checks for the OS version which is WatchOS 5.0 and later. This is what I have done so I hope it helps you.
1.
#if os(watchOS)
...your code
#endif
if #available(watchOS 5.0, *) {
...your code
}

Share AsyncStorage from iOS react native app with Apple Watch

I'm developing the main app with react native and the Apple Watch with Swift.
The main app (react native) uses AsyncStorage to store some values, that then are used as params for a fetch that shows a list.
After running the simulator, I found manifest.json inside
~/Library/Developer/CoreSimulator/Devices/D10E869B-040B-446F-9B8B-754F111442EC/data/Containers/Data/Application/AC837AFE-312B-4861-906D-EC9EEE7D029B/Document
s/RCTAsyncLocalStorage_V1
with the data inside.
I need to access those values in the Apple Watch in Xcode to do the same job as the iOS app. How do I access that data?
Since Apple Watch apps run independently from iOS app since watchOS 2, there’s really no way to directly access the data stored locally on iPhone — you’ll need to maintain some form of communication between your iOS and watchOS apps.
The framework intended for this is called WatchConnectivity. I see two more-or-less suitable solutions for your case:
Using transferFile to transfer your file from an iOS device to an Apple Watch whenever it got updated. The viability of this option highly depends on how big your file is.
Or you can just use updateApplicationContext to pass an already serialized data instead of transferring a raw JSON file — again, highly depends on your specific needs.
Unfortunately, I don’t know how WatchConnectivity is supposed to work with ReactNative. If you want a deeper introduction to this framework — I highly recommend watching this amazing video from WWDC 2015.

Did Apple change NSUserDefaults sharing from iOS app to watchOS app

I want to ask about how to use NSUserDefaults on the watchOS app.
Is its data different from the iOS app's NSUserDefaults's data?
There are a lot of stackoverflow questions about this topic and all of them have same answers. That said, for example
Watch apps that shared data with their iOS apps using a shared group
container must be redesigned to handle data differently. In watchOS 2,
each process must manage its own copy of any shared data in the local
container directory. For data that is actually shared and updated by
both apps, this requires using the Watch Connectivity framework to
move that data between them.
However, all the quoted text disappeared from the web page referred, see this accepted answer.
Instead, in current Apple Docs. There is
Additionally, iOS automatically forwards a read-only copy of your iOS
app’s preferences to Apple Watch. Your WatchKit extension can read
those preferences using an NSUserDefaults object, but it cannot make
changes directly to the defaults database.
I have 2 questions:
Which one is correct: all of StackOverflow questions' answers I mentioned above, or, the Apple Docs
Which mechanism iOS use to forward NSUserDefaults object to watchOS app? Is it reliable to be relied on for future development and how recent the data is up to date? Can this feature be deprecated in the near future?
Many thanks
To answer your first question, both answers you quoted from StackOverflow and Apple are correct. Apple forwards the iOS app's NSUserDefaults as read-only values, but the watch has it's own NSUserDefaults for its preferences. The main takeaway from the documentation is for watch apps to move away from shared container groups that use NSUserDefaults, (as this was how WatchKit apps were implemented). In watchOS, Apple has added WatchConnectivity which is the standard for sharing data between the iOS and watch apps.
To answer your second question, rely on NSUserDefaults as you would normally to store preferences related to each app separately and use WatchConnectivity for sharing data between apps.

How to get the current location in a WatchKit app?

If I'm not wrong, the App Watch can't take locations itself and needs to request it to the iPhone, so the current location is got in the WatchKit extension at iOS side... right?
I think this is a quite common thing WatchKit developers would do, but I don't find a clear tutorial/example of it, could somebody tell me one or post me some code? In addition, do you know if the way to deal with locations changes in watchOS 2?
EDIT: I've found that in some posts it is said that CoreLocation can be accessed from the WatchKit extension, and in others I've read that only the iOS app can... which is the correct?
You can access CoreLocation and all its methods directly from WatchKit itself. There's no need to employ any sort of additional logic, such as opening the parent app.
In watchOS 1, your WatchKit app is technically running on the iPhone, and you can therefore use (almost) any frameworks available to you on the iPhone (such as CoreLocation).
In watchOS 2, the WatchKit app is running on the Watch itself. I have done some research and I've not found anything that indicates you will have to make any changes to your usage of CoreLocation, and I will therefore assume the frameworks automatically handle the communication between the iPhone and the Watch.
I'll update this answer if I find anything indicating that you will have to employ some other logic to make this work in watchOS 2.

Can I access healthkit data from iWatch extension?

I am making a iWatch app where I need to show data from healthkit. is it possible to access healthkit APIs from iWatch extension?
No. It's mentioned specifically in the HealthKit Framework Reference:
"You cannot access HealthKit from extensions (like the Today view) or from a WatchKit app."
What you can do is call openParentApplication:reply: to talk to the iPhone app itself and retrieve that data. Search around for that method name and you'll find some examples on how to call it and get data back to the Watch from it.
UPDATE: As others have mentioned below, this has changed for watchOS 2. The documentation has not been updated yet, but check out the WWDC 2015 videos for HealthKit and the Watch for some snippets of code you can use with the Xcode 7 beta.
Yes, in watchOS 2 you will be able to.
Yes, it's possible on watchOS 2.
However, it's a bit confusing, because it's still mentioned in the HealthKit Framework Reference for watchOS
You cannot access HealthKit from extensions (like the Today view) or from a WatchKit app.
Do not care about this.
Follow a few steps below.
Follow Setting Up HealthKit in the reference, you are now ready to access
Follow Accessing HealthKit Data, then you will be able to access
Make sure your application is running on watchOS 2.
Please see the reference for more detail.

Resources