What communication to use, updateApplicationContext or sendMessage for constant data sync - swift

I have an iOS shopping list app, where items are added and displayed in a tableView. I want to create a Watch App Extension but I’m thinking of what is the best function call to use in this case, the updateApplicationContext(:) method or the sendMessage(:replyHandler:errorHandler:) method I was reading the documentation but I’m a little confused since both seem to work.
Here is the functionality I’m expecting to have…
What I want is to be able to add items in the iOS app even if the Watch app is Off, which is normal behavior, BUT I want the Watch app to update with whatever is in the tableView (in iOS) as soon as it is turned on and even if the iPhone is not On at the time the Watch is turned on.
In other words, I want the data in the iOS app to always be in sync with the Watch app.
Which is the best function call to use in this case, the updateApplicationContext(_:) method or the sendMessage(_:replyHandler:errorHandler:) method?
Thanks

As for me, I would use updateApplicationContext(_:) since you would want to update it in real time or in the background as it gets connected.
as for this sendMessage(_:replyHandler:errorHandler:) The cons is The isReachable property must currently be true for these methods to succeed. so you might get a slight delay to update your UI until it is reachable and ask for updates.

Related

WatchOS - complication update from iOS

Is there a way how to update watch complication from iOS app? I've found some solutions but nothing works for me. I need to change the text in the complication to the text inside iOS app whenever I touch my button inside the iOS app. Any solution?
Use the Watch Connectivity framework to send the update to the watch by calling your WCSession object’s transferCurrentComplicationUserInfo: method. This method sends a high priority message to your WatchKit extension, waking it as needed to deliver the data. As soon as the watch receives the data, it calls your session delegate’s session:didReceiveUserInfo: method. In this method, update your complication data using the provided user info dictionary, and then call your data source’s reloadTimelineForComplication: or extendTimelineForComplication: method to update your timeline.
From here
More details in this 2016 WWDC session.
But pay attention that number of such pushes is limited to 50 in watchOS3.

Get Data to Complication: ExtensionDelegate not Called

(It looks like this issue has been encountered by others in previous weeks, but there haven't been any solutions that I've found.)
I'm trying to do a really basic thing: Get data from either my iOS app or my Watch app to my Complication Controller.
I am turning out to be way less capable of getting this done than I thought. watchOS 2 Transition Guide indicates that I should "[fetch] the needed data from the extension delegate" using the following code:
ExtensionDelegate* myDelegate = [[WKExtension sharedExtension] delegate];
NSDictionary* data = [myDelegate.myComplicationData objectForKey:ComplicationCurrentEntry];
Great. Except, I haven't been able to figure out how to get this to work on the extension side. Though even more importantly, I can't seem to even get the extension delegate code to run at all from a complication controller launch. When I run the complication, I get this message: "Extension received request to wake up for complication support." However, none of the code within any of the extension delegate's methods seems to run. I've also set breakpoints within every method and none of those breakpoints are hit.
It also looks like "transferCurrentComplicationUserInfo:" is also suggested to be used for complication updates, though it's unclear precisely how it's used. As much as I've gathered, it's used to wake up the watch extension so that ExtensionDelegate can store the new data for the next time the complication controller runs, but due to the previous issue I haven't been able to confirm.
I've got one maybe workaround (pinging the server from the complication controller and hoping that session variables persist so I can send relevant data), but there's every chance that if I can't get this worked out my complication work will be hosed. Any help here would be tremendous.
By the way, here's the code I have for "getCurrentTimelineEntryForComplication", if that's helpful at all.
- (void)getCurrentTimelineEntryForComplication:(CLKComplication *)complication withHandler:(void(^)(CLKComplicationTimelineEntry * __nullable))handler {
NSDate* entryDate = [NSDate date];
ExtensionDelegate* myDelegate = [[WKExtension sharedExtension] delegate];
NSString* data = [myDelegate.complicationData objectForKey:#"meow"];
NSLog(#"complication data: %#", data);
CLKComplicationTimelineEntry* entry = [self getTimelineEntry:#"2015-08-25 00:19:42" entryDate:entryDate complication:complication];
handler(entry);
}
I've been working with Complications in WatchOS2 since Xcode 7 Beta 4. I'm now on the latest, Xcode Beta 6. I've had a number of issues as in both Beta versions running on the Watch, running on the iPhone then installing to the Watch, and running on the simulator frequently give false negatives due to what appears to be buggy APIs and OS releases. I have been able to get data to show on complications in the following way.
Ensure that your primary Interface Controller implements the WCSessionDelegate protocol.
Implement both the didReceiveMessage and didReceiveApplicationContext methods in your Interface Controller.
In your iPhone app, attempt to send a message using the WCSession to the Watch.
If the message fails to send from the iPhone app, send the application context.
Back in the Interface Controller, when you receive a message -or- a context, update the values in your Extension Delegate.
Still in the Interface Controller and still after receiving a message -or- context, get a handle to the CLKComplicationServer and for each complication in activeComplications call reloadTimelineForComplication.
In your Complication Controller's getCurrentTimelineEntryForComplication grab the data you set in the Extension Delegate and set the values in your CLKComplicationTimelineEntry.
This will work usually when the App is already open on the Watch, the app is still resident in memory, but backgrounded on the Watch, or you start the app and their is context waiting which it consumes.
I have not been able to get the historical timeline entries to function (or the future ones). Nor, I have I been able to get the timeline to update independently of the Watch app.
If you are having trouble, here are some debugging things to try. As I stated above, the API and OS appears to be very buggy. The steps below do work (sometimes).
In the sim, use the Reset all Settings option on both the iPhone and Watch sim.
On the device, restart the Watch. If necessary, unpair and repair the Watch, although this takes a really long time to do.
On the iPhone, delete the app (which will also delete the Watch app if installed) and reinstall.
I hope that helps!
Justin
In order to make the ComplicationController respond to WCSession activity you must make the controller conform to WCSessionDelegate, then manage didReceiveUserInfo from within the ComplicationController. The ExtensionDelegate is not woken up for these updates when in the background. You can still update your delegate from the controller if necessary.
Also, as of right now, the simulator does not send transferCurrentComplicationUserInfo to the watch sim, you have to test on devices.

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.

Interrupt calls/SMSs on iPhone IOS 5

Can we interrupt calls/SMSs on iPhone IOS 5? any code samples?
I am looking for some code samples for an application that gets notified when a call is incoming/outgoing to/from the phone, and gets the caller number.
Same thing for SMSs.
I know this seems like spying, but the purpose of this at the end is way far of that.
I'll take this from a non-jailbroken position (because you do not specify it in your question).
Can we interrupt calls/SMSs on iPhone IOS 5?
No. Absolutely not. In doing so, you'd need 3 things:
A Listener For Incoming Calls/SMS's
An Event Called When A Call Or SMS is Incoming.
A Responder Able To Cut Off Said Call
The first is impossible without breaking out of the app sandbox, a clear no-no in iOS development. It also presents a major security risk for the operating system as a whole. If applications could listen to each other and react any way they wanted, it would create chaos! Users wouldn't have any privacy whatsoever. The second would require some kind of listener that was always present and capable of waking/starting your app to interrupt the call, which again, is a clear case of stepping out of the sandbox. In fact, the only way to launch your application to interrupt the call would be to send a URL, which in itself requires an application... Yikes! The third is just plain impractical. If you made even a tiny mistake in the way you determined whether or not to cut off the call or SMS, you could prevent potentially important messages from getting to innocent bystanders.
I know this seems like spying
Because it is! You need a listener in order to evoke some action from your application.
Of course, this isn't to say it's impossible, but it would require a jailbroken device.

Possible to hook into the phone calling functions with current iPhone SDK?

I've heard it mentioned elsewhere, one cannot programmatically hook into the phone call area of an iPhone using the current SDK. I'm looking to learn iPhone development and Obj C, with the end goal of creating a call timer app that runs in the background and alerts the user when a call has gone on too long.
Is it even possible to hook into methods liek that?
No. Your app will be interrupted when the user receives a call, and your code will not be allowed to run while the user is on the call. Additionally, there are no background apps allowed for the iphone. The best you can get is push notification, but you can't create a daemon or anything like that.
This information is provided in the iPhone Application Programming Guide
With version 4 you can now multitask to some degree.