Dialog izin lokasi saat ini menghilang terlalu cepat

175

Aplikasi saya mengambil lokasi pengguna, mendapatkan koordinat, dan menyediakan jarak ke atau dari tujuan atau asal mereka. Semua tujuan yang mungkin ini ditampilkan dalam tampilan tabel, jadi saya mendapatkan pengguna mengoordinasikan pada saat yang sama saat mengisi tabel. Satu-satunya hal adalah, tampilan peringatan yang menanyakan lokasi pengguna muncul kemudian menghilang begitu cepat sehingga tidak mungkin untuk mengkliknya!

Apakah ada cara untuk menampilkan lansiran ini secara manual saat aplikasi pertama kali memuat? Saya mencoba mendapatkan lokasi pengguna ketika aplikasi memuat untuk mencoba dan memaksa lansiran untuk ditampilkan, tetapi itu tidak berhasil.

Glenn Sayers
sumber

Jawaban:

698

Meskipun sulit dilacak, solusi untuk ini cukup sederhana.

Melalui banyak trial and error saya menemukan bahwa sementara dialog akses lokasi muncul ketika Anda mencoba mengakses layanan lokasi di aplikasi untuk pertama kalinya, dialog menghilang dengan sendirinya (tanpa interaksi pengguna) jika CLLocationManagerobjek dirilis sebelum pengguna merespons dialog.

Saya sedang membuat CLLocationManagercontoh dalam viewDidLoadmetode saya . Karena ini adalah instance lokal untuk metode, instance dirilis oleh ARC setelah metode selesai dieksekusi. Segera setelah instance dirilis, dialog menghilang. Solusinya agak sederhana. Ubah CLLocationManagerinstance dari menjadi variabel level metode menjadi variabel instan level kelas. Sekarang CLLocationManagerinstance hanya dirilis setelah kelas diturunkan.

Zoli
sumber
117
Saya berharap saya bisa memberi Anda +100
coder
1
Tekan saja masalah yang sama dengan Xamarin.iOS. Buat ruang lingkup kelas CLLocationManager dan dialog tetap terlihat.
Krumelur
1
Yaaaaa .... jika Anda bisa melanjutkan dan memberi diri Anda kenaikan gaji, itu akan jadi greeeeeaaaat. (Serius, ini juga menghemat besar bagi saya)
Garfonzo
2
Saya harus bergabung dengan pesta ini juga. Di sini, dapatkan Internet High Five dari saya!
Matthieu Riegler
3
Siapa pun yang memiliki masalah ini di Swift pastikan Anda memindahkan deklarasi LocationManager di luar viewDidLoad. Bersulang!
KD.
5

Gejala yang sama, penyebab berbeda: jangan menelepon startUpdatingLocationlebih dari satu kali berturut-turut .

Saya tidak sengaja menyusun hal-hal sedemikian rupa sehingga kode itu secara tidak sengaja memanggil startUpdatingLocationdua kali berturut-turut, yang tampaknya buruk. Mungkin juga ada hubungannya dengan pilihan antrian karena saya menunggu untuk mulai memperbarui sambil menunggu hasil permintaan jaringan, tapi saya tidak perlu melakukan sihir GCD untuk memperbaikinya ... hanya perlu memastikan saya tidak mengulangi awal.

Semoga seseorang dapat mengambil manfaat dari rasa sakit saya. :)

clozach
sumber
5

Saya telah menghadapi situasi yang sama. Setelah debugging saya temukan

let locationManager = CLLocationManager()

disebut dalam lingkup metode, tetapi harus disebut secara global.

Mengapa?

Singkatnya, locationManager telah dirilis setelah metode kembali. Tapi itu tidak boleh dirilis sampai pengguna memberikan atau menolak izin

Ankur Lahiry
sumber
4

Saya jatuh ke masalah yang sama (setidaknya oleh gejala). Dalam kasus saya masalahnya ada pada - (void)applicationWillResignActive:(UIApplication *)application;metode, di mana saya merilis CLLocationManagercontoh saya sebagai bagian dari persiapan untuk transisi latar belakang. Ketika saya menghapusnya dan meninggalkannya hanya dalam - (void)applicationDidEnterBackground:(UIApplication *)application;masalah hilang.
Bagian yang sulit adalah peringatan Lokasi Inti DO menangguhkan aplikasi Anda saat masih di latar depan.
Semoga itu akan membantu Anda, butuh banyak waktu untuk menemukan bajingan itu :)

Ariel
sumber
4

Saya tahu ini adalah jawaban yang sangat terlambat. Tapi itu bisa membantu seseorang. Saya juga menghadapi masalah yang sama dan menghabiskan satu jam untuk mengidentifikasi masalah ini. Awalnya kode saya seperti ini.

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

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

    [locationManager release];

Sekarang peringatan lokasi dihilangkan dengan cepat. Ketika saya batalkan komentar pada baris terakhir itu berfungsi dengan benar.

   // [locationManager release];
Ramaraj T
sumber
3
Ini benar. Satu-satunya peringatan yang akan saya tambahkan ke jawaban ini adalah bahwa ketika proyek Anda telah mengaktifkan ARC, Anda tidak perlu memasukkan pernyataan rilis dalam kode Anda dan Anda masih akan mengalami masalah ini. Satu-satunya cara untuk menyelesaikan masalah dalam skenario itu adalah membuat level kelas variabel, bukan level metode.
Zoli
3

Saya juga mengalami masalah ini, tetapi solusi dalam kasus saya ternyata sangat berbeda dari jawaban yang diterima.

Di aplikasi saya, saya menelepon stopUpdatingLocationdari applicationWillResignActive. Ini adalah masalah karena applicationWillResignActivedipanggil ketika dialog izin muncul. Ini menyebabkan stopUpdatingLocationsegera setelah itu startUpdatingLocation, itulah sebabnya dialog akan segera menghilang.

Solusinya adalah hanya untuk panggilan stopUpdatingLocationdari applicationDidEnterBackgroundsebaliknya.

Alan Kinnaman
sumber
2

Ini terjadi pada saya saat menggunakan Simulator iOS. Saya memutuskan bahwa itu terjadi karena Skema Run saya mensimulasikan lokasi. Saya pikir ini memiliki efek yang sama dengan menelepon locationManager.startUpdatingLocation()saat peluncuran dan jadi itu menutup dialog.

Hapus centang pada kotak centang "Izinkan Simulasi Lokasi" dalam dialog Edit Skema memperbaiki masalah. Setelah berfungsi sesuai keinginan dan izin ditetapkan, Anda dapat mengaktifkan kembali simulasi lokasi dan simulator akan berfungsi dengan baik sejak saat itu.

Paolo
sumber
Ini bekerja sampai batas tertentu bagi saya. Atleast saya bisa melihat dialog
CppChase
2

Swift 4 dan iOS 11 :

Pastikan Anda telah menambahkan jalur privasi ( selalu dan saat digunakan ) ke .plistfile Anda dan tambahkan CoreLocationFramework ke proyek Anda

Dialog izin lokasi muncul dengan benar ketika saya berubah:

locationManager.requestAlwaysAuthorization()

dengan:

locationManager.requestWhenInUseAuthorization()

PS .: Saya sudah mencoba SEMUA saran dan semuanya gagal (minta otorisasi untuk viewDidLoad, varalih-alih letuntuk locationManager, jangan mulai startUpdatingLocation()setelah permintaan..Saya pikir itu bug dan saya berharap mereka akan menyelesaikannya sesegera mungkin ..

Alessandro Ornano
sumber
Saya telah mengikuti semua saran juga, tetapi saya selalu memiliki masalah yang sama. Dialog izin lokasi muncul sebentar, lalu menghilang segera. Kemudian izin dialog pemberitahuan saya muncul (yang ini normal), ketika saya menekan terima atau tolak, izin lokasi lain muncul (kali ini tetap dan biarkan saya terima atau tolak).
@ BitoQ Ya, untuk saya juga. Situasi yang sama tetapi setidaknya kita dapat melihat dialog ini, saya harap dengan iOS 11.1 berikutnya mereka akan memperbaiki bug ini ..
Alessandro Ornano
1

Solusi SWIFT 4 @Zoli akan terlihat seperti:

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
    }
}
wm.p1us
sumber
0

Anda paling mendefinisikan variabel locationManager sebagai objek global.

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

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    CLLocationManager *locationManager = [[CLLocationManager alloc] init];
    [locationManager startUpdatingLocation];
}
Mahdi Nili
sumber
0

Saya bertemu dengan situasi Anda yang sama.

  • Solusi saya diubah dari variabel lokal ke instance anggota.
  • Penyebabnya adalah bahwa instance lokal? Tidak valid setelah metode selesai yang mencakup variabel lokal (memperpanjang lokasi saya Manajer)
  • Env saya .: Xcode9.3.1
#impor 
@interface ViewController ()

@akhir

@ implementasi ViewController
@ mensintesis locManager; // setelah
- (void) viewDidLoad {
    [super viewDidLoad];
    // Lakukan pengaturan tambahan setelah memuat tampilan, biasanya dari nib.

    // MyLocationService * locManager = [[alokasi BSNLocationService] init: nil]; // sebelum. loc. delegasi tidak berfungsi karena instance menjadi tidak valid setelah metode ini.
    self-> locManager = [[MyLocationServiceokasikan] init: nil]; // setelah
    locManager.startService;
}

pengguna2058374
sumber