[英]Location Services not working in background called by WatchKit
我的Apple Watch应用程序需要一些数据并从相应的iPhone应用程序请求它。 要满足请求,iPhone应用程序需要用户位置。 在使用真正的Apple Watch接收和测试后,我发现我的iPhone应用程序在后台运行时没有收到位置更新。 如果iPhone应用程序在前台处于活动状态,则可以正常运行。 使用模拟器,它在两种情况下都有效。
在这两种情况下(活动和后台),WatchKit扩展程序会成功调用并启动iPhone应用程序并一直运行,直到在iPhone应用程序中调用startUpdatingLocation。 但是,如果应用程序在后台运行,则永远不会调用didUpdateLocations。
我尝试使用requestAlwaysAuthorization以及requestWhenInUseAuthorization。 没有不同。 我还激活了功能内的“位置更新”后台模式。 但再没有区别。
有其他人遇到同样的问题,并找到了在后台接收位置的方法吗?
这里有一些代码。 首先检查是否需要授权。
// iOS 8 check to avoid crash on older iOS
if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)])
{
[self requestLocationAlwaysAuthorization];
}
else
{
[self runLocationUpdate];
}
在这里检查正确的位置管理器权限。
- (void)requestLocationAlwaysAuthorization
{
CLAuthorizationStatus currentAuthStatus = [CLLocationManager authorizationStatus];
if (currentAuthStatus == kCLAuthorizationStatusDenied)
{
//request user to change setting
}
else if (currentAuthStatus == kCLAuthorizationStatusRestricted)
{
//request user to change setting
}
else if (currentAuthStatus == kCLAuthorizationStatusNotDetermined)
{
[self.locationManager requestAlwaysAuthorization];
[self runLocationUpdate];
}
else if (currentAuthStatus == kCLAuthorizationStatusAuthorizedWhenInUse)
{
//maybe when in use is also enough?
[self runLocationUpdate];
}
else if (currentAuthStatus == kCLAuthorizationStatusAuthorizedAlways)
{
//all ok
[self runLocationUpdate];
}
}
这里调用startUpdatingLocation。 只有在iPhone应用程序处于活动状态时才会调用didUpdateLocations委托。
-(void)runLocationUpdate
{
[self.locationManager startUpdatingLocation];
}
要检查和注意的三件事:
位置权限如[self.locationManager requestAlwaysAuthorization];
仅由操作系统确认一次。 如果您已经请求了权限,则无论级别如何,操作系统都不会向用户显示请求。 操作系统将仅传递请求并保留权限级别。 只有当[CLLocationManager authorizationStatus]
返回kCLAuthorizationStatusNotDetermined
时,才能确定OS将向用户显示请求的唯一时间。 在所有其他情况下,您必须通过显示警报或其他形式的UI显示来手动请求权限。 另请注意,即使您删除了应用并重新安装,操作系统仍会保留其是否已显示请求。 因此,要进行测试,您需要重置模拟器的内容或iPhone的位置隐私。
确保已为NSLocationAlwaysUsageDescription
和NSLocationWhenInUseUsageDescription
添加了plist密钥如果不将其添加到plist,操作系统将忽略任何位置权限请求。
如果您想在手机应用程序处于后台时使用requestAlwaysAuthorization
从手机(而不是手表应用程序扩展程序)获取位置数据,还需要在Project> Target> Capabilities下注册后台模式位置更新。
更新使用后台任务为您的应用程序提供在后台进行响应的时间。 像这样的东西:
-(void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void (^)(NSDictionary *replyInfo))reply{
UIApplication *app = [UIApplication sharedApplication];
UIBackgroundTaskIdentifier bgTask __block = [app beginBackgroundTaskWithName:@"watchAppRequest" expirationHandler:^{
[[UIApplication sharedApplication] endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
//make your calls here to your tasks, when finished, send the reply then terminate the background task
//send reply back to watch
reply(replyInfo);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2.0 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
[app endBackgroundTask:bgTask];
bgTask=UIBackgroundTaskInvalid;
});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.