Alert when web query is in progress?
I was stopped in my work by a small problem: my application contains some web queries, which are almost immediately performed if wifi connection is used, however they need a couple of seconds to finish in case of 3G or even EDGE connection. During this period, I would like to indicate to the user that the query is in progress, e.g. by displaying a message on a label.
The code looks something like this:
-(void)query{
alertLabel.text = @"in progress…";
// the query follows...
NSString *queryURLstring = [NSString stringWithFormat:@"http://xyz.xyz"];
NSURL *queryURL = [[NSURL alloc] initWithString:queryURLstring];
NSString *receivedData = [[NSString alloc] initWithContentsOfURL:queryURL];
//query done
alertLabel.text = @"";
}
What happens in practice is that when the query is being executed, the user can not actually do anything. When the requested data is received, the "in progress…" text appears just for a moment and it disappears immediately. I can not understand that, as this is not how it should work. The text should be displayed on the label before the query is executed, and should be cleared only upon finishing. Have anyone faced such issue? Can you recommend a solution? Thanks f开发者_运维知识库or all kind of suggestions! Miv
There are few solutions for your problem.
@Eiko has explained the problem and the reasons very well.
Next is one possible solution (with minimal amount of changes to your code):
Just execute your query
method in the background thread like this:
[self performSelectorInBackground:@selector(query) withObject:nil];
And replace the alertLabel.text = @"in progress…";
by:
[alertLabel performSelectorOnMainThread:@selector(setText:) withObject:@"in progress…" waitUntilDone:NO];
[the same about the alertLabel.text = @"";
]
It would be better if you would:
- Add 2 methods:
- (void)showLoadingWithText:(id)loadingText;
and- (void)hideLoading;
. - Call these methods in the main thread (instead of performing selectors directly on the label).
- Add some additional activity indicators like
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
(will display a loading indicator in the header) or your customUIActivityIndicatorView
(you should locate it somewhere near thealertLabel
).
You should load the data asynchronously.
- Show the alert label
- Start downloading asynchronously
- Upon finishing (successful or error) remove the label.
When something takes longer than expected and you are blocking the main thread be prepared to get the whole application killed automatically - you definitely do not want this to happen!
As for the updates on screen. Updates happen only at the end of the current run loop iteration, so this is totally expected behavior. (To be honest, I'm a bit surprised the test is visible at all).
精彩评论