Hộp thoại cho phép vị trí hiện tại biến mất quá nhanh


175

Ứng dụng của tôi lấy vị trí của người dùng, lấy tọa độ và cung cấp khoảng cách đến hoặc từ điểm đến hoặc nguồn gốc của họ. Tất cả các điểm đến có thể này được hiển thị trong chế độ xem bảng, vì vậy tôi sẽ khiến người dùng phối hợp cùng lúc với việc điền vào bảng. Điều duy nhất là, chế độ xem cảnh báo yêu cầu vị trí người dùng xuất hiện rồi biến mất nhanh đến mức không thể nhấp vào nó!

Có cách nào để tự trình bày cảnh báo này khi tải ứng dụng lần đầu không? Tôi đã thử lấy vị trí của người dùng khi ứng dụng tải lên để thử và buộc cảnh báo hiển thị, nhưng điều đó không hiệu quả.

Câu trả lời:


698

Mặc dù khó theo dõi, giải pháp cho việc này khá đơn giản.

Qua nhiều thử nghiệm và lỗi tôi phát hiện ra rằng trong khi hộp thoại truy cập vị trí bật lên khi bạn cố gắng truy cập bất kỳ dịch vụ định vị nào trong ứng dụng lần đầu tiên, hộp thoại sẽ tự biến mất (không có bất kỳ tương tác người dùng nào) nếu CLLocationManagerđối tượng được phát hành trước đó người dùng trả lời hộp thoại.

Tôi đã tạo ra một CLLocationManagerví dụ trong viewDidLoadphương thức của tôi . Vì đây là một thể hiện cục bộ của phương thức, nên thể hiện được ARC phát hành sau khi phương thức hoàn thành thực thi. Ngay khi phiên bản được phát hành, hộp thoại biến mất. Giải pháp khá đơn giản. Thay đổi CLLocationManagerthể hiện từ một biến cấp độ phương thức thành biến thể hiện cấp độ lớp. Bây giờ CLLocationManagercá thể chỉ được phát hành khi lớp được tải.


117
Tôi ước tôi có thể cung cấp cho bạn +100
coder

1
Chỉ cần gặp vấn đề tương tự với Xamarin.iOS. Đặt phạm vi lớp CLLocationManager và hộp thoại vẫn hiển thị.
Krumelur

1
Yaaaaa .... nếu bạn có thể đi trước và tăng lương cho mình, đó sẽ là greeeeeaaaat. (Nghiêm túc mà nói, đây cũng là một khoản tiết kiệm lớn đối với tôi)
Garfonzo

2
Tôi cũng phải tham gia bữa tiệc này. Ở đây, nhận được Internet High Five từ tôi!
Matthieu Riegler

3
Bất cứ ai gặp vấn đề này trong Swift đều đảm bảo bạn di chuyển khai báo LocationManager bên ngoài viewDidLoad. Chúc mừng!
KD.

5

Cùng một triệu chứng, nguyên nhân khác nhau: không gọi startUpdatingLocationnhiều lần liên tiếp .

Tôi đã vô tình cấu trúc những thứ mà mã vô tình gọi startUpdatingLocationhai lần liên tiếp, điều này rõ ràng là xấu. Nó cũng có thể có liên quan đến việc lựa chọn hàng đợi vì tôi đang chờ để bắt đầu cập nhật trong khi chờ kết quả của yêu cầu mạng, nhưng tôi không cần thực hiện bất kỳ phép thuật GCD nào để khắc phục ... chỉ cần đảm bảo rằng tôi không lặp lại bắt đầu.

Hy vọng ai đó có thể hưởng lợi từ nỗi đau của tôi. :)


5

Tôi đã phải đối mặt với tình huống tương tự. Sau khi gỡ lỗi tôi đã tìm thấy

let locationManager = CLLocationManager()

được gọi trong phạm vi phương thức, nhưng nó phải được gọi trên toàn cầu.

Tại sao?

Tóm lại, locationManager đã được phát hành sau khi phương thức đã trở lại. Nhưng nó không nên được phát hành cho đến khi người dùng cho hoặc từ chối cấp phép


4

Tôi rơi vào cùng một vấn đề (ít nhất là bởi các triệu chứng). Trong trường hợp của tôi, vấn đề nằm ở - (void)applicationWillResignActive:(UIApplication *)application;phương thức, nơi tôi đã phát hành CLLocationManagercá thể của mình như là một phần của việc chuẩn bị cho quá trình chuyển đổi nền. Khi tôi gỡ bỏ nó và chỉ còn lại nó trong - (void)applicationDidEnterBackground:(UIApplication *)application;vấn đề đã biến mất.
Phần khó khăn là cảnh báo Vị trí lõi DO tạm dừng ứng dụng của bạn trong khi ứng dụng vẫn ở phía trước.
Hy vọng rằng nó sẽ giúp bạn, tôi đã mất rất nhiều thời gian để tìm ra tên khốn đó :)


4

Tôi biết đây là một câu trả lời rất muộn. Nhưng nó có thể giúp ai đó. Tôi cũng phải đối mặt với vấn đề tương tự và dành một giờ để xác định vấn đề. Lúc đầu mã của tôi là như thế này.

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

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

    [locationManager release];

Bây giờ cảnh báo vị trí xuất hiện nhanh chóng. Khi tôi bỏ ghi chú dòng cuối cùng thì nó hoạt động chính xác.

   // [locationManager release];

3
Đây là sự thật. Lời cảnh báo duy nhất tôi muốn thêm vào câu trả lời này là khi dự án của bạn được bật ARC, bạn không cần đưa câu lệnh phát hành vào mã của mình và bạn vẫn sẽ gặp phải vấn đề này. Cách duy nhất để giải quyết vấn đề trong kịch bản đó là tạo mức biến lớp thay vì mức phương thức.
Zoli

3

Tôi cũng gặp phải vấn đề này, nhưng giải pháp trong trường hợp của tôi hóa ra hoàn toàn khác với câu trả lời được chấp nhận.

Trong ứng dụng của tôi, tôi đã gọi stopUpdatingLocationtừ applicationWillResignActive. Đây là một vấn đề vì applicationWillResignActiveđược gọi khi hộp thoại cho phép xuất hiện. Điều này đã gây ra stopUpdatingLocationngay sau startUpdatingLocationđó, đó là lý do tại sao hộp thoại sẽ ngay lập tức biến mất.

Giải pháp đơn giản là gọi stopUpdatingLocationtừ applicationDidEnterBackgroundthay thế.


2

Điều này đã xảy ra với tôi khi sử dụng Trình mô phỏng iOS. Tôi xác định rằng điều đó đã xảy ra vì Run Scheme của tôi đang mô phỏng một địa điểm. Tôi nghĩ rằng điều này có tác dụng tương tự như gọi locationManager.startUpdatingLocation()khi khởi chạy và vì vậy nó đã đóng hộp thoại.

Bỏ chọn hộp kiểm "Cho phép mô phỏng vị trí" trong hộp thoại Chỉnh sửa lược đồ đã khắc phục sự cố. Khi nó hoạt động như bạn muốn và quyền được đặt, bạn có thể bật lại mô phỏng vị trí và trình giả lập sẽ hoạt động tốt từ đó trở đi.


Điều này làm việc đến một số mở rộng cho tôi. Tôi đã thấy hộp thoại
CppChase

2

Swift 4 và iOS 11 :

Hãy chắc chắn đã thêm các dòng riêng tư (cả luôn luônkhi sử dụng ) vào .plisttệp của bạn và thêm CoreLocationFramework vào dự án của bạn

Hộp thoại cho phép vị trí xuất hiện chính xác khi tôi thay đổi:

locationManager.requestAlwaysAuthorization()

với:

locationManager.requestWhenInUseAuthorization()

Tái bút : Tôi đã thử TẤT CẢ các lời khuyên và tất cả đều thất bại (yêu cầu ủy quyền viewDidLoad, varthay vì letcho locationManager, đừng bắt đầu startUpdatingLocation()sau khi yêu cầu..Tôi nghĩ đó là một lỗi và tôi hy vọng họ sẽ giải quyết sớm nhất có thể ..


Tôi cũng đã làm theo tất cả các lời khuyên, nhưng tôi luôn có cùng một vấn đề. Hộp thoại cho phép vị trí xuất hiện nhanh chóng, sau đó biến mất ngay lập tức. Sau đó, quyền hộp thoại thông báo của tôi xuất hiện (cái này là bình thường), khi tôi nhấn chấp nhận hoặc từ chối, một quyền khác sẽ xuất hiện (lần này nó vẫn ở đó và để tôi chấp nhận hoặc từ chối).

@BitoQ Vâng, đối với tôi cũng vậy. Tình huống tương tự nhưng ít nhất chúng ta có thể thấy hộp thoại này, tôi hy vọng với iOS 11.1 tiếp theo họ sẽ sửa lỗi này ..
Alessandro Ornano

1

Giải pháp SWift 4 @Zoli sẽ như sau:

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

0

bạn hầu hết xác định biến locationManager là đối tượng toàn cầu.

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

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

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

0

Tôi đã gặp tình huống tương tự của bạn.

  • Giải pháp của tôi đã được thay đổi từ biến cục bộ thành cá thể thành viên.
  • Nguyên nhân là do cá thể cục bộ không hợp lệ sau khi phương thức kết thúc bao gồm biến cục bộ (mở rộng locationManager của tôi)
  • Env của tôi: Xcode9.3.1
# nhập khẩu 
@interface ViewCont điều khiển ()

@kết thúc

@imâyation ViewContoder
@synthesize locManager; // sau
- (void) viewDidLoad {
    [siêu viewDidLoad];
    // Thực hiện bất kỳ thiết lập bổ sung nào sau khi tải chế độ xem, thường là từ ngòi.

    // MyLocationService * locManager = [[BSNLocationService allocate] init: nil]; // trước. các địa phương. đại biểu không hoạt động vì thể hiện trở nên không hợp lệ sau phương thức này.
    self-> locManager = [[MyLocationService alloc] init: nil]; // sau
    locManager.startService;
}

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.