iOS Extension - Detect "extension state changes" (Background/Foreground) - ios

I have a share extension implemented for iOS8. The service uses OAuth to authenticate. The login info I use for the extension is shared with the container app.
The problem is:
When I am in the extension, then app switch to the container app and logout, and then app switch back to the host app containing the extension - How do I detect that the extension has just re-appeared? The extension is relying on certain information to be present in the shared DB between the container app and the extension, however, that data is removed when the app logs out.
I have tried registering for various "app notifications" such as UIApplicationDidBecomeActiveNotification. However, as expected, these aren't called for extensions.
How can I detect when the state of the extension changes such that I can make my extension more robust when it reappears?

The viewDidAppear:animated: method of your main view controller class should be called every time you reenter your extension. When you are about to leave, viewWillDisappear:animated: should be called.

See
NSExtensionContext.h
iOS 8.2 added a number of notifications to use for extensions:
NSExtensionHostDidBecomeActiveNotification
NSExtensionHostDidEnterBackgroundNotification
NSExtensionHostWillEnterForegroundNotification
NSExtensionHostWillResignActiveNotification

Related

How to enable Ios Callkit Call Directory extension

I am trying to add the Callkit Call Directory extension to my React Native app so that I can add additional numbers that will show with caller id (populated from my app).
The Callkit documentation states:
"Before a Call Directory extension can operate on incoming calls, the user must explicitly enable the extension in the iOS Settings app."
However, there is no section for "Call blocking and identification" in my phone's settings (see here for similar issue: https://discussions.apple.com/thread/251896172)
I have tried using the openSettingsWithCompletionHandler method, which does open the settings on the phone, but still no option for "Call blocking and identification".
How can I let my app use this functionality if it cannot be seen in the phone settings? Am I doing something completely backward?
Thanks.

Call WKInterfaceController's method from UIViewController

I have an iPhone app and added a WatchExtension. Now I managed to send a string to the Watch using the MMWormhole. In order to use the string I must call update() inside the WKInterfaceController from a method inside my UIViewController, so the iPhone application.
Is that possible?
I tried to do something like InterfaceController.update() but Xcode complained that it does not know the variable InterfaceController.
Thanks in advance :)
The iPhone App and Watch Extension are TWO seperate process, although they are stored in ONE bundle, so you can not call the method of other process in runtime.
In WatchKit:
If you want to share code, use Framework.
If you want to share data, use App Group.
If you want to use notification, use Inter-Process Communication(In iOS, It's Darwin Notification, and MMWormhole use this feature).
I think you want to let the Watch update its interface when iPhone app do something, you can do like this:
send a message to Watch Extension.
Watch Extension receive that message.
In the message handler, update interface.
In my option, the iPhone App and Watch Extension can be seen as a kind of C/S architecture, iPhone App is Server and Watch Extension is Client, maybe this metaphor is easier to understand.

WatchKit: direct communication with the containing iOS app

I just get started with WatchKit and I'm trying to do this (if I'm not wrong, it is possible to do): I'd like the WatchKit Extension to ask the containing app for requesting some data to a web service, and then return the service response to the Extension to update the WatchKit App interface accordingly.
As I read in Apple Watch Programming Guide, yo can call the openParentApplication:reply: method in the WatchKit Extension to request something to its containing app, and then the application:handleWatchKitExtensionRequest:reply: method in the AppDelegate of the containing app should be called. Once this method called, I need to perform the service request, wait for its response, and then send it back to the Extension.
However, when I run the WatchKit App scheme in the simulator, the openParentApplication:reply: method is called, but a breakpoint within the application:handleWatchKitExtensionRequest:reply: is not reached. So I'm not even able to test if I can correctly perform the web service request and get its response back.
What could I be missing? Should I configure somehow the schema to reach breakpoints in the containing app as well? Is it needed to declare some kind of background feature for this?
Thanks in advance
I just answered a very similar question here which will allow you to open the iOS app from the Watch Extension and getting a reply back.
In order to debug the iOS app while running the Watch Extension, you should follow the steps explained here.

Ios 8: Determine the destination app when my app goes to the background?

I override my app's openURL-method to know when we're about to leave the app from an ABPersonViewController, the reason being that that class doesn't notify its delegate on all of the actions it presents to the user. If it did everything would be fine.
This worked flawlessly in iOS 7, but when trying this in iOS 8.1 it turns out that the ABPersonViewController doesn't call openURL for all its actions anymore. For instance, tapping a phone number gets me to the phone app without calling openURL. Tapping the SMS bubble on the other hand will call openURL.
When tapping the facebook profile entry (with the URL "fb://profile/1234567890") the log says that "Launch Services" doesn't have a registered handler for the scheme "fb". So I'm assuming that calls to Launch Services have replaced the calls to openURL. I can't find out much more about it other than that it's "a private API".
Is there a way to detect these calls? Or, is it possible to override handlers for known schemes like "tel" and "mailto" internally for my app? I basically just need to know when we're leaving the app and where we're going.

How to detect an app extension is enabled in containing app on iOS 8?

I am developing a custom keyboard on iOS 8 beta, and I want to tell the user that how to enabled it in containing app if my custom keyboard is not enabled, is there any way to detect an app extension is enabled ?
first of all let's set some constants to make it easy to understand each other:
containing app = the app that installs the extension and holds the extension binary and target
host app = the app that the extension is running inside (other party)
extension = any of iOS8's new components/modules that we can now build into system-wide use: custom keyboards, today widgets, photo editing effects, and more..
Apple also released a more quiet API called App Groups API
This API allows a developer to group n extensions under 1 bundle identifier, and creates a communication wire between the app and the extensions contained in it.
you can share data between the extensions and the containing app using NUserDefaults, but with this new method:
[[NSUserDefaults alloc] initWithSuiteName:#"<app group identifier>"];
read/write... and sync:
[myDefaultsObj synchronize];
and now to the bottom line:
use the app group's url schemes to test what you want:
https://developer.apple.com/library/prerelease/ios/documentation/Foundation/Reference/NSExtensionContext_Class/#//apple_ref/occ/instm/NSExtensionContext/openURL:completionHandler:
- (void)openURL:(NSURL *)URL completionHandler:(void (^)(BOOL success))completionHandler
URL - The URL to open.
completionHandler - A block that is called when the URL has opened.
this parameter - success - is a Boolean value that indicates whether the open was successful.
Good luck!!!

Resources