Open communication session with iOS app from Pebble watchapp - ios

I recently made an app for Apple Watch that I want to port to Pebble. The app is simple, when opened on the Watch it requests the info to the iPhone app, that asks for location, gets the nearest POI and returns the info to the Watch; all of this is done via - (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void(^)(NSDictionary *replyInfo))reply AppDelegate's method.
Is it possible to get this behavior on a Peeble app? I'm reading the docs and it says:
The session can only be opened from the phone app. This means that the iOS app has to start "talking" to the watch first in order to open the communications channel; the other way around is not possible.
Pebble iOS docs
So, if I understood correctly, the Pebble watchapp cannot request anything to the iPhone app, is the iPhone app the one which has to send the info to the Pebble watchapp. Is this correct?
Thank you so much.

Yes, that is correct for PebbleKit iOS.
On the other hand you can use PebbleKit JS, and build an app that utilizes AppMessage, and can get your location, talk to your POI api, etc.

Related

Trigger apple watch application launch from iPhone [duplicate]

I would like to give a hint to the user, that my iOS app supports the Apple Watch.
So I would like to link/open the Apple Watch companion app from within my iOS app, very much similar to opening the Settings App using ([[UIApplication sharedApplication] openURL: [NSURL URLWithString:UIApplicationOpenSettingsURLString]];)
This shall enable the user to directly navigate to the Watch companion app to setup my app for the watch.
I could not find any URL which would open the companion app in general or specific to a section of the companion app.
If direct linking is not supported, I am also interested in alternative approaches for this use case.
Thanks in advance!
EDIT:
I checked the WatchKitSettings Info.plist file in the simulator to see if it registers any URL schema, but it does not.
I guess it's not possible to programmatically launch the watch companion app from iOS. The opposite way would be possible: to launch the iOS app in the background upon receiving a message from the watch. See WWDC talk Introducing Watch Connectivity.
You could check WCSession.defaultSession().watchAppInstalled and ask the user to launch the app if it is true.
Previously, it was not possible to launch the WatchKit App from the iPhone app, but the iPhone app could be launched—only in the background—with the openParentApplication method.
As of WatchOS 2, however, it is now not possible for either app to cause the other to launch. Instead, there are new methods for queueing changes to be picked up when the other app is launched in the future.
One partial solution for your use case could be displaying a local notification which could be tapped to open the watch app. The primary flaw in such an approach is I do not believe there is a way to limit this notification to the Watch only, so it would also appear on the iPhone where if tapped it would bring the iPhone app to the foreground. Messy if implemented like this, and therefore not worth it I'd have thought, even if it could pass app store review.

iOS background fetch keeps launching the app

I'm working on an iOS application which had Background Fetch enabled via the Info.plist for around a year. There were multiple versions released with background fetch enabled, but then a few weeks ago the feature that necessitated background fetch was removed. The UIBackgroundModes key was removed completely from the Info.plist, and the app was released to the App Store.
Surprisingly though, telemetry indicated that the application was still being launched in the background periodically! This is a snippet from the actual app delegate source code:
- (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
// NB: this callback should NEVER happen! But if it happens, we want to know about it.
... send telemetry log here ...
completionHandler(UIBackgroundFetchResultNoData);
}
Has anybody experienced anything similar? According to the documentation, it should be impossible for the app to be launched if the UIBackgroundModes dictionary don't contain the right values. In this case, there's no background mode turned on at all, yet the app is periodically launched in the background to perform the fetch...
Telemetry data indicates that it happens on iOS 11 only, but that might be a coincidence because only a small fraction of the installed base is on iOS 9/10.
BTW a source level assistance request was sent to Apple with this issue, but they haven't replied yet; but maybe developers of other apps have encountered this issue before.

iOS: Handling interactive notifications when app is not running in background

I am trying to implement interactive local notifications for my app, and in particular via implementing this method:
- (void) application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification withResponseInfo:(NSDictionary *)responseInfo completionHandler:(void (^)())completionHandler
The method works fine except if the user kills the app and then receives an interactive local notification. In that case there is no indication that the local notification action (button click) was received.
I am looking for help/advice on 2 fronts
(1) Is anyone able to confirm/deny that handleActionWithIdentifier is not called when the app is not running at all (i.e. not even in background mode). I went through the relevant programming guide and I noticed that much of the language talked about foreground and background mode without addressing the third possibility. However, I'm looking for something more solid than 'it doesn't work for me' to put this to rest. Is there anything in the docs that says these should or should not work after the app is killed?
(2) How can I log in the Xcode console after I have killed my app? Every time I try this, I notice that when I relaunch the app I no longer have logging. This is important because I need to prove one way or another whether I receive interactive notification messages from user clicks after the user has killed the app.
I would appreciate any and all advice on this matter. Thank you.
If the app is terminated then when it gets launched via the notification then didFinishLaunchingWithOptions gets called with a key of UIApplicationLaunchOptionsLocalNotificationKey. The value of this key is an NSDictionary containing the payload of the local notification
You can't log in the Xcode console from the app if the app isn't running of course. But if you run the app not via Xcode you can watch the output by going to Window|Devices then selecting your attached device.
If you are relaunching the app via Xcode and logging isn't there this is probably a bug in Xcode, I've noticed recent versions of Xcode is having problems displaying logging. If this happens try the Devices output.

How to programmatically open Apple Watch companion app from iOS app

I would like to give a hint to the user, that my iOS app supports the Apple Watch.
So I would like to link/open the Apple Watch companion app from within my iOS app, very much similar to opening the Settings App using ([[UIApplication sharedApplication] openURL: [NSURL URLWithString:UIApplicationOpenSettingsURLString]];)
This shall enable the user to directly navigate to the Watch companion app to setup my app for the watch.
I could not find any URL which would open the companion app in general or specific to a section of the companion app.
If direct linking is not supported, I am also interested in alternative approaches for this use case.
Thanks in advance!
EDIT:
I checked the WatchKitSettings Info.plist file in the simulator to see if it registers any URL schema, but it does not.
I guess it's not possible to programmatically launch the watch companion app from iOS. The opposite way would be possible: to launch the iOS app in the background upon receiving a message from the watch. See WWDC talk Introducing Watch Connectivity.
You could check WCSession.defaultSession().watchAppInstalled and ask the user to launch the app if it is true.
Previously, it was not possible to launch the WatchKit App from the iPhone app, but the iPhone app could be launched—only in the background—with the openParentApplication method.
As of WatchOS 2, however, it is now not possible for either app to cause the other to launch. Instead, there are new methods for queueing changes to be picked up when the other app is launched in the future.
One partial solution for your use case could be displaying a local notification which could be tapped to open the watch app. The primary flaw in such an approach is I do not believe there is a way to limit this notification to the Watch only, so it would also appear on the iPhone where if tapped it would bring the iPhone app to the foreground. Messy if implemented like this, and therefore not worth it I'd have thought, even if it could pass app store review.

Using Core Location in Apple WatchKit

I'm currently developing an apple watch extension. Anybody knows if the current location is provided by iPhone or Watch itself?
I can't find any information about this and i need to draw a compass pointing where the watch is pointing.
In order to do what you want you don't need CoreLocation you just need a magnetometer.
AFAIK the Apple Watch doesn't have one built in.
The sensors it has are...
Accelerometer
Gyroscope
Heart rate sensor
Barometer
No magnetometer though.
According to Apple's Dev Documentation:
The best solution for performing any long-running tasks is to let your iOS app perform the task instead. For example, instead of starting location services in your WatchKit extension, start it in your iOS app. Your iOS app can gather the needed data and put it in a shared app group so that your extension can access it later. Use the openParentApplication:reply: method to initiate tasks and receive a reply or use a shared group container to communicate details between your iOS app and WatchKit extension. For information about how to handle communication between your iOS app and WatchKit extension, see Communicating Directly with Your Containing iOS App.
P.S. I am working on similar app.
You can't use CoreLocation from the watchkit extension. You can however use an api to open the parent app (in the background) and ask your parent api for the information. The api is really nice because you can use it with a reply so that you can easily get the information back:
+ (BOOL)openParentApplication:(NSDictionary *)userInfo reply:(void(^)(NSDictionary *replyInfo, NSError *error)) reply; // launches containing iOS application on the phone

Resources