iOS crash on Starting Background Task - ios

I've recently revisited my app which was last built for iOS 8.4 and now updating it to 9.3. It was working fine the first few times I ran it but now crashes on every open, across each simulator with the error: EXC_BAD_ACCESS(code=50)
-(void)beginBackgroundUpdateTask
{
if (self.backgroundTaskAgent == UIBackgroundTaskInvalid)
{
self.backgroundTaskAgent = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^(void) {
[self endBackgroundUpdateTask];
}];
}
}
-(void)endBackgroundUpdateTask
{
if (self.backgroundTaskAgent != UIBackgroundTaskInvalid)
{
[[UIApplication sharedApplication] endBackgroundTask:self.backgroundTaskAgent];
self.backgroundTaskAgent = UIBackgroundTaskInvalid;
}
}
The crash occurs in the top method with beginBackgroundTaskWithExpirationHandler. I've never had this error before and can't find any solution to it myself or on SO.

Try like this,
-(void)beginBackgroundUpdateTask
{
self.backgroundTaskAgent == UIBackgroundTaskInvalid
self.backgroundTaskAgent = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^(void) {
[self endBackgroundUpdateTask];
}];
}
-(void)endBackgroundUpdateTask
{
[[UIApplication sharedApplication] endBackgroundTask:self.backgroundTaskAgent];
self.backgroundTaskAgent = UIBackgroundTaskInvalid;
}

Related

Disabling UI interaction of iPad till the data is downloading on main thread in backend

I want to Disable UI interaction of iPad till the data is downloading on main thread in backend using Blocks
I m downloading the images at loading time
-(void)downLoadImageData{
[self ShowActivityIndicator];
[iOSNetwork getImages:ImageID andEvent:eventID
onCompletion:^(NSString* result,NSError* error)
{
dispatch_async(dispatch_get_main_queue(), ^{
if(error)
{
[self stopFetch:#"Error while Processing"];
}
else
{
[[UIApplication sharedApplication] beginIgnoringInteractionEvents];
[self stopFetch:result];
}
});
}];
}
-(void) stopFetch:(NSString*) result{
[self hideActivityIndicator];
//after downloading completed
[[UIApplication sharedApplication] endIgnoringInteractionEvents];
}
if use entire application call
[[UIApplication sharedApplication] beginIgnoringInteractionEvents];
after downloading completion
[[UIApplication sharedApplication] endIgnoringInteractionEvents];
another choice
[self.view setUserInteractionEnabled:NO];
after the completion
[self.view setUserInteractionEnabled:YES];
one more choice
self.navigationController.navigationBar.userInteractionEnabled=NO;
// perform other events also userInteractionEnabled=NO;
after the completion
self.navigationController.navigationBar.userInteractionEnabled=YES;
// perform other events also userInteractionEnabled=NO;
in your question
-(void)downLoadImageData{
[self ShowActivityIndicator];
[[UIApplication sharedApplication] beginIgnoringInteractionEvents]; // call here
[iOSNetwork getImages:ImageID andEvent:eventID
onCompletion:^(NSString* result,NSError* error)
{
dispatch_async(dispatch_get_main_queue(), ^{
if(error)
{
[self stopFetch:#"Error while Processing"];
}
else
{
[self stopFetch:result];
// not here
}
});
}];
}
You can use MBProgressHud for this. You need to add MBProgressHUD files into project.
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
self.HUD = [[MBProgressHUD alloc] initWithWindow:appDelegate.window];
[appDelegate.window addSubview:self.HUD];
- (void)showHUDWithText:(NSString *)labelText{
if (_isHUDAlreadyInProgress) {
return;
}
_isHUDAlreadyInProgress = TRUE;
[_HUD.superview bringSubviewToFront:_HUD];
self.HUD.labelFont = [UIFont systemFontOfSize:13.0];
//self.HUD.labelText = labelText;
[self.HUD show:TRUE];
}
- (void)hideHUD{
_isHUDAlreadyInProgress = FALSE;
[self.HUD hide:TRUE];
}

local notification when not reachable and app in background

Goal is to notify end user about reachability changed when app is in background.
Broadcasting approach NSNotificationCenter not working in background.
second approach i tried beginBackgroundTaskWithExpirationHandler in applicationDidEnterBackground but associated issue with it:
a) Time limitation of 10 min
b) i calling a end loop for detecting the reachability state which run on main thread and in result it choke the UI. Code:-
-(void)applicationDidEnterBackground:(UIApplication *)application
{
NSLog(#"Application entered background state.");
// bgTask is a property of the class
if (isUserLogin) {
NSAssert(self.bgTask == UIBackgroundTaskInvalid, nil);
bgTask = [application beginBackgroundTaskWithExpirationHandler: ^{
dispatch_async(dispatch_get_current_queue(), ^{
[application endBackgroundTask:self.bgTask];
self.bgTask = UIBackgroundTaskInvalid;
});
}];
dispatch_async(dispatch_get_current_queue(), ^{
while ([application backgroundTimeRemaining] > 1.0) {
curReach = [[utilities sharedUtility]reachabilityChanged];
NetworkStatus netStatus = [curReach currentReachabilityStatus];
NSLog(#"-----------back ground task------------");
if (netStatus == ReachableViaWWAN || netStatus == ReachableViaWiFi) {
//isNetworkMessagePopup = YES;
}
else{
// if (isNetworkMessagePopup) {
// isNetworkMessagePopup = NO;
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
if (localNotif) {
localNotif.alertBody = FORMAT_UNABLE_TO_CONNECT_SERVER_DUE_TO_NO_INTERNET;
localNotif.alertAction = NSLocalizedString(#"Read Message", nil);
localNotif.soundName = #"pushNotification.caf";
localNotif.repeatInterval = 5;
//localNotif.applicationIconBadgeNumber = 1;
[application presentLocalNotificationNow:localNotif];
[localNotif release];
break;
//}
}
}
}
[application endBackgroundTask:self.bgTask];
self.bgTask = UIBackgroundTaskInvalid;
});
}
}
Please suggest me is it possible to notify user in iOS whenever reachability changed and app in background state?
If yes then how can i achieve this.
Thanks.
You could possibly use the background fetch capability as described in the iOS App Programming Guide to check reach ability and post a local notification if the network is un available.
There is no guarantee of how often this will be called - probably in the order of every few minutes or longer - certainly not every few seconds.

Tracking User Location in the Background in iOS 7

I am trying to track's user location when the application moves to background. I just need to track once. So, I am not using background location services. In the code below this works when I uncomment 1 but it doesn't work when I uncomment 2.
- (void)applicationDidEnterBackground:(UIApplication *)application
{
// 1 works here [self startStandardUpdates];
self.bgTask = [application beginBackgroundTaskWithExpirationHandler:^{
[application endBackgroundTask:self.bgTask];
self.bgTask = UIBackgroundTaskInvalid;
}];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{
// 2 doesn't work here [self startStandardUpdates];
});
}
In second case this delegate function is not called.
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
NSLog(#"Updated\n%#",locations);
[self.manager stopUpdatingLocation];
[[UIApplication sharedApplication] endBackgroundTask:self.bgTask];
self.bgTask = UIBackgroundTaskInvalid;
}
Can someone tell me why this is not working in 2nd case. Also, is it fine using [self startStandardUpdates] in the first position ?
Try this
By default, this is YES for applications linked against iOS 6.0 or later.
if ([self.manager respondsToSelector:#selector(pausesLocationUpdatesAutomatically)]) {
self.manager.pausesLocationUpdatesAutomatically = NO;
}

how to call a method by using nstimer in background state

I want to fetch service for every 15 mins,so i am using NSTimer.It is working fine.But how to call same service while app is in background state by using nstimer.Nstimer is not working in background state.Please suggest me.
//when the application is about to move from active to inactive state.
- (void)applicationWillResignActive:(UIApplication *)application
{
[self sendBackgroundLocationToServer];
}
- (void) sendBackgroundLocationToServer
{
UIBackgroundTaskIdentifier bgTask = UIBackgroundTaskInvalid;
bgTask = [[UIApplication sharedApplication]
beginBackgroundTaskWithExpirationHandler:^{
[[UIApplication sharedApplication] endBackgroundTask:bgTask];
}];
//Start Timer
[self startTimer];
//Close the task
if (bgTask != UIBackgroundTaskInvalid)
{
[[UIApplication sharedApplication] endBackgroundTask:bgTask];
}
}

How to reinitialize app after backgrounding

-(void) closeUpShopBeforeBackgrounding {
// this listen to the UIApplicationDidEnterBackgroundNotification
[self beginBackgroundUpdateTask];
// do some closing stuff
[self endBackgroundUpdateTask]; }
- (void) beginBackgroundUpdateTask {
self.backgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[self endBackgroundUpdateTask];
}]; }
- (void) endBackgroundUpdateTask {
[[UIApplication sharedApplication] endBackgroundTask: self.backgroundTask];
self.backgroundTask = UIBackgroundTaskInvalid; }
This code is working fine for me, but when I foreground the app again, its dead in the water. Its as if the viewDidLoads are not firing, and nothing is happening.
Is there anything I need to do when the app foregrounds to kick it back into life?

Resources