Progress bar not showing accurate progress - iphone

In my app i am getting data from server and saving in SQLite table. i have to show the progress bar for this entire process. I wrote [myRequest setDownloadProgressDelegate:progressView]; but it is working up to downloading the data from server only,it is not showing the progress for saving data in to the SQLite table. please help me. Thank you
Here is some code i wrote before calling the url,in the request finishing method i am saving the entire data in to SQLite.
if (!myQueue)
{
myQueue = [[ASINetworkQueue alloc] init];
}
[myQueue reset];
[myQueue setDownloadProgressDelegate:progressView];
[myQueue setShowAccurateProgress:YES];
[myQueue setDelegate:self];

ASINetworkQueue will only update the progressView up to downloading the data from server, Because ASI classes are for making connection with server , downloading source , make a queue of requests etc.
After the class had informed you that data is fully downloaded ASINetworkQueue's work is finished and after that it is your application's responsibility to show the progress of saving the data in db

Related

Application freezing while fetching large data from core data base

I am using Core data, and trying to get large amount of data at a time using code
NSArray *result = [context executeFetchRequest:request error:&error];
But my main thread is freezing. How can I fetch my data on background thread ?
[In apple documentation its given on link in column "Fetch in the Background for UI Responsiveness"][1]
But There is no sample code to implement it. Please help me out.
[self performSelectorInBackground:#selector(yourMethodName) withObject:nil];
if you dont need to pass any parameters to that method.. leave nil at the end
in that method wich you are calling handle your fetching

FMDatabase and NSOperation

I am using FMDatabase for sqlite based iphone application. The problem is that application is fetching bulk data from a web service and inserting into a local sqlite database which is blocking UI [main thread]. Also we cannot run sqlite related commands in background thread. Can we use NSOperation here ? Any example ??
You should be able to run your SQLite operations in the background, as long as you only run them inside that thread and not from the main or any other.
You could use a NSOperationQueue to handle this, setting the max number of concurrent operations to 1 to make sure only one writes to your SQLite at a time and then calling NSInvocationOperations to save your data.
NSInvocationOperation * invocation = [[NSInvocationOperation alloc] initWithTarget:self selector:#selector(writeThisToDB) object:thisObject];
[operationQueue addOperation:invocation];

how to show loading image indicator inside uitable?

i'm new using Trhee20 in Xcode and i'm building an APP that needs to send a post request to a page to register a new user using the following code:
TTURLRequest *request = [TTURLRequest requestWithURL:page delegate:self];
request.httpMethod = #"POST";
request.cachePolicy = TTURLRequestCachePolicyNoCache;
request.response = [[[TTURLJSONResponse alloc] init] autorelease];
[request.parameters addObject:nombre forKey:#"username"];
[request.parameters addObject:email forKey:#"email"];
[request.parameters addObject:pass1 forKey:#"pass"];
[request.parameters addObject:pass2 forKey:#"cpass"];
I know that i need to use:[request sendSynchronously];to send the data but i don't know how to save the data that i'll retrieve from the server into a variable because this method only gives me a true or false.
The second thing i would like to know is how to set an image loading activity indicator into a uitable to block this while the request is being send to the server and quit that image once it has finished.
Thanks a lot for your help.
Answer #1: You set up a TTURLRequestDelegate and define the methods of what you want to happen for each callback.
Answer #2: This isn't Three20 specific, you should just be able to add the loading image when you make the request, and then remove it once you get one of the above mentioned delegate methods called.
On a side note: make sure that if you're actually doing something synchronously that you do not do it on the UI thread as it will make your app hang.

Making multiple service calls on iPhone app initialization

I need to make multiple asynchronous service calls in the application:didFinishLaunchingWithOptions: method from my application delegate in order to retrieve some data from a service to be used across various controllers in my app. I have control over the service, and I've designed the API to be as RESTful as possible, so I need to make multiple calls during app initialization.
What I want to do is to show a loading view with a progress indicator - similar to the default splash screen from Default.png - and remove that view once the service calls have completed and I have the initial values I need. This is pretty easy to do if there's only one service call, since I can simply hook that logic into the connectionDidFinishLoading: delegate method of NSURLConnection by hiding the loading view and displaying the root controller.
However, with multiple service calls, it becomes tricky. I can "chain" everything together and fire off one request, wait for it to finish/fail, then fire off the second request, and so on until I get to the last request. In the last request, I then hide the loading view and display the normal view. However, this can get unwieldy with multiple service calls, and the code becomes hard to understand and follow.
Any suggestions on the best approach for this?
I'm thinking one solution is to have a singleton class responsible for making service calls and app initialization. The singleton object will fire off all necessary requests in parallel on start, and each fail/finish callback will check if every request has finished. If all requests have finished, then it can call some method in the application delegate and tell it to hide the loading view, show the root controller, etc.
Thoughts?
Another possibility is to have each service completion callback notify (NSNotification) the controller of the progress indicator that progress has been made. You could also tell the controller of the progress indicator of how many request you were planning to make, and let it keep score, and itself do a callback when it thinks everything is done.
I am doing something similar with an NSOperationQueue that is configured to just run 1 operation at a time. See for example WeaveEngine.m and it's synchronizewithServer:credentials: method. I queue up all the separate operations, which are mostly async network calls.
you could use NSThreading and make synchronous calls in separate threads for each thing you need to get like
[NSThread detachNewThreadSelector:#selector(getDataRequest1:) toTarget:self withObject:urlRequest];
[NSThread detachNewThreadSelector:#selector(getDataRequest2:) toTarget:self withObject:urlRequest];
[NSThread detachNewThreadSelector:#selector(getDataRequest3:) toTarget:self withObject:urlRequest];
then in the selector for each thread do something like
- (void) getDataRequest1:(NSURLRequest*)urlRequest {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSHTTPURLResponse *urlResponse;
NSError *error;
NSData *responseData = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&urlResponse error:&error];
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
if ([urlResponse statusCode] < 200 || [urlResponse statusCode] > 299) {
//request probably failed
}else{
[self performSelectorOnMainThread:#selector(completeRequest1:) withObject:responseData waitUntilDone:NO];
}
[pool drain];
[responseString release];
[urlRequest release];
}
of course it really depends on how many requests/threads you are wanting to spawn.
and you will need to keep track of how many you spawn vs how many finish so you can properly stop your spinner.

Create a new delegate class for each asynchronous image download?

First, I'm using an NSURLConnection to download JSON data from twitter. Then, I'm using a second NSURLConnection to download corresponding user avatar images (the urls to the images are parsed from the first data download).
For the first data connection, I have my TwitterViewController set as the NSURLConnection delegate. I've created a separate class (ImageDownloadDelegate) to function as the delegate for a second NSURLConnection that handles the images. After the tweets are finished downloading, I'm using this code to get the avatars:
for(int j=0; j<[self.tweets count]; j++){
ImageDownloadDelegate *imgDelegate = [[ImageDownloadDelegate alloc] init];
Tweet *myTweet = [self.tweets objectAtIndex:j];
imgDelegate.tweet = myTweet;
imgDelegate.table = timeline; //to reload the data
NSURLRequest* request = [NSURLRequest requestWithURL:[NSURL URLWithString:myTweet.imageURL]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60];
imgConnection = [[NSURLConnection alloc] initWithRequest:request delegate:imgDelegate];
[imgDelegate release];
}
So basically a new instance of the delegate class is created for each image that needs to be downloaded. Is this the best way to go about this? If I were to create only one instance of the delegate class there's no way to figure out which image is associated with which tweet, correct? Nor would I be able to figure out the exact order in which the images are being downloaded.
The algorithm works fine... I'm just wondering if I'm going about it the most efficient way .
Put image downloads into something like an NSOperationQueue.
When the image download is done, save it to the caches directory, then send out a notification containing the original image URL, and the filename the image is now located at.
Anything that wants the image can listen for the notification. If nothing cares anymore (say cells that have scrolled off the screen) then they will have unsubscribed from notifications, so the image will just sit there until the system cleans out your cache directory...
It's also trivial with this system to check and see if an image already exists on disk before you download it, just keep somewhere a mapping of URL's to filenames.
You might perhaps use the queuing feature of ASIHTTPRequest instead. You can create an ASINetworkQueue to handle a ordered queue of requests, and each request can perform behaviors on completion, so that you can track requests with responses.
Requests are based on the NSOperation class, and the queue on NSOperationQueue, so this framework does a lot of the coding work for you.