Xcode / iOS模拟器:手动触发重大位置更改


77

有没有办法手动告诉设备发送重要的位置更改通知,该通知将唤醒为此通知注册的所有应用程序?这仅用于测试,我知道此私有API调用在提交到应用商店后会被拒绝。


1
我浏览了私有框架的头文件,但找不到类似于此触发器的任何内容。仅通过上车并带着笔记本电脑开车来进行测试并不方便。
尼克,

1
如果使用CLLocationManager didUpdateToLocation:fromLocation:委托,则可以使用startUpdatingLocation代替startMonitoringSignificantLocationChanges进行测试。如果您的GPS接收状况良好,则在CLLocationManager内未设置过滤器的情况下,几乎每秒钟都会调用didUpdateToLocation。对于测试目的,这可能会有所帮助。
托马斯,

1
实际上,测试CLLocationManager的输出与通过重大位置更改“唤醒”应用程序的生命周期一样重要。
尼克

如果您拥有Apple Dev帐户,则可能需要查看iOS5 UIAutomation。它最终可能为您提供解决方案。唯一的障碍是我不知道是否可以通过UIAutomation将程序置于后台模式。
巴尼·马托克斯

FWIW Xcode不允许您的应用正确暂停,您可能会得到意想不到的结果。那是在普通设备上,它实际上会挂起,但是由于您正在运行Xcode,它只会留在后台进行调试...
Honey

Answers:


192

有两个答案:

A)跳上火车:-)

B)使用模拟器。在iOS 5.x模拟器中,有一个带有位置子菜单的调试菜单。选择高速公路。这将使模拟器沿着想象中的北加州风景秀丽的280开始。它为您提供除视图之外的所有内容:您的应用将获得“重要的位置更改”更新,并且如果已暂停,它还将在后台启动

要验证您是否确实在移动,请在模拟器中启动safari,然后转到maps.google.com,然后点击跟踪我的位置按钮。你应该搬家。

太棒了!现在如何调试系统启动的生命周期问题?简单!让xCode等待您的应用程序启动以开始调试。从方案菜单中,选择编辑方案。在“运行方案”和“信息”选项卡中,为“启动”设置选择:“等待My.app启动”。

在模拟器中运行一次您的应用程序,以便它开始监视位置更新,然后强制退出它,以便将其挂起。 在您的应用程序中添加一个断点确实完成了启动功能,然后等待。一旦您的模拟器足够远,您的应用程序将被唤醒,断点被击中,您就可以赚钱。

但实际上,乘火车更有趣。


2
有人在iOS 6.X模拟器上尝试过吗?无法正常工作。
塞捷夫

2
对于我来说,iOS 6.1 sim和XCode 4.6也不运气。
Stephen Petschulat

1
等待时间太长,请参阅@Chris解决方案
DanSkeel 2015年

3
iOS9.3 + xCode 7.3更新:此方法就像一个魅力!(注意:请确保正确处理requestAlwaysAuthorization()+适当的info.plst键)。另外,设置distanceFilter = 500使我每30-40秒(有时甚至是
〜15s

1
走了5年。这对XCode 9仍然有效吗?我已经做完了上面提到的所有事情。大约等了5分钟。没有。
Dibzmania

18

好吧,我发现我可以通过切换飞行模式和/或WiFi来实现。也许以设备在飞行模式下启动应用程序,然后关闭应用程序并关闭飞行模式。这将打开GPS并强制发送位置更新。


1
对于我来说,重新启动使用大量位置更改监控的已终止应用程序并没有效果。
aslisabanci 2012年

1
是的!这是一个非常好的主意!我的问题是在设备锁定时让系统启动我的应用程序,并且此“飞行模式”解决方案在iOS 9上像超级魅力一样工作!非常感谢 !
nverinaud

4

我还想测试重新启动的终止的应用程序,该应用程序使用了重要的更改监视功能。我编写了一段代码,以便在启动选项字典中的位置键启动它时显示本地通知。

我在模拟器中运行了我的应用程序。然后从多任务处理栏中将其杀死。然后,我将iOS模拟器的位置设置为自定义位置。我退出模拟器,然后再次启动。我的应用收到了重要的位置更新,并显示了本地通知。


3

我一直在同一个问题上挣扎,如何测试“ startMonitoringSignificantLocationChanges”并检查我的应用在暂停时是否正在接收位置更新。

我无法在断点上捕获执行,但是通过将新的位置数据发送到服务器,我设法看到了实现的结果。

整个流程:-通过“ startMonitoringSignificantLocationChanges”和对我的服务器的API调用来实现,以更新位置纬度和经度-将位置更新背景模式功能设置为true-运行该应用,以便启动位置管理器,并且该应用正在监听位置更改-强制关闭应用程序-将模拟器上的debug-> location设置为高速公路驱动器-打开地图以查看位置是否正在更改-等待服务器上的位置更新,每3分钟获取一次新结果

但是,我仍然不确定在实际设备上是否足够好。

我正在开发Xcode 6.0.1(6A317);在模拟器iPhone 5s(8.0)上进行了测试。


2

添加到MagicSeth的答案中,如果您需要在真实设备而不是模拟器上进行测试,则可以UIApplication.LaunchOptionsKey.location通过在“设置”应用程序的“常规”>“隐私”屏幕中禁用并重新启用“定位服务”来触发后台启动按键。


这将是比回答更好的评论
Jodast

我是不是能够得到与模拟器工作的解决方案,但这个工作出色的iOS上的12
duncanc4

1

根据您的情况,我建议两种解决方案:

  1. 使用一个Timer或LocalNotification,它定期调用stopMonitoringSignificantLocationChanges,然后依次调用startMonitoringSignificantLocationChanges,这将触发将新位置发送到您的代码(可能与以前的位置相同)。

  2. 建立您自己的GPS模拟器,该模拟器将在调试版本中开始,并将调用与CLLocationManager相同的委托方法。


存在一个应用程序生命周期,这是问题的本质。
尼克

存在一个应用程序生命周期,这是问题的本质。该应用程序终止,并通过将位置显着更改为后台启动。将应用程序启动到后台后,我们需要对其进行测试,包括寿命和网络通信。我们实际上花了一天时间,然后用便携式计算机在控制台上巡视整个活动,以解决问题。
尼克

1

我在iOS 7和Xcode 5.1.1中注意到的一件事-如果您期望SLC事件将您的应用启动到后台模式,则它可能会或可能不会达到您设置的断点。对我来说,有时甚至没有显示NSLog消息。

如果是这样,您可以从系统日志中查看NSLog输出。您可以从iOS Simulator的“调试”菜单打开“系统日志”。


0

在iOS 4中,您可以注册以进行重大位置更改。从Apple文档:使用此服务,仅当用户的位置发生显着变化时才生成位置更新;因此,对于社交应用程序或为用户提供非关键的,与位置相关的信息的应用程序而言,它是理想的选择。如果在发生更新时挂起了应用程序,则系统会在后台将其唤醒以处理更新。如果应用程序启动了该服务然后又终止了,那么当新位置可用时,系统会自动重新启动应用程序。此服务仅在包含蜂窝无线电的设备上在iOS 4和更高版本中可用。

在此处此处查看Apple文档

这是一些用于注册指示性位置更新的示例代码:

- (void)startSignificantChangeUpdates {

// Create the location manager if it doesn't exist
if (nil == locationManager)
    locationManager = [[CLLocationManager alloc] init];

locationManager.delegate = self;
[locationManager startMonitoringSignificantLocationChanges];

}

文档说:如果让此服务运行,并且您的应用程序随后被挂起或终止,则当新的位置数据到达时,该服务会自动唤醒您的应用程序。在唤醒时,您的应用程序将被置于后台,并留出少量时间来处理位置数据。因为您的应用程序在后台,所以它应该做的工作最少,并且避免任何可能阻止其在分配的时间到期之前返回的任务(例如查询网络)。否则,您的应用程序可能会终止。


谢谢...我了解它的工作原理,并且已经使用了一段时间。问题是如何在不开车的情况下进行测试以使设备触发它。
尼克,

啊对不起 我可以删除答案吗?
Jane Sales

-1

高速公路驾驶

在此处输入图片说明

// MARK: - MKMapViewDelegate

  func mapView(_ mapView: MKMapView, didUpdate userLocation: MKUserLocation) {
    guard let location = userLocation.location else { return }

    print(location.speed)
  }

-4

好吧,这是不可能的,因为应用程序范围仅限于其自己的空间,并且此类通知无法通过Apple Documented API列表生成。当然..如果使用了任何未公开的API,由于使用了未公开的/私有API,应用程序将被苹果拒绝。


显然...在回答之前,请先阅读问题。“这仅用于测试,我意识到此私有API调用在提交到应用商店后会被拒绝。”
尼克(Nick)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.