I know there are hundreds of topics out there concerning the background fetch on iOS. I simply cannot solve my problem to get the background fetch for my app to work. It is absoulutely substantial for the outcome of my app to have a working background fetch. My background fetch works fine on the simulator via Debug -> Simulate Background fetch and also on device with the special scheme setting: "Launch due to a background fetch event". I know that it doesn´t gets executed when the user is force quitting the app. I tried to lock the iPhone and wait for hours then unlock it to try to trigger the background fetch. Nothing happens. Actually everything works fine but the background fetch simply NEVER gets executed on my iPhone. I know that iOS has a special algorithm for calling background threads so a little patient is needed. But after 2 months of waiting for a background fetch to happen automatically I don´t have patients anymore. What I did:
App capabilites: Background fetch activated
Info.plist: Required background modes: App downloads content from the network
App delegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if ([UIApplication instancesRespondToSelector:#selector(registerUserNotificationSettings:)]){
[application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound categories:nil]];
}
[[UIApplication sharedApplication] setMinimumBackgroundFetchInterval:2.0];
return YES;
}
- (void) application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
//Do my stuff
completionHandler (UIBackgroundFetchResultNewData);
}
Did you check out to go Settings->General->background app refresh and check if its enabled?
It could be the problem...
Related
I fired LocalNotification 5 minutes from current time. Then I stopped the application and killed it from background. I received local notification after 5 minutes. While taping on the app icon got opened but didReceiveLocalNotification Method is not called.
Please post some code for better answer.
In the meantime test your app on device.Sometime notification methods working on device but not working on simulator.
use this method
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void(^)())completionHandler{
}
I'm working on an iPhone app that needs to send the current location to a server so it knows what push notifications to send. It doesn't have to be very precise, startMonitoringSignificantLocationChanges is perfect for my needs.
This all works well as long as the app is running on screen or in the background. However if I kill/terminate the app it doesn't work anymore. From what I understand the app should be automatically relaunched with the special UIApplicationLaunchOptionsLocationKey as launch option. However the app doesn't relaunch (at least not in simulator).
I've read some stuff here too:
Behaviour for significant change location API when terminated/suspended?
Does the automatic relaunching only work when the app is terminated from suspended state by the system and not when you manually kill the app? I also tried the special info.plist UIApplicationExitsOnSuspend which also terminates the app when it goes into the background. It doesn't get relaunched then either.
Is there a way to simulate the app being terminated by the system in the simulator?
What happens after an iOS update when the phone has restarted? Is there a way to make sure that the app will get relaunched?
An app is relaunched by an SLC regardless of how it was killed provided when it was killed at least one CLLocationManager had called startMonitoringSignificantLocationChanges. There is one caveat to this - in version iOS7.0(.x) it was broken. It started working again in iOS7.1+.
To get this working requires that you complete a few steps.
In you project capabilities you must enable the background mode location updates because you want to be woken in the background.
You need to add the key NSLocationAlwaysUsageDescription to the info.plist containing a description of why you want to always be able to use location in the background.
In the code you must request authorization from the user to always use location
In the code you must request that location updates continue to be delivered while in the background
In the code you must start monitoring for significant location changes
Here is an example:
AppDelegate,h
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#interface AppDelegate : UIResponder <UIApplicationDelegate, CLLocationManagerDelegate>
#property (strong, nonatomic) UIWindow *window;
#property CLLocationManager* locationMgr;
#end
AppDelegate.m
#import "AppDelegate.h"
#implementation AppDelegate
#synthesize locationMgr;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSLog(#"app launching");
locationMgr = [[CLLocationManager alloc] init];
[locationMgr setDelegate:self];
// Added in iOS8
if([locationMgr respondsToSelector:#selector(requestAlwaysAuthorization)])
[locationMgr requestAlwaysAuthorization];
// Added in iOS9
if([locationMgr respondsToSelector:#selector(setAllowsBackgroundLocationUpdates:)])
[locationMgr setAllowsBackgroundLocationUpdates:YES];
[locationMgr startMonitoringSignificantLocationChanges];
return YES;
}
-(void) locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
NSLog(#"app delegate received significant location change");
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:[[UIApplication sharedApplication] applicationIconBadgeNumber]+1];
}
#end
The first time you run the app on your device, click on OK to allow the app to use your location in the background when it is requested. Then double click the home button and swipe the app off the task switcher to kill it. Click home, then swipe up from the bottom of the screen to open the Control Center and turn on Airplane Mode, wait a few seconds, then turn off airplane mode. Watch the badge counter increment on your app.
It was launched by iOS on an SLC.
One gotcha I would like to add. If you create two CLLocationManager instances and call startMonitoringSignificantLocationChanges on both, then call stopMonitoringSignificantLocationChanges on one. Even though the other CLLocationManager will continue to receive SLC events while the app continues to run, when you app exits for any reason, it will not be relaunched.
It seems the last call before exit sets the relaunch behaviour.
start, start, stop, exit - app doesn't relaunch on SLC.
start, start, stop start, exit - app does relaunch on SLC.
I've answered a question like this.
You can check my answer on the link below.
https://stackoverflow.com/a/35722254/3368791.
I know there is NSURLSession class which is launched in iOS7 and it does have NSURLSessionUploadTask for uploading data to server, But I need to know whether it will continue uploading even after in background mode if no? then what to do for continue that task in background mode too for complete uploading.
previously we can use beginBackgroundTaskWithExpirationHandler: and endBackgroundTask: which will continue that task to max 10 minutes for iOS6 but in iOS 7 and above it will hardly run upto 3 minutes (as per my knowledge).
So can you please help me guys for any solution or example if available.
The answer for your first question is probably YES, you can continue uploading for the tim e that is permitted by the iOS but for that you need use UIBackgroundTaskIdentifier to get hold of that extra time.
And for the second part of your question for uploading the remaining images when the app is not running you can use Background fetch. When you enable Background fetch the app regularly downloads and processes small amounts of content from the network. So probably by combining UIBackgroundTaskIdentifier and Background fetch you can achieve uploading the images in background.
Below mentioned are the steps to combine UIBackgroundTaskIdentifier and Background fetch.
First let's initialise UIBackgroundTaskIdentifier
-(void) beginBackgroundUploadTask
{
if(self.backgroundTask != UIBackgroundTaskInvalid)
{
[self endBackgroundUploadTask];
}
self.backgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[self endBackgroundUploadTask];
}];
}
Once the background task runs out of time from the stipulated allotted time, we should invalidate and end the background task.
-(void) endBackgroundUploadTask
{
[[UIApplication sharedApplication] endBackgroundTask:self.backgroundTask ];
self. backgroundTask = UIBackgroundTaskInvalid;
}
Do not forget to enable Background Modes in Xcode → Select Project File → Capabilities → Check the Background fetch checkbox.
For further info you can refer the link below:
http://mobisoftinfotech.com/resources/mguide/background-fetch-ios/
Could any help in creating a Unity3D App which could request some data from some webservice (let say every 5 mins) and send a local notification while the game app is running in the background.
You can use the AppController class that the Unity player creates. You need to respond to some of these messages:
- (void)applicationWillEnterForeground:(UIApplication *)application
- (void)applicationDidBecomeActive:(UIApplication *)application
- (void)applicationDidEnterBackground:(UIApplication *)application
These are called when the application goes from the background to active and vice-versa. If you want to communicate with unity, you can pass some info with:
UnitySendMessage("GameObjectName1", "InBackground", "Message to send");
If you send the message in (void)applicationDidEnterBackground:(UIApplication *)application
, the method InBackground() will be called. You can have coroutine in that method with is called in every fixed time. This is a theory. Try to implement it.
I'm writing following code that opens browser when app will be going to background:
- (void)applicationWillResignActive:(UIApplication *)application
{
/*
Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
*/
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"http://www.google.com"]];
}
but its not opening. Any suggestions?
Can I open browser in "applicationWillResignActive" or not?
You code looks fine so I guess that iOS won't let you do it. Your app has been told to go into the background - you don't get to open new apps!
PS :
Why would you ever want to do this - surely this will just really really annoy the user?