iOS 7 - Update Data Every 24 Hours - objective-c

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

Related

How get pusher events when the iOS app go to the background?

I need to get triggered eventos from pusher, and when the app go the background I don't get them (only the first one).
I have this:
#property(strong, nonatomic) PTPusherPresenceChannel *taxi_channel;
PTPusherPresenceChannel *taxi = [PusherController sharedApp].taxi_channel;
- (void)viewDidLoad
#weakify(self);
[taxi bindToEventNamed:#"client-driver-cancel-service" handleWithBlock:^(PTPusherEvent *event)
{
DDLogDebug(#"%#: %#", event.name, event.data);
#strongify(self);
[self cancelServiceAcepted];
}];
The problem is that I get a single event when get into the background, but after the first I don't get them anymore.
I have implemented the code at https://github.com/pusher/pusher-test-iOS/blob/master/Diagnostics/Code/ClientDisconnectionHandler.h
If the app go the foreground it work fine.
I'm the author of libPusher. I answered your question on Github but I thought I'd post it here as it might be helpful for others.
Unfortunately its not really possible to use Pusher in the background and its not really what it is designed for. Pusher works great for receiving events in realtime while your app is running but to get background notifications, you really need to be looking at using Apple push notifications OR period fetch, depending on whether you'd prefer push or pull.
My suggestion would be:
Use Pusher while your app is in the foreground to receive real-time updates
Use push notifications to send significant events to your app while it is in the background (these should be less frequent) AND/OR
Possibly use background fetch to pull the latest changes/events from your server
Restart listening to events from Pusher when your app resumes in the foreground

UIApplication fixed background fetch interval (private API welcome)

I'm working on an internal app that requires to check the server every 10 mins or so when the application enters background. Normally, I can use APNS when new record arrives.
However, this app will completely skip Apple's garden, so no APN and yes private API.
So the question, is there any way for me to set the background fetch interval directly instead of calling the normal application setMinimumBackgroundFetchInterval:
I also welcome other ideas for the same result.
I recommend implement VOIP background mode, because is simply and provide app wakeup every few minutes. Just set Voice over IP in Background Modes and register handler;
Example:
[[UIApplication sharedApplication] setKeepAliveTimeout:600 handler:^{
NSLog(#"Here I do something every 600 seconds");
}];
This method more preferable because can work on old iOS, and timeout is fixed vs background fetch where timeout is calculated by user activity and app usage.

Cancel all local notifications when app is closed by the user

There is a small bug in my App.
My App displays notifications at specific times when the App is running and cancel all of them whenever a button is switched.
My problem is that whenever a user closes the App using the multitasking feature of iOS the notifications are still showing up.
I tried to add the following code which doesn't work:
- (void)applicationWillTerminate:(UIApplication *)application
{
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
[[UIApplication sharedApplication] cancelAllLocalNotifications];
}
The problem is that my App should show notifications when the App is running but shouldn't show notifications when the App is terminated.
Why does the above code not work?
The correct answer is that this cannot currently be done by a multitasking app. One solution is to set a flag in our info.plist declaring your app wants to be killed when the user switches to another app - then you will get the willTerminate message (but get killed then).
There are huge numbers of threads on this topic, one which quotes an Apple doc that tells you backgrounded apps that are terminated do NOT get the willTerminate message is here.
For me, this just means I can now close an open bugreport out with a 'cannot fix' resolution :-)
Just because your app is visible in the app-changer, it doesn't mean it is still running.. it can get closed at any point. You cannot differentiate between the OS closing your app or the user closing your app.
Perhaps a button would be the solution? A button that cancels all notifications?
Or you run a real background task (which can last for about 5 minutes) and stop all notifications afterwards. Or you just schedule the notifications for the next 5-10 minutes and that's it.
For what are you using them?

iOS app lifecycle regarding CLLocationManager startMonitoringForRegion

In iOS one can purportedly use the CLLocationManager's startMonitoringForRegion: method to register a delegate to respond to the device moving into a specific geographic region, even when the app isn't launched. From the CLLocationManager Class Reference:
In iOS, the regions you register with the location manager persist between launches of your application. If a region crossing occurs while your iOS app is not running, the system automatically wakes it up (or relaunches it) in the background so that it can process the event. When relaunched, all of the regions you configured previously are made available in the monitoredRegions property of any location manager objects you create.
I assume if the app is relaunched, iOS doesn't actually bring it to the foreground. I couldn't find any good samples illustrating where startMonitoringForRegion fits into an overall application, so my questions are:
Does one have to register the delegate for startMonitoringForRegion from somewhere specific? I'm guessing it can't be plonked in a view controller if we're launching the app without bringing it into the foreground. Can someone give an example with some context around it?
If we decide we do want to bring the app into the foreground as a result of entering the region, how would we do so?
When is startMonitoringForRegion registered with the OS and when is it unregistered? Does the user have to have launched the app at least once (even if it's since been killed) for the initial registration to take place? What about if the user powers off the device? Will our handler be registered the next time the device is powered on, or will the user have to launch the app at least once again?
Does one have to register the delegate for startMonitoringForRegion from somewhere specific? I'm guessing it can't be plonked in a view controller if we're launching the app without bringing it into the foreground.
False. A view controller object still does exists if it's allocated-initialized, even if its contents are not presented.
If we decide we do want to bring the app into the foreground as a result of entering the region, how would we do so?
Not possible using public APIs (I'm not sure whether an app in the background can use - [UIApplication openURL:] with its own URL scheme to bring itself into the background, but I doubt it); however you may be able to use the SpringBoardServices framework to launch your app:
SBSLaunchApplicationWithIdentifier(CFSTR("com.mycompany.theBestiPhoneAppEver"), false);
When is startMonitoringForRegion registered with the OS and when is it unregistered? Does the user have to have launched the app at least once (even if it's since been killed) for the initial registration to take place?
If the user never runs your application, code inside will never be run, so it won't get registered.
What about if the user powers off the device? Will our handler be registered the next time the device is powered on, or will the user have to launch the app at least once again?
Now that's a good question. I don't know it off the top of my head, nor did I find an answer in the documentation (probably you haven't found that either), so I'd say you just better try it yourself to be sure.

App won't relaunch when monitoring CLLocationManager significant location changes - iPhone

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.