iOSclosures/closures应用程序时进行Geofencing

我正在Geofencing上工作,当应用处于前景或背景状态时,我想触发它​​正在工作的“didEnterRegion”“didExitRegion” 。 但是我也想在应用程序处于非活动状态时触发它。 我的代码如下:

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 } 

上述代码工作正常,如果应用程序是在后台或前台,但如果我双击主页button ,closures应用程序从任务,然后geofencing不工作可以帮助我实现这一目标。

注:我正在使用XCode 7.3.1和iOS 9.3,而我正在iPhone 5s上进行testing。

提前致谢 !!!!!

对不起,但有点不同:(ADC SITE)

如果您将重大更改的位置服务保持运行,并且您的iOS应用程序随后被暂停或终止,那么当新的位置数据到达时,服务会自动唤醒您的应用程序。 在起床时,应用程序将被放置在后台,您将得到一小段时间(大约10秒钟)以手动重新启动位置服务并处理位置数据。 (如“了解何时启动位置服务”中所述,您必须在可以传递任何待定位置更新之前手动重新启动位置服务。

所以iOS会唤醒你的应用程序,但是你必须:1)实例化一个新的CLLocationManager 2)等待'直到第一次callback使用geoloc

注意ADC的状态,你将在后台运行,所以或者如果你需要用户把它放在前台,使用本地通知。