Reputation: 2955
I found that sometimes you may be doing something in your iPhone application that requires the user to wait while it completes. Often this is a network related activity, but in other cases it may not be. In my case I was parsing the response from a network connection and wanted the network activity indicator to keep spinning even though it had already downloaded the content.
below is what i'm doing:
applicationDelegate.m :
- (void)setNetworkActivityIndicatorVisible:(BOOL)setVisible
{
static NSInteger NumberOfCallsToSetVisible = 0;
if (setVisible)
NumberOfCallsToSetVisible++;
else
NumberOfCallsToSetVisible--;
// Display the indicator as long as our static counter is > 0.
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:(NumberOfCallsToSetVisible > 0)];
}
otherView.m:
dispatch_queue_t dataLoadingQueue = dispatch_queue_create("synchronise", NULL);
dispatch_async(dataLoadingQueue,
^{
[appDelegate setNetworkActivityIndicatorVisible:YES];
[[DataLoader instance]LoadDataForGrewal];
[[FieldConsultantViewModelManager instance] resetCache];
[[DailyFieldConsultantViewModelManager instance] clearCache];
[appDelegate loadMainViews];
[[DataLoader instance]LoadDataForOtherEntities];
[appDelegate setNetworkActivityIndicatorVisible:NO];
});
dispatch_release(dataLoadingQueue);
as u can see above, i'm trying to keep the network indicator while updating the data into the database but it does not work , any clue / suggestions ?
Thanks EDIT :
dispatch_queue_t dataLoadingQueue = dispatch_queue_create("synchronise", NULL);
dispatch_async(dataLoadingQueue,
^{
dispatch_async(dispatch_get_main_queue(), ^{ [self setNetworkActivityIndicatorVisible:YES]; });
[[DataLoader instance]LoadDataForGrewal];
[[FieldConsultantViewModelManager instance] resetCache];
[[DailyFieldConsultantViewModelManager instance] clearCache];
[appDelegate loadMainViews];
[[DataLoader instance]LoadDataForOtherEntities];
dispatch_async(dispatch_get_main_queue(), ^{ [self setNetworkActivityIndicatorVisible:NO]; });
});
dispatch_release(dataLoadingQueue);
it does not work i'm not sure why because i'm newbie in ios
Upvotes: 2
Views: 2053
Reputation: 9600
For anyone looking for a complete solution, this is what I use (in Swift). It delays a short duration when stopping the network indicator. This will prevent the indicator from flickering if you have a lot of serial network request.
private var networkActivityCount = 0
func updateNetworkActivityCount(increaseNumber increase:Bool)
{
let appendingCount = increase ? 1 : -1
networkActivityCount += appendingCount
let delayInSeconds = increase ? 0.0 : 0.7
perform({ () -> () in
let application = UIApplication.sharedApplication()
let shouldBeVisible = self.networkActivityCount > 0
if application.networkActivityIndicatorVisible != shouldBeVisible {
application.networkActivityIndicatorVisible = shouldBeVisible
}
}, afterDelay: delayInSeconds)
}
Where perform:afterDelay
is defined as
public func perform(block: ()->(), afterDelay:Double) {
let dispatchTime: dispatch_time_t = dispatch_time(DISPATCH_TIME_NOW, Int64(afterDelay * Double(NSEC_PER_SEC)))
dispatch_after(dispatchTime, dispatch_get_main_queue(), {
block()
})
}
Just call updateNetworkActivityCount(increaseNumber: true)
before your request and the same with false
in your request callback. I.e:
updateNetworkActivityCount(increaseNumber: true)
let task = urlSession.dataTaskWithRequest(request) { data, response, error in
self.updateNetworkActivityCount(increaseNumber: false)
...
Upvotes: 1
Reputation: 1718
try to dispatch your setNetworkActivityIndicatorVisible:
call on main queue, because UIApplication is in UIKit and UIKit is not thread-safe.
Upvotes: 2