Swift UserDefault :sharing data via share group doesn't work - swift

just started swifting recently and got an issue by using app group to share data between iOS devices.
basically I have setup the project followed the steps below:
[iPhone]
Enabled App Group for the iPhone target
initialed data below(groupID is matched what I set in the project):
sharedDefaults = NSUserDefaults.init(suiteName: groupID)
sharedDefaults?.setObject("User Default Shared String", forKey: "test")
sharedDefaults?.synchronize()
double checked the test string by loading user default locally, which is able to display in the Log.
let t_sharedDefaults = NSUserDefaults.init(suiteName: groupID);
t_sharedDefaults?.synchronize();
let str = t_sharedDefaults?.valueForKey("test") as! String;
print(str);
[watch extension]
Create a new watch extension target.
Enable App Group.
Load the User default data under awake with context via the code below:
sharedDefaults = NSUserDefaults.init(suiteName: groupID);
sharedDefaults?.synchronize();
let str = sharedDefaults?.valueForKey("test")
print(str);
I have run the iPhone target first, and then the watch app.
However, the watch app is not able to read expected data from the user default.
I have also uploaded the test project in Github, please let me know if you have any thought on this issue.
[Github]
https://github.com/mattcn/WatchOS_DataSharing
Thanks for your help in advance.

In Watch OS1 this worked, but in Watch OS2 there has been some changes. You need to use something called WatchConnectivity to send the data you want to save to the watch.
so even if you use shared user defaults or app groups the data you put inside them will be on the watch and so not accessible from the iOS app.
To send data to the watch you can use the WatchConnectivity framework.

Thanks Ashish to bring the difference between OS1 and OS2 up.
just found a good reference from:
NSUserDefaults(suiteName:) on iOS 9 and WatchOS 2 - not working?
In watchOS 2 you need to keep in mind that there is 2 different processes running:
Apple Watch Process
iPhone Process
Both of these processes have their own sandbox that's why they call it "native", so if you try to use the shared NSUserDefaults it will not work because the Apple watch app has a completely different sandbox than the host iPhone app.
If you want to save something from your phone to the NSUserDefaults on the Apple watch Target:
Use WatchConnectivity to send the data you want to save to the watch. Then when the watch receives the data you sent to it, save it to the Apple watch's default NSUserDefaults.

Related

NSUbiquitousKeyValueStore.didChangeExternallyNotification fires also when change is done on device itself

My app worked fine until iOS 16.0.
When I write to iCloud: NSUbiquitousKeyValueStore then the didChangeExternallyNotification notification is triggered also on the device I wrote to iCloud. So it did not change externally but internally. Therefore my app runs into a loop ;-(
Does anyone have the same issue?
I had contact with Apple and found at the you need to use 1 var:
let defaultsAppGroup = UserDefaults(suiteName:"xxx")
When using:
UserDefaults(suiteName:"xxx").set()
Multiple instances of UserDefault are made and therefore a didChangeExternallyNotification will be triggered to the other instances.

iOS iCloud document change notification

Can you, in Swift get a change notification when a document in the apps's iCloud Drive container changes?
For example I am testing a simple concept where I am storing all app data as a json string in the app's iCloud Drive container and I am loading it when the app launches. I can retrieve and save the json string on demand on multiple devices, but I am wondering if there is a way to get a change notification sent to an app when the file is changed on another device.
If so, some direction would be appreciated.
If you are using UIDocument, you can register for UIDocumentStateChangedNotification (for a particular document), otherwise if you are looking for changes in the App's iCloud container you need to use NSMetaDataQuery which is described in Discovering an App's Documents in Document-Based App Programming Guide for iOS

How to send data from Iphone to Watchkit in OS2 in SWIFT

I want to send a dictionary from iPhone to Watchkit in watchOS 2.
In watchOS 1 it works fine for me with appgroups but in watchOS 2 I know that we have to use WCSession but I don't know how to use it.
Please help me find the solution.
This blog post should help you out.
From that post: First, you'll create and activate a WCSession like so:
if (WCSession.isSupported()) {
let session = WCSession.defaultSession()
session.delegate = self
session.activateSession()
}
For transferring a dictionary:
let applicationDict = // Create a dict of application data
let transfer = WCSession.defaultSession().transferUserInfo(applicationDict)
Then, on the receiving end, you'll need to implement session:didReceiveUserInfo: (Developer documentation). Note, according to Apple's "watchOS2 Transition Guide,"
To begin communication, both your Watch app and your iOS app must have an active WCSession object. Typically, each app creates, configures, and activates a session object at launch time and stores a reference to it in a central location. When you want to send data, you retrieve the session object and call its methods.

How can Apple Watch listen to data change on iPhone?

Let's say the iPhone has a text field or any internal data, upon the data change, I want to push it automatically to the Apple Watch. I know I can use the share data. But that seems to require user to initiate the call (e.g. pressing a button) on the Watch. Is there a listener on the Apple Watch that I can use if there is a change in the shared data? Or there is way for the iPhone to automatically push data to the watch, and the watch just receive it and display it? Or any other way?
You can see this answer. MMWormhole seems a good way to communicate between App and its extensions (i.e. Watch App).
Hope this helped.

Apple Watch and iphone communication

I am implementing apple watch app with in my existing app.I need to full fill these task between both iphone and watch
1) sending data from watch to iphone Done (by using openParentApplication).
2) getting call back also done (using openParentApplication call back method)
3) I need to get apple watch notify when user click on a button on iphone app .I have implemented reverse functionality using openParentApplication.
I stuck how to update apple watch UI after user click on any button or any particular task happen on iphone app.
Please let me know is there any way to perform passing event and data from iphone to apple watch
Please use this link https://github.com/mutualmobile/MMWormhole for communication between iphone and watchKit.
You should checkout the new WCSessionDelegate is watchOS 2.0. It can be implemented on both the Apple Watch and contains multiple methods for sending data back and forth between the two devices. Detailed information can be found in the WWDC video Introducing Watch Connectivity