I am working on an iPhone app, which downloads Focus list of items on each app start (6 items with images).
I'm using 1 NSMutableURLRequest for downloading 6 items textual information in a loop, then in the same method block with different for loop I'm using :
NSURL * imageURL = [NSURL URLWithString: strUrl];
NSData * imageData = [NSData dataWithContentsOfURL:imageURL];
for getting images of all 6 items. Code is working fine, if I wait till this process completes and update my list on home view.
If I try to navigate then my app stuck till its in process of download. I called complete method on Background thread, but still it got stuck for the process completion.
How can I code for this, so user can experience all navigation without stuck and when he'll come back can get the 6 items in view ?
Thanks in advance.
You could use NSURLConnections asynchronous request to do the downloads in the background
+ (void)sendAsynchronousRequest:(NSURLRequest *)request queue:(NSOperationQueue *)queue completionHandler:(void (^)(NSURLResponse*, NSData*, NSError*))handler`
That way the download won't block your code. You can also do the completion work on background thread (as long as its not working with the UI, that code ALWAYS needs to be on the main thread).
Related
We are implementing Sirikit for one of our application. We are able to send message using SiriKit intent INSendMessageIntent. Upon “Send” Siri command handling, we need to pass some of the information to other application.
We have figured out [self.extensionContext openURL] to open application from intentViewController. As we observed that, there is configureWithInteraction of IntentViewController which gets called every time Siri processes each user command. Since we need to open application only on “Send” Siri command, we are not able to identify current processing state i.e. “Send”.
OR is there anyway to call openURL from intentHandler?
We are completing IntentResponse as mentioned below.
NSUserActivity *userActivity = [[NSUserActivity alloc] initWithActivityType:#“com.xxxxxx.xxx.myapp”];
INSendMessageIntentResponse *response = [[INSendMessageIntentResponse alloc] initWithCode:INSendMessageIntentResponseCodeSuccess userActivity:userActivity];
NSLog(#"response is %#",response);
completion(response);
We are expecting following function from containing app’s delegate to be called when action gets completed (i.e.INSendMessageIntentResponse is passed to completion handler)
-(BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler
Several years passed ... but anyway, maybe it will help someone.
You can pass parameters with user activity you created.
[userActivity addUserInfoEntries: ]
I was using ShareKit for a p long time, without downloading last updates from its repository.
Now i need some of its new features, so i've pulled all last commits and tried to run my app with new ShareKit without making any changes to my code (except some small changes in includes).
App compiles without errors but when i try to execute usual Facebook sharing code - it crashes without any useful error description.
old code i want to get to work
NSURL *url = [NSURL URLWithString:[NSString stringWithUTF8String:sk::game_services::get_app_store_url()]];
SHKItem *item = [SHKItem URL:url title:[NSString stringWithUTF8String:message] contentType:SHKURLContentTypeWebpage];
[SHKFacebook shareItem:item];
and according to updated ShareKit demo app and its documentation - this code should still work.
but it doesn't
it horribly crashes in currentIndicator method of SHKActivityIndicator inside macro DEFINE_SHARED_INSTANCE_USING_BLOCK that contains dispatch_once call.
debugger just says "SIGABRT" and thats all.
i don't know what to do.
I am using the following code to populate a webView in my Mac app...
NSURL *url = [NSURL URLWithString:#"https://joeworkman.net"];
[self setMainFrameURL:[url absoluteString]];
I would like to be able to capture when there are errors loading this URL and then instead load a local HTML file stored within my app. This way the users gets presented with a presentable error instead of an ugly 500 server error (if that was the case). Not to mention that most users would not know what that meant anyhow.
I'm loading a rather simple XML file from a URL. I wanted to show the network activity indicator while the parser is loading the file, but obviously not while it is parsing.
Question: Does the initWithContentsOfUrl: method lock program execution while the document is loaded from the url? In other words, is the code below correct?
It seems obvious to me that this is okay, but I wanted to make 100% sure.
NSString* const urlString = #"...";
NSURL* url = [NSURL URLWithString:urlString];
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
NSXMLParser* parser = [[NSXMLParser alloc] initWithContentsOfURL:url];
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
This article explains it pretty well http://akosma.com/2010/05/28/initwithcontentsofurl-methods-considered-harmful/:
The main problem with these methods, of course, is the fact that they
are synchronous; this means that the thread executing them (usually
the UI thread) will block completely until they return, and in most
applications this means that you are de-facto blocking the whole
application for an unknown amount of time. This means that no buttons
or UI widgets will react to input, no navigation will be possible, no
touch events will be delivered or executed, nothing will happen at all
until the network operation completes.
Even worse; when using initWithContentsOfURL:, there is no timeout,
there is no meaningful feedback for network failures, and no way for
the user to cancel the current network operation. This last factor
justifies by itself not using initWithContentsOfURL: at all; you must
never ship code that leads to a bad user experience. Your users will
resent this and will complain!
If you want to display download progress, you will need to download the file yourself using something like NSURLConnection, then pass the local file path to the XML parser.
Yes, it does block. So your activity indocator won't be displayed.
I am making an iPad app where you can download files (like PDF, doc, etc) and view them offline.
I already have the view part and you can download a file to the document directory.
As it is now you need to wait for the download to be finished to move on.
This can be solved by putting it in a thread, but what happens when the user downloads multiple files or even download the same file multiple times?
My idea is to make a download queue, with a view for the progress.
Workflow:
The user opens a document and press download, the user gets a message that the download is started and can be viewed in the offline documents view.
The user downloads 3 more documents.
When the user goes to the offline document view the user sees a table view with 4 filled cells. 2 documents are done loading and 2 other are still downloading because there is a download/status bar shown in the table view cell.
The downloaded documents can be viewed or deleted.
The downloads in progress can not be watched (yet) but can be cancelled.
I want to make a threaded download class where you can add urls to be downloaded. the class has methods to cancel and delete document-downloads, but also has methods to return the progress.
If possible the class can handle simultaneous downloads.
The problem is, I don't know where to start?
NSURLConnection is already asynchronous. All you need to do is to create NSURLConnection instances, associate them with your data structures, and have at it.
Here's an example where I assume you have one UIView per item. If you use a table view you can't count on view instances, but instead associate a download with an NSIndexPath, or something else.
#implementation MyDownloadView
- (void)startDownload {
NSMutableURLRequest *req = [[NSMutableURLRequest alloc] initWithURL:myURL cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10];
[req setHTTPMethod:#"GET"];
// Set headers etc. if you need
[[[NSURLConnection alloc] initWithRequest:req delegate:self] autorelease];
[req release];
self.responseData = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
// Alternatively, store to a file so you don't run out of memory
[self.responseData appendData:data];
}
#end
Then implement the other NSURLConnection delegate methods to do what you need.
I've written an open source example that has pretty much all features you want, canceling a download is currently only available in code, but it's pretty easy to add a button for that.
I'm using asi-http-request for managing the downloads, and they are displayed in a grid view (AQGridView) instead of a UITableView, but i think you get the idea.
Download progress is managed via KVO.
See PSPDFDownload.m for a start. Download the full demo here
Full disclosure: This demo uses PSPDFKit for faster pdf display. But the Kiosk example is exactly what you need, and you don't need to use PSPDFKit for pdf display. There's even an example code path that uses Apple's QuickLook.