Here is what I have tried that has NOT worked:
Using openURL to attempt to open the containing app
Here is what I have thought of that wouldn't work:
Using local notifications to provide a link to the containing app (creating the local notification from the extension)
Here are options I am considering:
Using a UIDocumentInteractionController and a custom file extension type to provide a link to my containing app (and my containing app only)
Starting a "fake" NSURL session to get the following functionality: In iOS, if your extension isn’t running when a background task completes, the system launches your containing app in the background and calls the application:handleEventsForBackgroundURLSession:completionHandler: app delegate method.
The UIDocumentInteractionController is confirmed to work in Xcode 6.5, but the flow is kind of wonky. The NSURL thing should work as well, but it's also a bit fishy. Does anyone have any other ideas of getting my containing app to open from a share extension, or an idea to communicate with it from a share extension?
I have confirmed that the NSURLSession way (second bullet under the "considering" options above) indeed does work. I'm still working out some kinks, but here are the basics. Using this method, you can indeed open your app from a share extension.
This method requires 3 main steps, as follows:
Make a background NSURLSession in a Share Extension.
Start a download task.
Call exit(0).
Make sure the thing you are downloading takes long enough so that the extension terminates before the download task finishes.
NSString *address = #"https://googledrive.com/host/0B5zObXR9UzgmbFpob2J5eXpjNXc/file3m";
self.mySession = [self configureMySession];
NSURL *url = [NSURL URLWithString:address];
NSURLSessionTask *myTask = [self.mySession downloadTaskWithURL:url];
[myTask resume];
exit(0);
Then, in your containing application's UIApplicationDelegate class, implement the
application:handleEventsForBackgroundURLSession:completionHandler:
method. This method gets called when the download task finishes after your extension has been terminated. Then, in this method, you can call
[[UIApplication sharedApplication] openURL:url];
or do some other stuff in your containing app.
The main problem with this method is that there is a delay between the time when the extension terminates and the time when the the containing app starts up. The main advantage of this method over the UIDocumentInteractionController method is that no extra user interaction is needed. More details will come as I continue to experiment.
Related
I have an extension and a container app.I open the container app with the method
[[self extensionContext] openURL:[NSURL URLWithString:#"customURLScheme://"] completionHandler:nil];
from extension via custom URL scheme but I don't know how to run some code in the container app as soon as it launches...??
In another words I'm trying to use the URL scheme just to open the app and then call some method from container app.
In your containing app's AppDelegate, you need to implement the method application:open:options: and do whatever is required in there.
The containing app gets the full URL that was used to open it, so you can use the URL to encode different operations to perform.
I would like to make an app, that opens and present itself to a user when a certain block of code is executed from inside that app. Is it possible like that?
Another solution would be to display a local alert notification, that would open the app on tap. But is it possible to do that without the notification?
Nope,You can't directly open the another app.
If you want to open another app using you app for that need to implement URL Schemes.
Here is basic example for open google map in Objective-C
-(IBAction) openMaps:(id)sender {
// Opens a map containing Envato's Headquarters
UIApplication *ourApplication = [UIApplication sharedApplication];
NSString *ourPath = #"http://maps.google.com/maps?ll=-37.812022,144.969277";
NSURL *ourURL = [NSURL URLWithString:ourPath];
[ourApplication openURL:ourURL];
}
And Here is best tutorial for create custom URL Schemes in Objective-C.
No, with out user interaction you can't open your app.
There is only two way for opening app as follow
Using local notification
Using NSURL schema
you can't directly open your app.
I am currently developing an iOS app that takes the streamable url of a music file from dropbox and plays it on the device.
When the user clicks a song, it opens a view controller and there, i want to have the option to download the file. So i have an IBAction:
- (IBAction)availableOfflinePressed:(id)sender {
NSString *trackPath = sharedApp.trackTitle;
NSLog(#"Available offline pressed for %#", trackName);
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(#"Started downloading...");
[self.restClient loadFile:trackPath intoPath:trackPath];
});
}
Now, even though it throws the "started downloading..." in the app log, the file is actually never downloaded. I know that the dropbox sdk rest client does not execute functions when in the background, that's why i use the GCD on the main thread.
So, can you help me here? am i missing something?
thanks in advance for any help
turned out it was a pretty silly answer!
the restClient was nil and not correctly set within the specific view controller, so it could not fire the dropbox delegate.
Actually, what was needed is to init the restClient as you might already do in your AppDelegate or anything and then set self.restClient.delegate=self; in the viewDidLoad() function of the specific view controller.
thanks everyone for your responses!
happy coding!
Im trying to upload images from the Photo app through Action Extension. I use NSURLSession to upload it in background. Here is the code i use.
var configName = "com.myapp.uploadImage"
var config = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier(configName)
config.sharedContainerIdentifier = "group.myApp.sample"
var session = NSURLSession(configuration: config)
let task = session.dataTaskWithRequest(request)
task.resume()
self.extensionContext!.completeRequestReturningItems(self.extensionContext!.inputItems, completionHandler: nil)
It works fine.
The question is when i upload an image and dismiss the view once and then again try uploading a second image while the initial process is still running in the background, the initial NSURLSession isn't completed. Only the second process gets completed. In short, the second session overcomes the first session.
I tried using NSOperationQueue. But action extension once dismissed and opened again for the second session, it just creates a new NSOperationQueue and hence the problem still persists.
Any suggestion will be helpful. Thanks in advance.
Make sure you don't attempt to instantiate a second background session with the same identifier while the first is still running. Save your background session so you can use it later.
As the "Background Session Considerations" of the URL Loading System Programming Guide: Using NSURLSession says:
Note: You must create exactly one session per identifier (specified when you create the configuration object). The behavior of multiple sessions sharing the same identifier is undefined.
Note, this document also mentions that one "must" specify and implement the delegate. (If nothing else, how will you know about failure if you don't do that?) The example provided in the Performing Uploads and Downloads section of the App Extension Programming Guide specifies the delegate, too.
Also, has your main app's app delegate implemented the handleEventsForBackgroundURLSession method? You have to capture the completionHandler and call it when the NSURLSessionDelegate method URLSessionDidFinishEventsForBackgroundURLSession is called.
Finally, I notice that you're using data task. The NSURLSession documentation is specific that one should not be using data tasks with background sessions, only upload/download tasks. I always assumed that was just so you don't try to use didReceiveData delegate method, but I might try using upload task just in case there's some other issue associated with data tasks with background sessions.
I'm having difficulty in the download using NewsstandKit when the app shut down.
My newsstand app download does starts in Background Mode, and exit to the background or push a download notification, the download issue everything is OK, but i shut down the app then the task is downloading,the downloading task failed.
Does it has to do some thing with the Server? or others?
You need to resume your downloads when the App Launches again.
Something to the tune of this would work
// Inside App Delegate Did Finish Launching
NKLibrary *nkLib = [NKLibrary sharedLibrary];
for(NKAssetDownload *asset in [nkLib downloadingAssets]){
[asset downloadWithDelegate:newsstandDownloadDelegate];
}
If you read the documentation you will find the following paragraph detailing how you should handle app termination:
While assets are being downloaded, the application could be suspended
or even terminated entirely if, for instance, there is insufficient
memory or the user force-quits the application. The application
(assuming it has the newsstand-content property) is later relaunched
into the background to handle the completion of the download or any
authentication challenges or errors related to it. The procedure in
this case is the following:
When the application is launched, it can use the
UIApplicationLaunchOptionsNewsstandDownloadsKey key to access an array
in the launchOptions dictionary passed into the
application:didFinishLaunchingWithOptions:. If there is an array, it
contains the identifiers that caused the launch; these could be
identifiers for downloads that have finished downloading that or could
not complete downloading. It iterates through the array of
NKAssetDownload objects from the downloadingAssets property of the
NKLibrary object and calls downloadWithDelegate: on each of them. If
it wants, the application can use the asset identifiers obtained in
the previous step to check which asset downloads caused the relaunch.
The NSURLConnectionDownloadDelegate object handles the asset downloads
as it does normally. The Newsstand Kit framework expects all calls of
its methods to be made on the main thread; the NSURLConnectionDelegate
Protocol methods are also invoked on the main thread.