When CLLocationManagerDelegate methods are called? - objective-c

I am using iOS8 and trying to track location(latitude and longitude) values. I needed clarification about when CLLocationManagerDelegate methods are called.
1)Will it be called only when app is in foreground along with locationchange OR
2)Will it be called when app is in background along with locationchange OR
3)In both the above conditions.
I just wanted to know/clarification about whether - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations is called even when app is in background along with locationchange OR only when app is in foreground along with locationchange OR in both conditions?
I have not enabled Location Updates Background Modes.I am using iOS8 and made necessary changes for location updates following the link.Using NSLocationAlwaysUsageDescription in my Info.plist.

Assuming that you asked the user for location permission (you have NSLocationAlwaysUsageDescription or NSLocationWhenInUseDescription keys in your info.plist) then didUpdateLocations is:
Always called when the app is in foreground mode
NOT called when the application is in background unless you enabled the background location mode.

Related

How to detect and implement touch events for single tap on home button?

Not sure if it is possible but is there any way to detect a single touch on the home button. To start with, I would simply like to add an NSLog if the user touches down once on the home button (without actually pressing), but I don't know where I would add this functionality. Does Apple allow you to interact with the home button?
I looked at the app delegate methods, but I can't see how any would work in a single tap (touch) context. Would really appreciate your help.
Does Apple allow you to interact with the home button?
No, not yet. There are no APIs available to explicitly detect home button interactions.
You can rely on the traditional app delegate lifecycle function invocations to perform any logic you wanted to.
- (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.
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillTerminate:(UIApplication *)application
{
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}

How to Monitor Location in Background in iOS?

I am currently writing a home automation app for a client which will open their garage, turn on the living room and office lights, and other such things when they arrive within 150 meters of their home. It will do the opposite when they leave. I am very grateful that geofencing is built into iOS, and the feature works perfectly when the app is in the foreground, but when the user closes the app, and the phone is still monitoring a geofence, the app does nothing when an event occurs. Is there a separate method other than locationManager:didEnterRegion: that I should be implementing for background notifications to my app? Here is the code that I am using right now:
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region {
NSLog(#"Entered Region - %#", region.identifier);
[self showRegionAlert:#"Entering Region" forRegion:region.identifier];
[self sendCommand:true];
}
- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region {
NSLog(#"Exited Region - %#", region.identifier);
[self showRegionAlert:#"Exiting Region" forRegion:region.identifier];
[self sendCommand:false];
}
To use location services while your app is in the background you need to change your app's info plist file. Should be found in Supporting Files folder and look like this, YourAppName-Info.plist
Add an item to the Information Property List and type in Required Background Modes as the key, which is of type Array. Add an item to that array and type in App registers for location updates into the value of that item.
I discovered it was a non-issue. It all works exactly the same way as if the app were active. The same method is called. I made sure to optimize the app for background launch though so that it would be more of an instant response. I guess I was doing something wrong though, or it just wasn't working at first.
Turn on BackgroundModes in Target Settings/Capabilities and enable Location Updates. Since app is in background, you will get little time for processing and the app will move to sleep mode. Use expirationHandler make app active for some more time for doing large processing.

UIViewController visible callback

I am developing an iOS application where need to do some stuff when I have Internet connection and other, when I haven't. If I haven't at some point I will show a message to the user to give me internet and come back. The question it is how to detect the following situation:
the user press the Home button twice, goes to multitasking , Settings and will connect to internet
the user comes back with multitasking to my app, but doesn't press anything
I know I will get callbacks to the AppDelegate:
- (void)applicationDidEnterBackground:(UIApplication *)application
- (void) applicationDidBecomeActive:(UIApplication *)application
but the code ( it is not started by me) it is very big, and I don't want to handle there the UIViewController needs, if there is any alternative.
My UIViewController's - (void)viewDidAppear:(BOOL)animated it isn't called when the user came back.
The breakpoint it is not hited for sure!
Any usable ideas, except in AppDelegate?
You can use the notification center to listen to applicationDidEnterBackground within the view controller:
[[NSNotificationCenter defaultCenter] addObserver: self
selector: #selector(handleEnteredBackground:)
name: UIApplicationDidEnterBackgroundNotification
object: nil];
Do this in viewDidLoad. Similarily for applicationDidBecomeActive.
Don't forget to remove yourself as an observer in viewDidUnload.
The application delegate is the correct place to be handling application state changes, but just because that is the case, it doesn't mean you must put all the logic that is triggered by the application state change in there.
Put the logic where it belongs. If it's networking code, that's not in the application delegate and it's not in the view controller, it's in a separate class. Then look into ways of tying the different parts of your application together. In most cases, notifications, KVO and the shared instance pattern are good approaches to take.

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.

Alternatives to applicationDidEnterBackground and applicationWillResignActive?

I've got an app that changes the screen brightness with [UIScreen mainScreen].brightness = newBrightness, and I want to restore the brightness to it's previous state when the user finishes using it.
I've tried these two delegate methods:
- (void)applicationDidEnterBackground:(UIApplication *)application
- (void)applicationWillResignActive:(UIApplication *)application
But without much success. I suspect my app must be in the foreground to change the brightness? When I change the brightness in didEnterBackgroundMethod, it has no effect at all. When I use willResignActive it does restore the brightness if I switch to another app, but it has no effect when I press the home button.
Are there any notifications or delegate methods that are executed before the app leaves the foreground?
It seems this happens to others as well: see this S.O. post.
Only way around it seems to be forgetting about setBrightness and simulating it by overlaying a black-semi-transparent on your view...
OLD ANSWER:
willResignActive should also be called when you press the home button before the application enters the background state.
This method is called to let your application know that it is about to move from the 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. An application in the inactive state continues to run but does not dispatch incoming events to responders.
This is also the behavior I witness. So, my guess (but it's just a guess) is that your app is not set to support background, so that when pressing the home button it is terminated. In this case applicationDidEnterBackground is not called.
I would suggest to check the info.plist file in your project for the UIApplicationExitsOnSuspend or "Select Application does not run in background" key.
Furthermore, you could try and put some breakpoints (or NSLog traces) in those functions and check whether they are effectively called as expected.
According to Apple´s DevForum it seems to be a bug that Apple don´t want to fix soon.