ios 当前位置权限对话框消失得太快

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7888896/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 22:02:53  来源:igfitidea点击:

Current location permission dialog disappears too quickly

objective-cioscore-location

提问by glenn sayers

My app takes the user's location, gets the co-ordinates , and provides a distance to or from their destination or origin. All these possible destinations are shown in a table view, so I'm getting the users co-ordinates at the same time as populating the table. The only thing is, the alert view that asks for the users location appears then disappears so quickly it's impossible to click it!

我的应用程序获取用户的位置,获取坐标,并提供与他们的目的地或原点之间的距离。所有这些可能的目的地都显示在表格视图中,因此我在填充表格的同时获取用户坐标。唯一的问题是,询问用户位置的警报视图出现然后消失得如此之快,以至于无法点击它!

Is there any way to manually present this alert when the app first loads? I tried getting the user's location when the app loads up to try and force the alert to show, but that didn't work.

有没有办法在应用程序首次加载时手动显示此警报?我尝试在应用加载时获取用户的位置以尝试强制显示警报,但这没有用。

回答by Zoli

While difficult to track down, the solution for this is quite simple.

虽然难以追踪,但解决方案非常简单。

Through much trial and error I found out that while the location access dialog pops up when you try to access any location services in the app for the first time, the dialog disappears on its own (without any user interaction) if the CLLocationManagerobject is released before the user responds to the dialog.

通过多次反复试验,我发现当您第一次尝试访问应用程序中的任何位置服务时会弹出位置访问对话框,如果该CLLocationManager对象之前被释放,该对话框会自行消失(无需任何用户交互)用户响应对话框。

I was creating a CLLocationManagerinstance in my viewDidLoadmethod. Since this was a local instance to the method, the instance was released by ARC after the method completed executing. As soon as the instance was released, the dialog disappeared. The solution was rather simple. Change the CLLocationManagerinstance from being a method-level variable to be a class-level instance variable. Now the CLLocationManagerinstance is only released once the class is unloaded.

CLLocationManager在我的viewDidLoad方法中创建了一个实例。由于这是该方法的本地实例,该实例在该方法执行完成后由 ARC 释放。实例一释放,对话框就消失了。解决方案相当简单。将CLLocationManager实例从方法级变量更改为类级实例变量。现在,CLLocationManager只有在卸载类后才会释放实例。

回答by clozach

Same symptom, different cause: do not to call startUpdatingLocationmore than once in a row.

相同的症状,不同的原因:不要startUpdatingLocation连续打电话多次

I had accidentally structured things such that the code was unintentionally calling startUpdatingLocationtwice in a row, which is apparently bad. It might also have had something to do with choice of queue since I was waiting to start updating pending the result of a network request, but I didn't need to do any GCD magic to fix it...just needed to make sure I didn't repeat the start.

我不小心构造了一些东西,以至于代码无意中startUpdatingLocation连续调用了两次,这显然很糟糕。它也可能与队列的选择有关,因为我正在等待等待网络请求的结果开始更新,但我不需要做任何 GCD 魔法来修复它......只需要确保我没有重复开始。

Hope someone's able to benefit from my pain. :)

希望有人能从我的痛苦中受益。:)

回答by Ankur Lahiry

I have faced the similar situation. After debugging I found

我也遇到过类似的情况。调试后发现

let locationManager = CLLocationManager()

is called in a method scope, but it should be called globally.

在方法范围内调用,但应该全局调用。

Why?

为什么?

In a nutshell, locationManager has been released after the method had returned. But it shouldn't be released until user give or deny permission

简而言之,locationManager 在方法返回后已被释放。但它不应该被释放,直到用户给予或拒绝许可

回答by Ariel

I fall into the same issue (at least by symptoms). In my case the problem was in the - (void)applicationWillResignActive:(UIApplication *)application;method, where I was releasing my CLLocationManagerinstance as part of preparing for background transition. When I removed it and left it only in - (void)applicationDidEnterBackground:(UIApplication *)application;the problem is gone.
The tricky part is that Core Location alert DO suspend your application while it still in foreground.
Hope that it will help you, took me a lot of time to found that bastard :)

我陷入了同样的问题(至少是症状)。在我的情况下,问题出在- (void)applicationWillResignActive:(UIApplication *)application;方法中,我正在释放我的CLLocationManager实例作为准备背景转换的一部分。当我删除它并只留下它时- (void)applicationDidEnterBackground:(UIApplication *)application;,问题就消失了。
棘手的部分是核心位置警报确实会在您的应用程序仍处于前台时暂停它。
希望它会帮助你,我花了很多时间才找到那个混蛋:)

回答by Ramaraj T

I know this is a very late reply. But it may help someone. I also faced the same problem and spent an hour to identify the issue. At first my code was like this.

我知道这是一个很晚的答复。但它可能会帮助某人。我也遇到了同样的问题,花了一个小时来确定问题。起初我的代码是这样的。

CLLocationManager *locationManager = [[CLLocationManager alloc] init];
[locationManager startUpdatingLocation];

CLLocation *location = locationManager.location;
//my stuff with the location

    [locationManager release];

Now the location alert disppeared quickly. When I uncomment the last line it is working correctly.

现在位置警报很快消失了。当我取消注释最后一行时,它工作正常。

   // [locationManager release];

回答by Alan Kinnaman

I ran into this problem, also, but the solution in my case turned out to be completely different than the accepted answer.

我也遇到了这个问题,但在我的案例中的解决方案与公认的答案完全不同。

In my app, I was calling stopUpdatingLocationfrom applicationWillResignActive. This was a problem because applicationWillResignActiveis called when the permission dialog appears. This was causing stopUpdatingLocationimmediately after startUpdatingLocation, which is why the dialog would immediately disappear.

在我的应用程序中,我stopUpdatingLocationapplicationWillResignActive. 这是一个问题,因为applicationWillResignActive在出现权限对话框时调用。这是stopUpdatingLocation在 之后立即引起的startUpdatingLocation,这就是对话框会立即消失的原因。

The solution was simply to call stopUpdatingLocationfrom applicationDidEnterBackgroundinstead.

解决方案只是调用stopUpdatingLocationfromapplicationDidEnterBackground代替。

回答by Paolo

This was happening to me while using the iOS Simulator. I determined that it was occurring because my Run Scheme was simulating a location. I think this has the same effect as calling locationManager.startUpdatingLocation()at launch and so it was closing the dialog.

我在使用 iOS 模拟器时发生了这种情况。我确定它正在发生是因为我的运行方案正在模拟一个位置。我认为这与locationManager.startUpdatingLocation()在启动时调用具有相同的效果,因此它正在关闭对话框。

Un-checking the "Allow Location Simulation" checkbox in the Edit Schemes dialog fixed the issue. Once it works as you want it to and the permission is set, you can re-enable the location simulation and the simulator will work fine from then on.

取消选中“编辑方案”对话框中的“允许位置模拟”复选框修复了该问题。一旦它按您的意愿工作并设置了权限,您就可以重新启用位置模拟,此后模拟器将正常工作。

回答by Alessandro Ornano

Swift 4 and iOS 11:

斯威夫特 4 和 iOS 11

Be sure to have added privacy lines (both alwaysand whenInUse) to your .plistfile and add CoreLocationFramework to your project

确保在您的文件中添加了隐私行(alwayswhenInUse.plist并将CoreLocationFramework添加到您的项目中

The location permission dialog appears correctly when I've changed :

当我更改时,位置权限对话框会正确显示:

locationManager.requestAlwaysAuthorization()

with:

和:

locationManager.requestWhenInUseAuthorization()

P.S.: I've tried ALLadvices and all fails (request authorization to viewDidLoad, varinstead of letfor locationManager, don't start startUpdatingLocation()after request..I think it's a bug and I hope they will resolve it as soon as possible..

PS.:我已经尝试了所有建议,但都失败了(请求授权viewDidLoadvar而不是letlocationManager,不要startUpdatingLocation()在请求后启动..我认为这是一个错误,我希望他们能尽快解决它..

回答by wm.p1us

SWIFT 4@Zoli solution will look like:

SWIFT 4@Zoli 解决方案将如下所示:

class WhateverViewController: UIViewController {
    let locationManager = CLLocationManager() // here is the point of the @Zoli answer

    // some code
    override func viewDidLoad() {
        super.viewDidLoad()

        // some other code
        locationManager.requestWhenInUseAuthorization()
        // some other code
    }
}

回答by Mahdi Nili

you most define locationManager variable as global object.

您最常将 locationManager 变量定义为全局对象。

@interface ViewController : UIViewController
{
    CLLocationManager *locationManager;
}
@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    CLLocationManager *locationManager = [[CLLocationManager alloc] init];
    [locationManager startUpdatingLocation];
}