Retrieve user defaults information from an Apple Watch - ios

I have an iPhone and an Apple Watch paired together, and there are some values stored in the user defaults of the phone. I want my Apple Watch to be able to retrieve that stored information somehow and bring it back to the Watch. What is the best method of achieving this with Swift?

Since watchOS2, you don't have any built in function for communicating between the iOS and watchOS app other than the WatchConnectivity framework. Due to the fact that Watch apps are no longer considered App Extensions, they don't have access to AppGroups and hence to UserDefaults on the iPhone.
For syncing UserDefaults, the updateApplicationContext(_:) function seems to be the best solution. You can send a dictionary of data with this function (the data you just saved to UserDefaults on the iPhone) and the system tries to make sure that the data is received by the time your app is displayed to the user. If the function is called several times before the app would be visible to the user (run in the foreground), the system overwrites the previous data, so the Watch app only receives the most recent data to display.

Related

Pass text from iOS label to WatchOS label - swift-

I've a problem, with my app.. I try to follow some guide like Passing data to Apple Watch app , but I'm not sure it will fit for my case.
I've some label with text on my iOS app, then I want to show this text on my watchOS app label, and I don't know which is the best way to pass this text and keep it synchronized with the iOS app..
Thanks a lot for your help!
For watchOS1, Since Watch App is included as an extension in your Host App. So, you can use App Group to share data between your Host App and your App Extension.
Refer to https://stackoverflow.com/a/44654185/5716829 for more on using App Groups.
Since watchOS2, you don't have any built in function for communicating between the iOS and watchOS app than the WatchConnectivity framework.
From the information provided in your question, the updateApplicationContext(_:) function seems to be the best solution for your problem. You can send a dictionary of data with this function and the system tries to make sure that the data is received by the time your app is displayed to the user. If the function is called several times before the app would be visible to the user (run in the foreground), the system overwrites the previous data, so the Watch app only receives the most recent data to display.
The right method for this is WCSession.updateApplicationContext(_ applicationContext: [String : Any]) https://developer.apple.com/documentation/watchconnectivity/wcsession/1615621-updateapplicationcontext "Sends a dictionary of values that a paired and active device can use to synchronize its state."

Apple watch - Storing data to Apple Watch separately without dependence on iPhone

I am working on an app which consists of an Apple Watch component. Once the iPhone app is launched, it will send information (device id, IP address, etc.) to Apple Watch via the WatchConnectivity framework and data will be stored to user defaults. The Apple Watch will use the information to send data to the server. But in some scenarios, the values from NSUserDefaults returns as "null".
For example
When the watch is switched on and off.
When the app is killed and not opened etc.
Please give some suggestions for storing data on Apple Watch permanently and without being dependent on iPhone every time.
I am storing stuff in the watch's filesystem by serializing/deserializing my custom objects by implementing NSCoding and using NSKeyedArchiver and NSKeyedUnarchiver.
Depending on the complexity of the data you want to store, it might be worth using a database framework (i.e. Realm or CoreData) to store persistent data on the watch.

CoreData not storing data across multiple iOS devices

I am trying to build an iOS application using Objective C.
Where say some user is logged into my App as UserName A and they want to invite for a particular task, another user of my App ,B using their FirstName/LastName/Phone Number.
I am using Coredata to store the user credentials when they register.
The issue is : This works fine when I register both A and B from the same iOS device but NOT when I register A from iOS device 1 and B from iOS device2.
Coredata seems to store only the user data in the local device.
How can I ensure my app works for all users logged in form any iOS device ?
Core Data does not upload data to any server or synchronize data across devices. It's designed as a local-only data store. You can turn on iCloud syncing in Core Data, but this has been deprecated as of iOS 10.
If you want your app data to be available across multiple devices, you'll need to write some code to do that. Apple provides CloudKit, and there are many third party solutions. But you can't just tell Core Data to sync data, because Core Data doesn't do that.

Independent operation of watchOS app when sharing app with iOS app

My iOS app uses CoreData as its data store and I have added a watchOS app to accompany it. Currently the workflow between the iOS and watchOS apps is as follows:
The watchOS app exposes a menu representing a subset of functions available in the iOS app
Choosing one of these options sends a message to the iOS app telling it which option was selected
The iOS app responds by packaging up any data needed by the watch for that particular function into a dictionary and sending this back to the watch in the reply handler
The watchOS app presents an interface to the user allowing them to change the values in the data
Each change sends a message to the iOS app which updates the core data store with the new values
This is working fine but clearly requires the phone to be connected to the watch throughout the use of the app for it to work. I'm wondering whether a model like the following would be possible:
As above
As above
As above
3a. The watch stores the data locally
As above
Each change updates the watch app's local copy of the data
The user can later check the data back in to the iOS app at which point it is merged into the core data database
I can guarantee that conflicts would not be an issue as the user would never be able to modify data which had already been created on the phone (it is not a requirement of the app to be able to do so).
So my question is, would the latter case allow the watchOS app to operate independently of the iOS app with the exception of transferring data, and is this a preferable method to the way I am handing this currently?
It's simpler for your watch app to be dependent on the phone. It's more complex for it to operate independently of the phone. Only you can
answer whether the added complexity to support true independence is worth it, since you're the person who has to implement, support, and maintain any additional code needed.
Do the changes make the watch app independent?
No, they don't let the watch app operate independently, since the watch still must request/receive data from the phone during steps 2 and 3.
For the watch app to be completely independent while away from the phone, it would have to query a local copy of the data which the phone updated as needed, instead of requiring the phone to send any remote data that the watch needs.
Is the change preferable?
Not as it stands. Your proposed change to defer updating the phone (even though it's still reachable) may require much unnecessary code related to locally storing data for the present, and merging updates back to the phone in the future.
Also, while you promise there presently is no merge conflict to deal with, there's no guarantee that any revisions you make to your app in the future won't introduce the possibility for conflicts to occur.
If you choose to establish two persistent stores, it would make your app less fragile to implement a merge policy now, to avoid your updates from completely failing to save, should a future conflict occur.
The real question...
Is the freedom to operate away from the phone (for hours) worth showing stale (or possibly misleading) data to the user?
Unless you also provide an indication showing when the data was refreshed by the phone, the user may assume that the displayed information is current and accurate, even though it may be hours old.
This adds more complexity to the watch app either in the user-facing UI or behind the scenes to handle stale data.
For your consideration, Apple Watch's Weather app simply shows no data at all when it can't obtain the current weather data from the phone (since users would want to know the current temperature and chance of precipitation).

Best practice to store a small amount of data (NSMutableDictionary) permanent on the WatchOS2

With the new architecture of WatchOS2, watch apps can run stand alone without a connection to the iPhone. What would be the best practice to store a small amount of data (by example a NSMutableDictionary), which normally would be stored in the NSUserdefaults. NSUserdefaults is not working on WatchOS2.
Concrete: When the app runs for the first time some data are collected, stored in the NSUserdefaults on the iPhone and than transferred via WatchConnectivity to the Apple watch.
If the user runs the next time the app stand alone on the Apple watch I need that data ton be retrieved.
You can use NSUserDefaults to store data locally. To share your data between Apple Watch and iPhone, you should use WatchConnectivity. As you said in comment, there is an another question-answer about NSUserDefaults here.

Resources