iOS app communication needs improvement

Originator:bigzaphod
Number:rdar://10492549 Date Originated:November 28, 2011
Status:Open Resolved:
Product:iOS SDK Product Version:
Classification:Enhancement Reproducible:
 
We really need a better way to share information between iOS applications. URL schemes almost do the job, but the transition is jarring and the process is ugly since you get booted out of your own app entirely and it severely breaks the flow.

I think a solution that builds upon what's already available would be to allow apps to open a URL and include a property list and a completion handler block. If the OS has an app that can respond to the given URL, it either switches to the app in the current manner using URL schemes and passing in the property list by way of the already-existing -application:openURL:sourceApplication:annotation: method, or if it supports this "new" way, the system will present a UIViewController provided by the third party app in a new window over top of the calling app somewhat similar to how form sheet modal view controllers are visually presented or maybe how iAds are presented with the little (X) close button so the user can always dismiss it regardless of what the third party app may present.

I imagine something like this added to UIApplication:

- (BOOL)openURL:(NSURL *)aURL withAnnotations:(id)plist completionHandler:(void (^)(BOOL success, id results))handler;

If the URL given isn't a supported scheme or the app that supports it doesn't implement this new method, the handler would get called with success set to NO and results set to nil but the app (if any) would open as it does now and life would go on as usual. If the scheme app does support this new approach, then after it's controller gets dismissed, the handler would be called in the originating app with a resulting plist object that the third party app optionally supplies allowing for rudimentary two-way communication.

So in UIApplicationDelegate, you'd probably have to have something like this:

- (UIViewController *)application:(UIApplication *)app interactionViewControllerForURL:(NSURL *)aURL sourceApplication:(NSString *)sourceApplication annotation:(id)annotation;

Returning nil from that method would be like returning NO from the other URL handling methods. The returned view controller is then presented by the OS in a new UIWindow created specifically for this purpose. The window and such would be constructed in the address space of this app - not the app that initiated the open request. The overlaying would be handled by the system. The app would not be activated and should not get the usual will become active, did enter foreground stuff and would be subject to similar rules as when an app is in the background doing task completion.

If the app finishes it's task and wants to return control back to the source application, it could call a method something like this on UIApplication and pass in a property list of optional results:

- (void)endApplicationInteraction:(id)results;

While the interaction controller is being displayed over top of the source app, the source app would also become inactive as if the screen was locked and be sent the usual inactive messages.

Additionally, if the user were to push the home button, I'd propose that it might be simplest to just cancel the interaction. That might not be ideal, however. The next-better might be to keep the interaction alive up until low memory kicks one of the apps or if the user switches into the third party app that was being presented in the window. In that case, the interaction would be canceled and no results transferred. So there'd be only one app interaction allowed by a 3rd party app at a time and activating an app via multitasking or whatever would cancel any interaction that might have been pending. That might prevent confusion. Or it might not even be necessary. I don't know.

Hopefully this makes some sense. It's not exactly trivial, but I think something along these lines would go a LONG ways toward improving inter-app communication flow in a way that maintains the clear separation between them and doesn't allow one app to intrude on the other's address space. It would also, I think, add some much-needed consistency in this regard. Supporting services like Instapaper would be a lot simpler and less intrusive if you could easily send a URL to the Instapaper app itself and let it handle things without having to implement your own networking code, getting API keys, etc. and without kicking the user entirely out of your app for such a simple and quick interaction.

Comments


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!