2016-08-20 2 views
2

Я работаю на Geofencing, и я хочу, чтобы вызвать «didEnterRegion» и «didExitRegion» он работает, когда приложение находится на переднем плане или в фоновом состоянии. Но я хочу вызвать его, когда приложение также неактивно. Мой код следующим образом:Geofencing в прошивке Когда приложение закрыто/Погибе

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 Button и закрыть приложение от задачи, то Geofencing не работает может кто-нибудь помочь я для достижения этой цели.

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

Заранее благодарен !!!!!

+0

Да. Не используйте двойное нажатие и убивайте приложение. Если вы это сделаете, он сообщает iOS, что вы не хотите, чтобы приложение запускалось. – Paulw11

+0

Итак, если приложение находится в состоянии InActive, это не вызовет его в любом случае? –

+0

Если он приостановлен (просто нажмите кнопку «Домой» и перейдите в другое приложение), вы получите уведомления о регионе, но не прекратите приложение. Однако вы делаете некоторые странные вещи в своем коде.Вы должны либо запрашивать при использовании, либо всегда авторизацию, а не обе (в вашем случае вы всегда хотите), и вы не хотите начинать обновление местоположений или точную точность; что убьет батарею – Paulw11

ответ

1

Извините, но немного отличается: (ADC SITE)

Если оставить значащего изменения хода службы местоположение и ваш IOS приложение впоследствии приостановлено или прекращено, служба автоматически просыпается ваш при появлении новых данных о местоположении. При время пробуждения приложение помещается в фоновое изображение, и вам предоставляется небольшое количество времени (около 10 секунд) для ручного перезапуска местоположения услуг и обработки данных о местоположении. (Вы должны вручную перезапустить службы определения местоположения в фоновом режиме, прежде чем незавершенное место обновления может быть доставлены, как описаны в Познаниях Когда начинать Location Services.)

Так IOS пробудит ваше приложение, но вы должны: 1) создать экземпляр NEW CLLocationManager 2) подождать 'до первого вызова назад для использования geoloc

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

+0

Спасибо ingconti Я пытаюсь это сделать, но не могу сделать. Можете ли вы предоставить мне пример кода для вышеуказанного решения или любую ссылку для ссылки. –

+0

код для местных уведомлений или гель для значительных местОбъекты? PLS пишите на май почта. – ingconti

+0

привет @ingconti вы можете поделиться примером кода. – ChanWarde

Смежные вопросы