I am working on Geofencing and I want to trigger "didEnterRegion" and "didExitRegion" it is working when the app is in foreground or in background state. But I want to trigger it when the app is inactive state also. My code is follows:
GeofencingClass.h
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
#define IS_OS_8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
@interface GeofencingClass : NSObject <UIWebViewDelegate,UIGestureRecognizerDelegate,CLLocationManagerDelegate> {
CLLocationManager *locationManager;
NSMutableArray *geofences;
}
@property (strong, nonatomic) NSMutableArray *geofences;
@property (nonatomic,retain)CLLocationManager *locationManager;
+(void)GeofencingCoordinatesFromAPI;
+(void)StartGeoFencingWithGeoData:(NSMutableArray *)GeoDataArray;
@end
GeofencingClass.m
#import "GeofencingClass.h"
@implementation GeofencingClass
@synthesize locationManager,geofences;
+(void)GeofencingCoordinatesFromAPI {
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSInteger Parameter1 = [userDefaults integerForKey:@"Parameter1"];
NSString* Parameter2 = [userDefaults objectForKey:@"Parameter2"];
NSString* secretAgent = [userDefaults objectForKey:@"nv_secretAgent"];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
NSError *error = nil;
NSString *urlstring = [NSString stringWithFormat:@"https://geofencingapiurl.com?parm1=%ld&parm2=%@&device=ios", (long)Parameter1, Parameter2];
urlstring = [urlstring stringByReplacingOccurrencesOfString:@"(null)" withString:@""];
urlstring= [urlstring stringByAddingPercentEscapesUsingEncoding:NSISOLatin1StringEncoding];
NSURL *url = [NSURL URLWithString:urlstring];
NSMutableURLRequest* request = [[NSMutableURLRequest alloc] initWithURL:url];
[request setValue:secretAgent forHTTPHeaderField:@"User-Agent"];
NSURLResponse* response = nil;
NSData* jsonData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
if(!error) {
//NSData *jsonData = [json dataUsingEncoding:NSASCIIStringEncoding];
NSMutableDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&error];
if ([jsonDict objectForKey:@"Authentication"] && [@"success" isEqualToString:[jsonDict objectForKey:@"Authentication"]]) {
geofences = [[jsonDict valueForKey:@"geodata"] mutableCopy];
dispatch_async(dispatch_get_main_queue(), ^{
[self StartGeoFencingWithGeoData:geofences];
});
} else {
NSLog(@"Invalid authentication");
}
}
});
}
+(void)StartGeoFencingWithGeoData:(NSMutableArray *)GeoDataArray {
locationManager = [[CLLocationManager alloc]init];
// NSLog(@"GeoDataArray = %@",GeoDataArray);
if(IS_OS_8_OR_LATER) {
[locationManager requestWhenInUseAuthorization];
[locationManager requestAlwaysAuthorization];
}
locationManager.delegate = self;
[locationManager startUpdatingLocation];
locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
locationManager.distanceFilter = kCLLocationAccuracyBest;
NSLog(@"latitude: %f longitude: %f",locationManager.location.coordinate.latitude,locationManager.location.coordinate.longitude);
NSLog(@"speed: %f altitude: %f",locationManager.location.speed,locationManager.location.altitude);
for (int i = 0; i < [GeoDataArray count]; i++) {
CLLocationDegrees geo_latitude = [[[GeoDataArray objectAtIndex:i] valueForKey:@"geo_lattitude"] floatValue];
CLLocationDegrees geo_longitude = [[[GeoDataArray objectAtIndex:i] valueForKey:@"geo_longitude"] floatValue];
float Radius = [[[GeoDataArray objectAtIndex:i] valueForKey:@"geo_radius"] floatValue];
CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(geo_latitude, geo_longitude);
CLCircularRegion *region = [[CLCircularRegion alloc]initWithCenter:coordinate radius:Radius identifier:[[GeoDataArray objectAtIndex:i] valueForKey:@"geo_id"]];
[locationManager startMonitoringForRegion:region];
}
}
-(void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region {
NSLog(@"Region Monitoring has been started%@",region.identifier);
[locationManager performSelector:@selector(requestStateForRegion:) withObject:region afterDelay:2];
}
-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region {
NSLog(@"Entered in some Region %@",region.identifier);
for (int i= 0; i <[GeoData count]; i++) {
NSInteger geo_id =[[[GeoData objectAtIndex:i] valueForKey:@"geo_id"] integerValue];
if ([region.identifier integerValue] == geo_id) {
NSInteger geo_action = [[[GeoData objectAtIndex:i] valueForKey:@"geo_action"] integerValue];
if (geo_action == 0) {
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:2];
localNotification.alertBody = @"You are now Entered in a region";
localNotification.timeZone = [NSTimeZone defaultTimeZone];
localNotification.soundName = UILocalNotificationDefaultSoundName;
NSMutableDictionary *userData = [[GeoData objectAtIndex:i] mutableCopy];
localNotification.userInfo = userData;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
}
}
}
}
-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region {
NSLog(@"Exit from some Region %@",region.identifier);
for (int i= 0; i <[GeoData count]; i++) {
NSInteger geo_id =[[[GeoData objectAtIndex:i] valueForKey:@"geo_id"] integerValue];
if ([region.identifier integerValue] == geo_id) {
NSInteger geo_action = [[[GeoData objectAtIndex:i] valueForKey:@"geo_action"] integerValue];
if (geo_action == 1) {
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:2];
localNotification.alertBody = @"You are now Exit from region";
localNotification.timeZone = [NSTimeZone defaultTimeZone];
localNotification.soundName = UILocalNotificationDefaultSoundName;
NSMutableDictionary *userData = [[GeoData objectAtIndex:i] mutableCopy];
localNotification.userInfo = userData;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
}
}
}
}
-(void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region {
if (state == CLRegionStateInside){
[self AlreadyInsideRegion:region];
} else if (state == CLRegionStateOutside){
[self NotInRegion:region];
} else if (state == CLRegionStateUnknown){
NSLog(@"Unknown state for geofence: %@", region);
return;
}
}
- (void)AlreadyInsideRegion:(CLRegion *)region {
NSLog(@"Already in a Region");
}
- (void)NotInRegion:(CLRegion *)region {
NSLog(@"You are Outside from a Region");
}
@end
MYAppDelegate.h
#import <UIKit/UIKit.h>
@interface MYAppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end
MyAppDelegate.m
#import "MYAppDelegate.h"
#import "GeofencingClass.h"
@interface MYAppDelegate ()
@end
@implementation MYAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey]) {
[GeofencingClass GeofencingCoordinatesFromAPI];
}
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application {
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
[GeofencingClass GeofencingCoordinatesFromAPI];
}
- (void)applicationWillTerminate:(UIApplication *)application {
}
-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
/// Handled Deeplinking here
return YES;
}
-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
/// Registered Push Notification Here and it is working fine
}
-(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
NSLog(@"Error:%@",error);
}
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
/// Handled received Push Notification Here and it is working fine
}
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
///Handled received local push Notification Here and it is working fine
}
The above code is working fine if the app is in background or foreground but if i double tap on Home Button and close the app from task then geofencing not working can anybody help me to achieve this goal.
Note: I am using XCode 7.3.1 and iOS 9.3 while I am testing this on iPhone 5s.
Thanks in advance !!!!!
Sorry but is a bit different: (ADC SITE)
So iOS will awake your app BUT you must: 1) instantiate a NEW CLLocationManager 2) wait 'till first call back to use geoloc
notes ADC states, you will be running in background, so or example use local notification if You need the user put it in foreground.