更新:自iOS 5和Xcode 4.1以来,现在可以在模拟器中测试位置甚至定义路线。有关更多详细信息,请参见http://developer.apple.com。
遗留问题
有没有办法在iPhone模拟器上测试CoreLocation?
我只需要能够自己设置位置并让CoreLocation返回它。
更新:自iOS 5和Xcode 4.1以来,现在可以在模拟器中测试位置甚至定义路线。有关更多详细信息,请参见http://developer.apple.com。
有没有办法在iPhone模拟器上测试CoreLocation?
我只需要能够自己设置位置并让CoreLocation返回它。
这是我的一个简单的技巧,可以强制CLLocationManager仅在模拟器上返回Powell's Tech Bookstore的地理坐标:
#ifdef TARGET_IPHONE_SIMULATOR
@interface CLLocationManager (Simulator)
@end
@implementation CLLocationManager (Simulator)
-(void)startUpdatingLocation {
CLLocation *powellsTech = [[[CLLocation alloc] initWithLatitude:45.523450 longitude:-122.678897] autorelease];
[self.delegate locationManager:self
didUpdateToLocation:powellsTech
fromLocation:powellsTech];
}
@end
#endif // TARGET_IPHONE_SIMULATOR
非常感谢您提供的优秀反馈,这促使我找到了一个强大的解决方案。
所有代码都可以在这里找到:
http://code.google.com/p/dlocation/
虽然代码看起来很混乱,但随着我使用它,它会变得更好。
解决方案是子类化CLLocationManager
并定义一个新的代理@protocol
,名为DLocationManagerDelegate
。
它旨在成为CLLocationManagerDelegate
的简单插入替换,编译后在实际设备上部署时变成一个非常薄层。
在设备上运行时,它将像平常一样使用CoreLocation
返回数据,但在模拟器中,它将从文本文件(在DLocationManager.h文件中定义)中读取纬度和经度。
希望这能有所帮助,实现比较简单,您需要startUpdatingLocation
和stopUpdatingLocation
来更新显示。
期待您的评论和反馈。
使用过滤函数在模拟器上运行时切换到测试实例。无论您以前从哪里接收位置(委托调用等),都通过此函数传递:
+ (CLLocation *) wakkawakka: (CLLocation*) loc {
#ifdef TARGET_IPHONE_SIMULATOR
/* replace with a test instance */
return [[CLLocation alloc] initWithLatitude:10.0 longitude:20.0];
#else
return loc;
#endif
}
撇开内存管理问题不谈...
我认为在这里有比像http://code.google.com/p/dlocation/中的CLLocationManager子类化更好的方法(仅个人意见)。在ObjectiveC中,似乎可以用“方法交换”的方式替换现有类的现有方法。你可以为现有类定义自己的分类,并在其中实现现有方法。
从客户端的角度来看,一切都是透明的:他觉得自己正在处理真正的CLLocationManager
,但实际上,你已经“接管了它”。因此,他不需要处理任何特殊的子类或任何特殊的代理协议:他继续使用与CoreLocation相同的类/协议。
Here's an example to took the control over the delegate a client would inject :
@implementation CLLocationManager (simulator)
-(void) setDelegate:(id)delegate { //实现自己的setDelegate方法... } -(id)delegate { //实现自己的delegate方法.... } -(void)startUpdatingLocation { } -(void)stopUpdatingLocation { } //.... //对于标准CLLocationManager中的其余任何方法,同样适用 @end
在此实现中,您可以自由地处理预定义的一组坐标(来自文件或其他任何来源),并使用标准的CLLocationManagerDelegate
协议将其“推送”到委托。
locationManager:didUpdateToLocation和locationManager:didFailedWithError这两个重载回调在iPhone模拟器中从未被调用,这有点奇怪,我得到的位置是纬度0.0000,经度0.0000。如果你开发一些东西,在模拟器环境下只能很难实现所有可能发生的位置处理情况。
如果您需要设置一个不同于模拟器提供的位置,请从测试类触发Core Location回调。
MKMapView
中蓝色用户位置点。 - Ortwin Gentz