2016-08-20 84 views
2

我工作的區域範圍設定,我想觸發「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上測試此功能。

在此先感謝!!!!!

+0

是的。不要雙擊並殺死應用程序。如果你這樣做,它告訴iOS,你不希望應用程序運行 – Paulw11

+0

因此,如果應用程序處於InActive狀態,它不會觸發它在任何情況下? –

+0

如果它被暫停(只需按主頁按鈕並轉到另一個應用程序),那麼你會得到區域通知,但不是如果你終止應用程序。儘管你在代碼中做了一些奇怪的事情。您應該要求在使用或總是授權時,而不是兩者都要(總是需要您的情況),並且您不想開始更新位置或最佳準確性;那會殺死電池 – Paulw11

回答

1

很抱歉,但有一點不同: (ADC SITE)

如果離開了顯著變化位置服務運行,您 iOS應用隨後被暫停或終止,服務 自動喚醒你的當新的位置數據到達時應用程序。在 喚醒時間,該應用程序被置於後臺,並且您會得到一個短時間(大約10秒)的 手動重新啓動位置 服務並處理位置數據。 (您必須手動任何未決的位置 更新可交付之前重新啓動在後臺 位置服務,在知行描述的時候開始 位置服務)。

那麼,iOS將喚醒你的應用程序,但你必須: 1)實例化一個新的CLLocationManager 2)等待'直到第一次回電才能使用geoloc

筆記ADC狀態,你將在後臺運行,所以或者如果你需要用戶把它放在前臺使用本地通知。

+0

Thanks ingconti我正在嘗試做,但無法做到。您能否爲我提供上述解決方案的示例代碼或任何參考鏈接。 –

+0

本地通知的代碼或用於significantLocationUpdates的geloc代碼? 請寫郵件。 – ingconti

+0

你好@ingconti請你分享示例代碼。 – ChanWarde

相關問題