How to reinitialize app after backgrounding - ios

-(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?

Related

iOS crash on Starting Background Task

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;
}

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];
}

Delay when using openURL right after after app launch

I am trying to launch another application using its url handler right on my own app launch.
- (void)applicationDidBecomeActive:(UIApplication *)application
{
NSURL *actionURL = [NSURL URLWithString:#"fantastical2://"];
[[UIApplication sharedApplication] openURL:actionURL];
}
It basically works, however there is a significant delay of about 7 seconds from seeing my app appear to actually opening the URL.
How come the delay? How can I launch open a URL/app immediately when launching my own app or reduce this delay?
You can resolve using any of the examples below.
Using diapatch_async
dispatch_async(dispatch_get_main_queue(), ^{
[[UIApplication sharedApplication] openURL:urlString];
});
Using perfomSelector
- (void)applicationDidBecomeActive:(UIApplication *)application
{
...
//hangs for 10 seconds
//[[UIApplication sharedApplication] openURL:[NSURL URLWithString: url]];
//Fix: use threads!
[self performSelector:#selector(redirectToURL:)
withObject:url afterDelay:0.0];
...
}
- (void)redirectToURL:(NSString *)url
{
[[UIApplication sharedApplication] openURL:[NSURL URLWithString: url]];
}
Using NSThread
- (void)applicationDidBecomeActive:(UIApplication *)application
{
...
//hangs for 10 seconds
//[[UIApplication sharedApplication] openURL:[NSURL URLWithString: url]];
//Fix: use threads!
[NSThread detachNewThreadSelector:#selector(openBrowserInBackground:)
toTarget:self withObject:url];
...
}
- (void)openBrowserInBackground:(NSString *)url
{
[[UIApplication sharedApplication] openURL:[NSURL URLWithString: url]];
}
Try with the NSTimer with target ..
For just Reference :
[NSTimer scheduledTimerWithTimeInterval:7.0
target:self
selector:#selector(targetMethod:)
userInfo:nil
repeats:NO];
-(void) targetMethod{
// Call Here ...
NSURL *actionURL = [NSURL URLWithString:#"fantastical2://"];
[[UIApplication sharedApplication] openURL:actionURL];
//Invalidate the time
[myTimer invalidate];
myTimer = nil;
}
Add your code in - (void)applicationDidFinishLaunching:(UIApplication *)application because - (void)applicationDidBecomeActive:(UIApplication *)application will be called after applicationDidFinishLaunching is called.
Try calling the -openURL method within a block that runs on the main thread. This will cause it to execute once everything else is loaded:
-(void)applicationDidBecomeActive:(UIApplication *)application {
dispatch_async(dispatch_get_main_queue(), ^{
NSURL *actionURL = [NSURL URLWithString:#"fantastical2://"];
[[UIApplication sharedApplication] openURL:actionURL];
});
}

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];
}
}

Resources