Геозоны в iOS, когда приложение закрыто / убито

ios objective-c iphone xcode7

1437 просмотра

1 ответ

Я работаю над геозоной и хочу вызвать «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
}

Приведенный выше код работает нормально, если приложение находится в фоновом режиме или на переднем плане, но если я дважды коснусь кнопки «Домой» и закрою приложение из задачи, тогда не работает геозонное ограничение, кто-нибудь может помочь мне достичь этой цели.

Примечание: я использую XCode 7.3.1 и iOS 9.3, пока тестирую это на iPhone 5s.

Заранее спасибо !!!!!

Автор: Mohammad Ashraf Ali Источник Размещён: 08.11.2019 11:15

Ответы (1)


1 плюс

Извините, но немного по-другому: (ADC SITE)

Если вы оставляете службу определения местоположения с существенными изменениями и ваше приложение iOS впоследствии приостанавливается или прекращает работу, служба автоматически активирует ваше приложение, когда поступают новые данные о местоположении. Во время пробуждения приложение переводится в фоновый режим, и у вас есть небольшое количество времени (около 10 секунд), чтобы вручную перезапустить службы определения местоположения и обработать данные о местоположении. (Вы должны вручную перезапустить службы определения местоположения в фоновом режиме, прежде чем будут доставлены ожидающие обновления местоположения, как описано в разделе «Знание, когда запускать службы определения местоположения».)

Так что iOS разбудит ваше приложение, НО вы должны: 1) создать новый CLLocationManager 2) подождать до первого обратного вызова для использования geoloc

отмечает, что ADC сообщает, что вы будете работать в фоновом режиме, например, используйте локальное уведомление, если вам нужно, чтобы пользователь поместил его на передний план.

Автор: ingconti Размещён: 20.08.2016 01:15
Вопросы из категории :
32x32