核心位置不适用于 Apple Watch
Core Location doesn't work with Apple watch
我有一个如下所示的 GPX 文件:
<?xml version="1.0" encoding="UTF-8"?>
<gpx
version="1.0"
creator="GPSBabel - http://www.gpsbabel.org"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.topografix.com/GPX/1/0"
xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd">
<time>2015-04-03T15:04:33Z</time>
<bounds minlat="32.994533333" minlon="35.573600000" maxlat="33.176883333" maxlon="35.630866667"/>
<trk>
<name>GNSSALTTRK</name>
<desc>IGCHDRS~HFFXA035~HFPLTPILOTINCHARGE: pilot~HFCM2CREW2: not recorded~HFGTYGLIDERTYPE:unknown~HFGIDGLIDERID:unknown~HFDTM100GPSDATUM: WGS-1984~HFRFWFIRMWAREVERSION: 1.00~HFRHWHARDWAREVERSION: 2012~HFFTYFRTYPE: ParaWind by Dr. Edgar Bolender~HFGPSGPS:Smartphone~HFPRSPRESSALTSENSOR: Smartphone~HFCIDCOMPETITIONID:~HFCCLCOMPETITIONCLASS:~</desc>
<trkseg>
<trkpt lat="33.060316667" lon="35.625166667">
<ele>88.000000</ele>
<time>2014-08-23T03:58:58Z</time>
</trkpt>
<trkpt lat="33.061700000" lon="35.624750000">
<ele>81.000000</ele>
<time>2014-08-23T03:59:11Z</time>
</trkpt>
<trkpt lat="33.062650000" lon="35.624250000">
<ele>83.000000</ele>
<time>2014-08-23T03:59:21Z</time>
</trkpt>
<trkpt lat="33.064316667" lon="35.624033333">
<ele>88.000000</ele>
<time>2014-08-23T03:59:37Z</time>
</trkpt>
<trkpt lat="33.065833333" lon="35.623866667">
<ele>86.000000</ele>
<time>2014-08-23T03:59:51Z</time>
</trkpt>
<trkpt lat="33.066983333" lon="35.623500000">
<ele>84.000000</ele>
<time>2014-08-23T04:00:02Z</time>
</trkpt>
....
我将它添加到当前方案并 运行 它但位置没有变化。
我怀疑它与旧的 timeTags 有关,但即使将系统时间更改为相关的 GPX 文件时间,它也没有触发位置事件。
现在我怀疑我的模型有问题,因为应用程序不要求用户使用位置(它是 Apple Watch 的应用程序)
#import "LocationModel.h"
#import <CoreLocation/CoreLocation.h>
@interface LocationModel ()<CLLocationManagerDelegate>
@property (nonatomic, strong) CLLocationManager* locationManager;
@end
@implementation LocationModel
static LocationModel* sharedInstance;
@synthesize locationManager;
#pragma mark - private
- (void)startStandardUpdates
{
// Create the location manager if this object does not
// already have one.
if (nil == locationManager)
{
locationManager = [[CLLocationManager alloc] init];
}
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
// Set a movement threshold for new events.
locationManager.distanceFilter = 1; // meters
[locationManager startUpdatingLocation];
// Start heading updates.
if ([CLLocationManager headingAvailable]) {
locationManager.headingFilter = 5;
[locationManager startUpdatingHeading];
}
}
#pragma mark - CLLocationManagerDelegate
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations {
// If it's a relatively recent event, turn off updates to save power.
CLLocation* location = [locations lastObject];
NSDate* eventDate = location.timestamp;
NSTimeInterval howRecent = [eventDate timeIntervalSinceNow];
if (abs(howRecent) < 15.0) {
// If the event is recent, do something with it.
NSLog(@"latitude %+.6f, longitude %+.6f\n",
location.coordinate.latitude,
location.coordinate.longitude);
}
}
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading {
if (newHeading.headingAccuracy < 0)
return;
// Use the true heading if it is valid.
CLLocationDirection theHeading = ((newHeading.trueHeading > 0) ?
newHeading.trueHeading : newHeading.magneticHeading);
NSLog(@"Heading changed: %f", theHeading);
//self.currentHeading = theHeading;
//[self updateHeadingDisplays];
}
#pragma mark - Init
-(id)init
{
self = [super init];
if (self) {
[self startStandardUpdates];
}
return self;
}
#pragma mark - public
+(LocationModel*)getSharedInstance
{
if(!sharedInstance)
{
sharedInstance = [[LocationModel alloc] init];
}
return sharedInstance;
}
+(void)myInit
{
sharedInstance = [[LocationModel alloc] init];
}
@end
我只是从 interfaceController 的 awakeWithContext 调用 myInit
Core Location 需要在 ios 应用中实现,而不是在扩展中实现(如 documentation 中所述)。
另一件事,在 IOS8 中,您应该在调用 startUpdatingLocation 之前调用 requestWhenInUseAuthorization。
// 检查 iOS 8. 如果没有这个守卫,代码将在 iOS 7 上因 "unknown selector" 而崩溃。
如果 ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
[self.locationManager requestAlwaysAuthorization];
}
关于 GPX 文件 - 模拟器似乎不喜欢它。就是玩不了。
我有一个如下所示的 GPX 文件:
<?xml version="1.0" encoding="UTF-8"?>
<gpx
version="1.0"
creator="GPSBabel - http://www.gpsbabel.org"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.topografix.com/GPX/1/0"
xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd">
<time>2015-04-03T15:04:33Z</time>
<bounds minlat="32.994533333" minlon="35.573600000" maxlat="33.176883333" maxlon="35.630866667"/>
<trk>
<name>GNSSALTTRK</name>
<desc>IGCHDRS~HFFXA035~HFPLTPILOTINCHARGE: pilot~HFCM2CREW2: not recorded~HFGTYGLIDERTYPE:unknown~HFGIDGLIDERID:unknown~HFDTM100GPSDATUM: WGS-1984~HFRFWFIRMWAREVERSION: 1.00~HFRHWHARDWAREVERSION: 2012~HFFTYFRTYPE: ParaWind by Dr. Edgar Bolender~HFGPSGPS:Smartphone~HFPRSPRESSALTSENSOR: Smartphone~HFCIDCOMPETITIONID:~HFCCLCOMPETITIONCLASS:~</desc>
<trkseg>
<trkpt lat="33.060316667" lon="35.625166667">
<ele>88.000000</ele>
<time>2014-08-23T03:58:58Z</time>
</trkpt>
<trkpt lat="33.061700000" lon="35.624750000">
<ele>81.000000</ele>
<time>2014-08-23T03:59:11Z</time>
</trkpt>
<trkpt lat="33.062650000" lon="35.624250000">
<ele>83.000000</ele>
<time>2014-08-23T03:59:21Z</time>
</trkpt>
<trkpt lat="33.064316667" lon="35.624033333">
<ele>88.000000</ele>
<time>2014-08-23T03:59:37Z</time>
</trkpt>
<trkpt lat="33.065833333" lon="35.623866667">
<ele>86.000000</ele>
<time>2014-08-23T03:59:51Z</time>
</trkpt>
<trkpt lat="33.066983333" lon="35.623500000">
<ele>84.000000</ele>
<time>2014-08-23T04:00:02Z</time>
</trkpt>
....
我将它添加到当前方案并 运行 它但位置没有变化。 我怀疑它与旧的 timeTags 有关,但即使将系统时间更改为相关的 GPX 文件时间,它也没有触发位置事件。
现在我怀疑我的模型有问题,因为应用程序不要求用户使用位置(它是 Apple Watch 的应用程序)
#import "LocationModel.h"
#import <CoreLocation/CoreLocation.h>
@interface LocationModel ()<CLLocationManagerDelegate>
@property (nonatomic, strong) CLLocationManager* locationManager;
@end
@implementation LocationModel
static LocationModel* sharedInstance;
@synthesize locationManager;
#pragma mark - private
- (void)startStandardUpdates
{
// Create the location manager if this object does not
// already have one.
if (nil == locationManager)
{
locationManager = [[CLLocationManager alloc] init];
}
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
// Set a movement threshold for new events.
locationManager.distanceFilter = 1; // meters
[locationManager startUpdatingLocation];
// Start heading updates.
if ([CLLocationManager headingAvailable]) {
locationManager.headingFilter = 5;
[locationManager startUpdatingHeading];
}
}
#pragma mark - CLLocationManagerDelegate
- (void)locationManager:(CLLocationManager *)manager
didUpdateLocations:(NSArray *)locations {
// If it's a relatively recent event, turn off updates to save power.
CLLocation* location = [locations lastObject];
NSDate* eventDate = location.timestamp;
NSTimeInterval howRecent = [eventDate timeIntervalSinceNow];
if (abs(howRecent) < 15.0) {
// If the event is recent, do something with it.
NSLog(@"latitude %+.6f, longitude %+.6f\n",
location.coordinate.latitude,
location.coordinate.longitude);
}
}
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading {
if (newHeading.headingAccuracy < 0)
return;
// Use the true heading if it is valid.
CLLocationDirection theHeading = ((newHeading.trueHeading > 0) ?
newHeading.trueHeading : newHeading.magneticHeading);
NSLog(@"Heading changed: %f", theHeading);
//self.currentHeading = theHeading;
//[self updateHeadingDisplays];
}
#pragma mark - Init
-(id)init
{
self = [super init];
if (self) {
[self startStandardUpdates];
}
return self;
}
#pragma mark - public
+(LocationModel*)getSharedInstance
{
if(!sharedInstance)
{
sharedInstance = [[LocationModel alloc] init];
}
return sharedInstance;
}
+(void)myInit
{
sharedInstance = [[LocationModel alloc] init];
}
@end
我只是从 interfaceController 的 awakeWithContext 调用 myInit
Core Location 需要在 ios 应用中实现,而不是在扩展中实现(如 documentation 中所述)。 另一件事,在 IOS8 中,您应该在调用 startUpdatingLocation 之前调用 requestWhenInUseAuthorization。
// 检查 iOS 8. 如果没有这个守卫,代码将在 iOS 7 上因 "unknown selector" 而崩溃。 如果 ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) { [self.locationManager requestAlwaysAuthorization]; }
关于 GPX 文件 - 模拟器似乎不喜欢它。就是玩不了。