我正在处理地理围栏,我想触发"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
}
如果应用程序在后台或前台运行,上述代码可以正常工作,但是如果我双击 Home 按钮并从任务中关闭应用程序,则地理围栏不起作用。有人能帮助我实现这个目标吗。
注意:我正在使用 XCode 7.3.1 和 iOS 9.3,在 iPhone 5s 上测试。
提前感谢!!!!