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!
Related
I want to download the data from server before launch
I know there is a way to duplicate the launch view and load it till the success callback from service came
But i need to know whether there is another UIapplicationprotocol
method which can be called before didfinsishlaunch to achieve this.Can anybody guide me on this?
No. As discussed in this question, Apple requires that your application launch time be relatively short, or your app will be killed. So it's not a good idea to synchronously connect to the network before/during applicationDidFinishLaunching.
Instead, you can start an asynchronous task (see NSURLSession) and show a progress indicator/spinner while it is executing.
- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(nullable NSDictionary *)launchOptions
above method will be called before method 'didfinishLaunching' method.
As far as I know,there is no such an method. but you can try to use BackgroundFetch,it can let you download data even the app is not be launched.
You can use the willFinishLaunchingWithOptions method to solve it.
It was shown in https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplicationDelegate_Protocol/index.html?hl=ar
I am using Dropbox's SDK API V1 to upload files from my iOS app. The files aren't loading in real time, but rather I push them into a queue, and they get uploaded in the background.
I can't figure out for the life of me how to take DB RestClient delegate and make it respond to a completion/failure event that happens in the background. Is that even possible?
It seems (and I am new here), that delegates are meant to respond to live events on screen. Is that even an option to assign them to anything other than a UI element/view?
Update: Adding some description of what the code looks like.
There is a lot of code and it's hard for me to tell what's relevant for this question.
I am using PHPhotoLibrary.sharedPhotoLibrary().performChanges() which has a completion handler.
On success, I send an image upload request via dispatch_async(dispatch_get_main_queue()) method.
Dropbox API has this method dropboxRestClient.uploadFile(filename, toPath: pathOnDropbox, withParentRev: nil, fromPath: localFileUrl)
In all the examples that I've seen, dropboxRestClient.delegate was assigned to a UIViewController of some sort, and never to anything else.
So I am not sure how to assign it correctly, so that it recognizes events that happen in this queue.
Encountered a very weird problem, using simple AFNetworking downloading operation, even tried with simple NSURLConnection operation, connection fails if you keep your app running, and lock screen and then unlock. Works absolutely fine in background though.
Any one encountered similar problem with NSURLConnection want to share some solution?
Thanks.
It looks like an iOS bug. Weird, but lock screen action affects NSURLSession somehow, so that it stops working and returns NSURLErrorNetworkConnectionLost. So in my app I gave up using shared session. I either use a new session object for every request or (if I need to maintain one session constantly) recreate it every time the screen gets unlocked. And it works. For users of AFNetworking or any other third party library working on top of NSURLSession the situation is harder, of course. You'll need to correct the code of the library, which is definitely not a good thing, but I think there's no other choice
Very helpful Andrey Chernukha,
In my case, figured out that you don't necessary need to recreate new session every time.
I ended up using array to save running NSURLSessionDataTasks and after phone is unlocked resume them.
Steps:
I created array NSMutableArray *dataTasksToResume
In - (void)applicationWillResignActive:(UIApplication *)application I saved all tasks to dataTasksToResume array
Cancel all running NSURLSessionDataTasks
In - (void)applicationDidBecomeActive:(UIApplication *)application get all tasks from array and resuming them (re-creating them)
Enjoy!
Hope it helps.
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.
I'm creating a jailbreak tweak that includes calling from the lockscreen. I am currently using [[%c(SKTelephonyController) sharedInstance] dialNumber:number] to call a number.
Everything is working fine and the call goes through until you try to make a call when there is an open application. For example, if you leave an application open and lock the phone without closing the application, SpringBoard will crash when you try making the call. If there is no open application, the call works fine and there is no crash.
Is there a way to suspend the application programmatically?
I've already looked into [[%c(UIApplication) sharedApplication] _killThermallyActiveApplication];, but the selector is unrecognized, although it is found in the private headers. I've also tried [application disableContextHostingForRequester:#"LaunchSuspend"], which also isn't working.
I'm trying to deactivate the application before making the phone call, but after 2 days of searching through headers, I am unable to do so.
Any help is appreciated.
Finally figured it out! I'll put the code below for those who need it.
[[%c(UIApplication) sharedApplication] quitTopApplication:nil];