在iPhone模拟器上测试CoreLocation

29

更新:自iOS 5和Xcode 4.1以来,现在可以在模拟器中测试位置甚至定义路线。有关更多详细信息,请参见http://developer.apple.com

遗留问题

有没有办法在iPhone模拟器上测试CoreLocation?

我只需要能够自己设置位置并让CoreLocation返回它。

8个回答

20

这是我的一个简单的技巧,可以强制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

18

非常感谢您提供的优秀反馈,这促使我找到了一个强大的解决方案。

所有代码都可以在这里找到:

http://code.google.com/p/dlocation/

虽然代码看起来很混乱,但随着我使用它,它会变得更好。

解决方案是子类化CLLocationManager并定义一个新的代理@protocol,名为DLocationManagerDelegate

它旨在成为CLLocationManagerDelegate的简单插入替换,编译后在实际设备上部署时变成一个非常薄层。

在设备上运行时,它将像平常一样使用CoreLocation返回数据,但在模拟器中,它将从文本文件(在DLocationManager.h文件中定义)中读取纬度和经度。

希望这能有所帮助,实现比较简单,您需要startUpdatingLocationstopUpdatingLocation来更新显示。

期待您的评论和反馈。


提供的链接对我来说无效。最终我通过子类化CLLocationManager编写了自己的模拟器。我在这里放了一个github上的副本 - progrmr
2
请查看我的答案。我已经开源了FTLocationSimulator,它从Google Earth生成的KML文件中读取位置更新。它还会更新MKMapView中蓝色用户位置点。 - Ortwin Gentz
试试这个:http://code.google.com/p/dlocation/source/browse/#svn%2Ftrunk%2FDeviceLocation - Richard Stelling

13

使用过滤函数在模拟器上运行时切换到测试实例。无论您以前从哪里接收位置(委托调用等),都通过此函数传递:

+ (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
}

撇开内存管理问题不谈...


4
只是出于好奇,你是如何在2009年4月了解wakkawakka的? - Raj Pawan Gumdal
我不确定你的意思,wakkawakka 有什么特殊含义吗?我只是用了一个无意义的短语。 :) - Nick Veys
据我所知,这是Shakira的歌曲,她在2010年非洲世界杯上签售了它。 - fyasar
2
哦,哇。 它实际上来自于一只木偶角色:http://en.wikipedia.org/wiki/Fozzie_Bear完全不同的意思,因为它没有任何意义。 :) - Nick Veys

9

我认为在这里有比像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协议将其“推送”到委托。


2

locationManager:didUpdateToLocationlocationManager:didFailedWithError这两个重载回调在iPhone模拟器中从未被调用,这有点奇怪,我得到的位置是纬度0.0000,经度0.0000。如果你开发一些东西,在模拟器环境下只能很难实现所有可能发生的位置处理情况。


2

我在我的项目中使用了你的示例,它非常好用,谢谢! - fyasar

2

如果您需要设置一个不同于模拟器提供的位置,请从测试类触发Core Location回调。


1

在 iPhone 模拟器上测试 CoreLocation

1) 要在模拟器中测试位置,最好的方法是使用 GPX 文件,只需转到文件 -> 新建 -> 资源 -> GPX 文件。

2) 添加 GPX 文件后,根据需要更新位置坐标。

3) 一旦将 GPX 文件添加到项目中,请选择 Scheme -> 编辑 Scheme -> 运行 -> 允许位置模拟。勾选位置模拟并选择刚创建的 GPX 文件的名称。

这样,模拟器将始终选择我们在 GPX 文件中添加的所需坐标。

Create the GPX file


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接