简体   繁体   English

iPhone位置数据在首次启动时不起作用

[英]iPhone Location Data doesn't work on very first start

I'm experiencing a strange issue with location on iPhone. 我在iPhone上遇到位置问题。 It looks just crazy but it seems to be reproducible. 它看起来很疯狂,但似乎是可复制的。 In my application I use Core Location to get location data on some user actions. 在我的应用程序中,我使用Core Location获取有关某些用户操作的位置数据。 Usually it seems to work. 通常它似乎可以正常工作。 But on the very first run after the app was deployed on device without previous version (doesn't matter from XCode or via iTunes), it doesn't work at all. 但是,在将应用程序部署到没有先前版本的设备上之后(在XCode或通过iTunes无关紧要)上的第一次运行,它根本不起作用。 Neither 都没有
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
nor 也不
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
are called. 叫做。 I don't even get coordinates of cell towers. 我什至没有得到手机信号塔的坐标。 The only sign that GPS is working is pop up that asks to allow access to location data. GPS正常工作的唯一标志是弹出,要求允许访问位置数据。 If I quit application (and by quit I mean really killing it instead of just putting into background), on next run everything usually starts working just fine. 如果我退出了应用程序(退出是指真正杀死它而不是仅仅将其置于后台),那么在下次运行时,一切通常都可以正常工作。

Some more details. 一些更多的细节。 As I need to get locations of where user does certain actions, I use following approach: 由于需要获取用户执行某些操作的位置,因此我使用以下方法:

  • I use the same shared CLLocationManager object (with kCLLocationAccuracyBest ) and the same shared delegate object. 我使用相同的共享CLLocationManager对象(带有kCLLocationAccuracyBest )和相同的共享委托对象。
  • When user does the action, I call startUpdatingLocation and create a background thread, basically timer, but there is something more not related. 当用户执行操作时,我会调用startUpdatingLocation并创建一个后台线程(基本上是计时器),但还有一些不相关的内容。 It wakes up once every 15 seconds 每15秒唤醒一次
  • I accumulate fixes received by - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation 我累积了- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
  • When background thread is waken up, it checks fixes and time. 后台线程唤醒后,它将检查修复程序和时间。 If there is a good enough fix, it stops waiting. 如果有足够好的修复程序,它将停止等待。 If 1 minute time interval is exceeded, it stops waiting as well. 如果超过了1分钟的时间间隔,它也会停止等待。
  • "Stops waiting" = calling some method. “停止等待” =调用某些方法。 That method seeks for best fix among received (if any) and processes it. 该方法在接收到的(如果有的话)中寻求最佳修复并进行处理。 Also it calls stopUpdatingLocation 它还调用stopUpdatingLocation

I don't see any obvious flaws in that way. 我看不到那种明显的缺陷。 And moreover, the very same binary usually starts working on second start. 而且,相同的二进制文件通常在第二次启动时开始工作。 Any ideas why? 有什么想法吗? Am I going crazy? 我要疯了吗?

It seems that I found the answer myself. 看来我自己找到了答案。 My application requires some start up preparations. 我的应用程序需要一些启动准备。 The difference was that at the very first run I do some big one-time job (some big synchronization over network). 不同之处在于,在第一次运行时,我会做一些一次性的大工作(通过网络进行一些大的同步)。 This long task is done in background thread. 这项漫长的任务是在后台线程中完成的。 The same thread then does "common initialization" including creation of CLLocationManager object. 然后,同一线程执行“公共初始化”,包括创建CLLocationManager对象。 Of course, background thread then quickly dies leaving CLLocationManager without any RunLoop. 当然,然后,后台线程很快就死掉了,而没有任何RunLoop就离开了CLLocationManager。 On the second start there is no need in big synchronization and "common initialization" is performed on UI thread. 在第二次启动时,不需要进行大的同步,并且在UI线程上执行“通用初始化”。 Therefore CLLocationManager is running on the main RunLoop and happily delivers fixes. 因此,CLLocationManager在主RunLoop上运行,并愉快地提供了修复程序。

To sum up: when you create CLLocationManager object, it is vitally important to do it on right thread (or rather NSRunLoop/CFRunLoop). 综上所述:创建CLLocationManager对象时,在正确的线程(或NSRunLoop / CFRunLoop)上进行操作至关重要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM