iOS中的地理围栏当应用程序关闭/杀死时

时间:2016-08-20 11:37:45

标签: ios objective-c iphone xcode7

我正在制作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
}

如果应用程序处于后台或前台,上面的代码工作正常但如果我双击主页按钮并从任务关闭应用程序然后地理围栏无法正常工作可以帮助我实现此目标

注意:当我在iPhone 5s上测试时,我正在使用XCode 7.3.1和iOS 9.3。

提前致谢!!!!!

1 个答案:

答案 0 :(得分:1)

抱歉,但有点不同: (ADC网站)

  

如果您让重要更改位置服务正在运行并且您正在运行   iOS应用程序随后被暂停或终止,该服务   新位置数据到达时自动唤醒您的应用。在   唤醒时间,应用程序被放入后台,你得到一个   少量时间(约10秒)手动重启位置   服务和处理位置数据。 (您必须手动重启   在任何待定位置之前的后台位置服务   可以提供更新,如了解何时开始   位置服务。)

所以iOS会唤醒你的应用但是你必须: 1)实例化一个新的CLLocationManager 2)等到第一次回叫使用geoloc

注意ADC状态,您将在后台运行,因此或示例如果您需要用户将其置于前台,请使用本地通知。