我想知道用户何时在我家附近。 我正在使用CoreLocation,并希望始终知道用户是否在我家附近(大约100米),即使该应用已关闭。
为此,我成功地在我的代码中知道用户是否在100米左右(CLRegionStateInside
)。 DidEnterRegion
和DidExitRegion
也可以。我使用kCLAuthorizationStatusAuthorizedAlways
来本地化用户。
我想节省电池寿命,所以我在用户制作3公里后添加了self.locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers;
来更新位置。
告诉我如何才能节省更多的电池续航时间,即使应用程序处于后台/关闭状态(也许我还要更改AppDelegate中的内容),如何更新位置?
我想知道我的代码是否符合我的需求?
这是我的代码:
#import "ViewController.h"
@import UserNotifications;
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
// Request Notification
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert)
completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (!error) {
NSLog(@"request authorization succeeded!");
}
}];
}
- (void)setUpGeofences {
CLLocationCoordinate2D center = CLLocationCoordinate2DMake(49.451096,
1.095425);
CLCircularRegion *region = [[CLCircularRegion alloc] initWithCenter:center
radius:100.0
identifier:@"Home"];
[self.locationManager startMonitoringForRegion:region];
self.locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers;
self.locationManager.allowsBackgroundLocationUpdates = YES;
}
- (void)showSorryAlert {
UIAlertController *alert = [UIAlertController
alertControllerWithTitle:@"Info"
message:@"You are using UIAlertController"
preferredStyle:UIAlertControllerStyleAlert];
[self presentViewController:alert animated:YES completion:nil];
}
- (void)locationManager:(CLLocationManager *)manager
didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
switch (status) {
case kCLAuthorizationStatusNotDetermined:
[self.locationManager requestAlwaysAuthorization];
break;
case kCLAuthorizationStatusAuthorizedWhenInUse:
[self.locationManager startUpdatingLocation];
[self setUpGeofences];
break;
case kCLAuthorizationStatusAuthorizedAlways:
[self.locationManager startUpdatingLocation];
[self setUpGeofences];
break;
case kCLAuthorizationStatusRestricted:
// restricted by e.g. parental controls. User can't enable Location Services
break;
case kCLAuthorizationStatusDenied:
// user denied your app access to Location Services, but can grant access from Settings.app
break;
default:
break;
}
}
- (void)locationManager:(CLLocationManager *)manager
didEnterRegion:(CLRegion *)region {
NSLog(@"didEnter : %@", region);
[self displayNotif:@"Bienvenue !" withBody:@"Passez nous voir !"];
}
- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region {
[self displayNotif:@"Au revoir !" withBody:@"A bientôt !"];
}
- (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region {
NSLog(@"Start monitoring for region: %@", region.identifier);
[self.locationManager requestStateForRegion:region];
}
- (void)locationManager:(CLLocationManager *)manager monitoringDidFailForRegion:(CLRegion *)region withError:(NSError *)error {
NSLog(@"Error: %@", error);
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations {
NSLog(@"NEW LOCATION");
// Stop location updates when they aren't needed anymore
[self.locationManager stopUpdatingLocation];
// Disable background location updates when they aren't needed anymore
self.locationManager.allowsBackgroundLocationUpdates = NO;
}
- (void)locationManager:(CLLocationManager *)manager
didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region {
// When regions are initialized, see if we are already within the geofence.
switch (state) {
case CLRegionStateInside: [self displayNotif:@"Bienvenue" withBody:@"Passez nous voir !"];
break;
case CLRegionStateUnknown: NSLog(@"Unknown");
case CLRegionStateOutside: NSLog(@"Outside");
default: break;
}
}
- (void)displayNotif:(NSString *)title withBody:(NSString *)body {
UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
content.title = [NSString localizedUserNotificationStringForKey:title arguments:nil];
content.body = [NSString localizedUserNotificationStringForKey:body
arguments:nil];
content.sound = [UNNotificationSound defaultSound];
/// 4. update application icon badge number
content.badge = @([[UIApplication sharedApplication] applicationIconBadgeNumber] + 1);
// Deliver the notification in five seconds.
UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger
triggerWithTimeInterval:1.f repeats:NO];
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:@"OneSecond"
content:content trigger:trigger];
/// 3. schedule localNotification
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
if (!error) {
NSLog(@"add NotificationRequest succeeded!");
}
}];
}
@end
答案 0 :(得分:1)
关于您在后台进行监控的问题,请参阅Apples文档,其中说明了以下内容:
如果在应用未运行时越过区域边界,则会将该应用重新启动到后台以处理该事件。同样,如果应用程序在事件发生时被暂停,它会被唤醒,并且会花费很短的时间(大约10秒)来处理事件。
这意味着,只要您的authorizationStatus被设置为.AdentifiedAlways那么剩下的就会自动处理它。