Did Apple change NSUserDefaults sharing from iOS app to watchOS app - ios

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.

Related

Is it possible to download another app in Swift?

I’m new to swift, and was wondering if I could download an iPhone/iPad app using swift (for example, I’m looking for something like an App Store API).
In a word, no.
Apple's security protections don't allow apps to install other apps. That would be a huge vulnerability.
And, as Rob pointed out in his comment, creating your own App Store would be a direct violation of the App Store guidelines you have to agree to in order to publish your apps on Apple's App Store. (Their ball, their rules.)

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.

How often and how much iPhone share NSUserDefault data to Apple Watch?

Look at this Apple Docs
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.
Is there anyone know how to access iOS app's preferences from Apple Watch and how often it is updated on the Apple Watch.
I did try to search for document, but could not found any.
AFAIK, NSUserDefaults can contain upto much memory. It would be bad if iPhone try to save all this user config in NSUserDefault onto the watch.
They don't. You should use the WatchConnectivity framework. Here is an extended answer: Reading NSUserDefaults in watchOS 2 (I know App Groups doesn't work)

Persistent storage on Apple watch

I am looking for a way to store something on the Apple watch app that I can read later on enabling me to identify it uniquely.
I don't see any API at the moment that would let me do this. The closest I have got is to save an image in cache but since its just a cache, its not reliable.
My goal is to uniquely identify an Apple Watch.
Any pointers would be much appreciated.
You can save information to be accessible from both watch and iPhone in NSUserDefaults and App Groups like this:
let defaults = NSUserDefaults(suiteName: "group.com.your-bundle-id.app-group-name")
where "group.com.your-bundle-id.app-group-name" is your app group identifier.
For more details about NSUserDefaults and other ways to share data between Watch and iPhone see
Architecting Your App
for the Apple Watch
User App Groups OR NSUserDefaults to share data between your iOS apps.
Easily share small amounts of data between your iOS app and your
WatchKit extension with App Groups and NSUserDefaults. For access to
other resources, such as a Core Data store, use a shared container
between your iOS app and your WatchKit extension to simplify data
access and provide up to date information.
I think that this would be very useful, not only for identifying the watch, but also to load the UI faster (without synchronizing lots of data via Bluetooth first).
However, there seems to be no solution at the moment to do this.
It also seems to be impossible to get the hardware identifier of the watch.
Maybe this will be possible once normal third-party developers are allowed to write real watch apps (not just extensions of iPhone apps). The WWDC is in June.

iOS 8 How to get Serialnumber

In our applications the user autentications is based on the serial number.It seems that in ios 8 it is not possible to get the serialnumber.Is any other way?
Thanks in advance.
Apple deprecated access to a unique-per-device UUID (known as uniqueIdentifier as of iOS 6. As of iOS 7, they also blocked access to MAC querying the address, and other sorts of unique identifiers. Sometime between iOS 6 and today, they started rejecting any application that accesses this property.
There are two replacement APIs that might help: on UIDevice, there is identifierForVendor, that is consistent across your apps. And there is also an entire framework, AdSupport, who's job is to provide an identifier that can be used for advertising networks. This identifier has the limitation of people can change it whenever they want, so you cannot rely on it being consistent across multiple launches.
The hint Apple is trying to pass on here is "you cannot consistently, uniquely identify people per device across multiple apps that are not your own".
In addition to zadr excellent explanation I would like to not iCloud as another possible solution:
Simply store a value (as file or key-value) in iCloud. Only disadvantage of this approach is, that you will have to add the iCloud entitlement to your app if your app does not use iCloud yet. On the other hand there are some advantages
Very little / none additional effort necessary if your app already uses iCloud
No additional Frameworsk like AdSupport necessary
The saved value will be consistent between devices and app re-install
More than one app can share the ID by using the same iCloud (ubiquity container)
Of course in some cases this might be a little overdone but in other this can be a handy solution.
I would recommend using uniqueIdentifier as suggested above but saving in keychain. This way its reliably available to you all the time, and can be used to track the user.

Resources