iOS - In-App Purchase & applicationDidBecomeActive - cocoa-touch

I'm working on an app for 4.0 using the background methods. I'm updating the user defaults with a number that is incremented each time the app is launched. Looks like in 4.0 didFinishLaunchingWithOptions doesn't fire each time the app is launched, only the first time it's launched if it's not already in the background. So right now, my user default is incrementing within the applicationDidBecomeActive method. Not sure if this is the right place. I did the same thing with Flurry Analytics and some other stuff that I want to instantiate each time the app is "launched".
I noticed that during an in-app purchase the applicationDidBecomeActive method fires twice. Not only is it falsely incrementing my user default as if the app was relaunched, it is also reinitializing flurry and the other items in the applicationDidBecomeActive method.
What am I doing wrong? Should I be using another method each time the app is "launched"?
Thanks,
Howie

Maybe you could try applicationWillEnterForeground instead of using applicationDidBecomeActive.

Related

iOS 7 - Update Data Every 24 Hours

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

applicationWillTerminate not getting called on force quit of iOS app

Does anyone have any insights into when/under what conditions applicationWillTerminate is called in iOS 5/6?
I've got some logic i'd like to execute whenever the application terminates (not moves to the background), for example if the user navigates to the application bar at the bottom of the screen by double tapping the home button and force quits the app.
when i try to do this on a test device, applicationWillTerminate does not seem to get called. Is there a reason for this?
My plan B is to tie that logic to some persistent object like a singleton or a static that is automatically destroyed when the app quits.
Any suggestions?
thanks
Have you read the documentation for applicationWillTerminate:,
It says,
For applications that do not support background execution or are linked against iOS 3.x or earlier, this method is always called when the user quits the application. For applications that support background execution, this method is generally not called when the user quits the application because the application simply moves to the background in that case. However, this method may be called in situations where the application is running in the background (not suspended) and the system needs to terminate it for some reason.
There is a "maybe" mentioned there. Probably that answers your question. So it is not necessary that this will get called when you quit the app. Probably you might have to use UIApplicationExitsOnSuspend to disable multitasking and then it might get called while putting in background. But that again depends on your app requirement. If you cannot disable multitasking, you might have consider doing that in applicationDidEnterBackground method or so. I am not sure if there are any other delegate methods which will help in identifying the force quit.

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.

Show app running time in iPhone

I would like to write a counter that shows how many seconds an app has be running for. (textView) and the counter should be cumulative and starts from where it left off. Im new to iphone sdk.
you are going to have to do these things:
get the time when the app starts in applicationDidFinishLaunching: in your application delegate
check if you have an old time using NSUserDefaults
have a thread that updates the ui (your textView display, may i suggest using a label instead) with the ever increasing time using NSThread or NSTimer - i recommend NSThread. you will also need to perform your updates on your ui thread as updating your ui from a background thread can just get lost in the post.
store the end time in applicationWillTerminate: in your application delegate using NSUserDefaults
lots of googling ahead of you, have fun!