is - (void)applicationDidEnterBackground:(UIApplication *)application capable of making calculations every day at 10AM, even when app is closed complitly (killed with task manager).
Sorry for stupid question but I don't want to start making something pointless. :)
Sort of. You can implement background fetching for your app in this method
- (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
However, you can't just implement the method. You have to be sure to enable background fetching for your application. Background fetching
Note that you can choose one of two options
1: Have the iOS schedule the fetch for you based on when the user usually opens your app
2: Request a time interval between fetches. Not guaranteed to execute when you want though, just a request.
Related
I have a timer related app,that lets the user set timer to different objects.
What I am doing right now -
Right now.I am scheduling a local notification when the timer gets to it's end, and then when the user gets the notification, he needs to open the app so it could process the changes related to this timer.
What I want to achieve -
I have looked on the new iOS7 background modes but could not determine if I can use that to perform those updates to the core data, without opening the app.
So the flow will be:
a timer is coming to it's end.
The user gets a local notification where he needs to permit the operation.
Get the user answer and perform the update while the app is still in the background.
Is that possible with the new API ? Or is it limited to data fetches only ?
If you are you are using Push Notification Using ios 7 new background fetcher api is useful,
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))handler
{
}
When a push notification arrives, the system displays the notification
to the user and launches the app in the background (if needed)so that it can call this method. Use this method
to download any data related and store to core data to the push notification. When your method is done, call the block in the handler
parameter.
I'm creating an app that needs to check for data once a day (midnight). I know there is a background fetch mode in iOS7, but from what I know there is no way to force it to update in given time interval. Is there any way to do this and still pass the Appstore review?
Thank you for any suggestions.
There is not real way to do this, since it requires you app to be running in background. background running modes are restricted to audio, VOIP, location and accessory type apps.
What you could do is just check when you last update data in the app when the user launches the app. This way you will only update data when the user starts your app and also only use data when the user is really using the app.
The background fetching will only work if the user is start your app often and iOS will allow you app to do background fetching. iOS will decide when you app is allowed to do a background refresh and you have little influence over the interval.
UIApplicationBackgroundFetchIntervalMinimum
The smallest fetchinterval supported by the system.
Maybe it's not exactly answer you expect but in iOS 7 there is a functionality which allow you to fetch the data every some period of time.
In this scenario iOS intelligently schedules the background fetch events based on your app usage and it helps you save battery life. So this not going to work every 24h but I think you can read the data and if it has been updated refresh the app if not ignore it.
In your Xcode 5 -> Target -> Capabilities turn on Background modes (background fetch).
And in application:didFinishLaunchingWithOptions add:
[[UIApplication sharedApplication] setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];
This is a method which will be called:
- (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
}
I am working on an app that keeps track of user's location at a time-interval set by the user himself(e.g. every 5 minutes) and sends it to a server page by ASIHTTPRequest.
This app should be able to receive updates on foreground, either on background or even when the app is not running(location services).
Although my app successfully receives updates on the foreground and background, it does not seem to wake up when it is not running and do not send me up any requests to the server.
I am using CLLocationManager and its delegate to perform startMonitoringSignificantLocationChanges for when it is on the background.
On Settings, the icon for my app in Location Services appears with a purple arrow as expected.
On my info.plist, I have Required Background Modes set with an item locations as required and methods:
locationManager:didUpdateToLocation:fromLocation:
locationManager:didFailWithError:
implemented.
My method:
(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
is also implemented and checks whether launchOptions
contains UIApplicationLaunchOptions- LocationKey before starting the significant locations monitoring for when it should wake up / relaunch.
Is there any way I can find out whether my app is really being relaunched?
Is there any extra config that needs to be set in order this to work?
Please let me know if I should provide any additional info.
Specs I am using:
SDK Xcode 4.2.1
CLLocation is inside a Singleton class (read somewhere this might impact)
iOS deployment target: 4.3
Tested on Iphone 3GS,4 and Xcode's iOS 5 simulator, same behavior happens to all of these devices.
Devices:universal
UPDATE
I inserted my code inside -[UIApplication beginBackgroundTaskWithExpirationHandler:] and tried to check against errors with UIBackgroundTaskInvalid. However, it does not even seem to enter the (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions method.
I am keeping track of the app by trying to save and retrieve data by using SQLite. When executing on both foreground and background, it records the data with no problem. When the app is not running, no data is saved at all.
How are you currently checking to see if the app relaunches? Are you logging anything?
The app will relaunch to the background, so you won't see your app come alive. It will actually shut down automatically after some time again. You can do some work and request more background time using -[UIApplication beginBackgroundTaskWithExpirationHandler:].
Another answer here on SO posted some example code. From your description I cannot see anything missing, compare your code to that project to see if your missing something.
I'm opening the database connection in AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
and I'm closing on applicationWillTerminate
- (void)applicationWillTerminate:(UIApplication *)application
{
/*
Called when the application is about to terminate.
Save data if appropriate.
See also applicationDidEnterBackground:.
*/
NSLog(#"Closing DB");
if(database) sqlite3_close(database);
}
But when I close (really close) the app on the simulator, I do not get the log "Closing DB" in the console. Is it normal?
What is the best place to close a sqlite3 connection in Objective-c?
(really close means
– Double tap the Home button to bring up the Multitasking bar
– Press and hold anywhere on the multitasking bar until the icons on it start to wiggle.
– While they are wiggling, each icon has a Minus sign symbol above it.
– Press the Minus symbol above any app to close it down.)
This is because your application didn't terminate. It went into background. Try adding your code to applicationDidEnterBackground
Try to avoid usage of -applicationWillTerminate: method because you have not enough time(!) to do your work correctly - maybe system is rebooting or shutting down. The best practice to save data and purge unused resources (if needed) is to put your code in -applicationDidEnterBackground: method.
From Apple's UIApplicationDelegate Protocol Reference:
Your implementation of this method has approximately five seconds to
perform any tasks and return. If you need additional time to perform
any final tasks, you can request additional execution time from the
system by calling beginBackgroundTaskWithExpirationHandler:. In
practice, you should return from applicationDidEnterBackground: as
quickly as possible. If the method does not return before time runs
out your application is terminated and purged from memory.
You should perform any tasks relating to adjusting your user interface
before this method exits but other tasks (such as saving state) should
be moved to a concurrent dispatch queue or secondary thread as needed.
Because it's likely any background tasks you start in
applicationDidEnterBackground: will not run until after that method
exits, you should request additional background execution time before
starting those tasks. In other words, first call
beginBackgroundTaskWithExpirationHandler: and then run the task on a
dispatch queue or secondary thread.
(c) taken from this answer
Im trying to find a way to save data before my app enters multitasking, i know how to save data, but i dont know what method to use to save it before the app enters multitasking.
-(void)applicationDidEnterBackground:(UIApplication *)application{
this one? because i have everything set up to save, but it doesn't seem to be saving it, and im positive that its the multitasking part because it works on the ios 3 simulator. Do i have to save it in the delegate?
Thanks,
Jacob
EDIT: On the IOS 3 one i have it saving data in the
- (void)applicationWillTerminate:(UIApplication *)application {
Yes Jacob, You have to save it in the application delegate of your app.
The method -(void)applicationWillResignActive:(UIApplication *)application gets called when the device enters standby mode or when the app is switched to background.
So the saving part you can add to this method .
Also to make the app save data for iOS versions < 4.0 , add the saving code to applicationWillTerminate: also.
You should use the method what is the method Apple recommends
-(void)applicationDidEnterBackground:(UIApplication *)application
but you can also use
- (void)applicationWillResignActive:(UIApplication *)application
which is the method that is called instead of
- (void)applicationWillTerminate:(UIApplication *)application
Take a look at this Delegate method:
-(void)applicationWillResignActive:(UIApplication *)application
This allows you to react when the application becomes inactive. See the Docs for more information.
Happy coding :)