Layanan Lokasi tidak berfungsi di iOS 8


608

Aplikasi saya yang bekerja dengan baik di iOS 7 tidak bekerja dengan iOS 8 SDK.

CLLocationManagertidak mengembalikan lokasi, dan saya tidak melihat aplikasi saya di bawah Pengaturan -> Layanan Lokasi juga. Saya melakukan pencarian Google pada masalah ini, tetapi tidak ada yang muncul. Apa yang salah?


Anda juga dapat menggunakan ini sebagai aplikasi referensi untuk solusi github.com/jbanford/ConstantLocationUpdates
ashok vadivelu

19
Saya memposting tentang beberapa perubahan pada manajer lokasi di iOS 8 di sini: nevan.net/2014/09/core-location-manager-changes-in-ios-8
raja

2
Anda dapat mencoba menggunakan pustaka ini yang menyederhanakan API Lokasi Inti dan memperlihatkan antarmuka berbasis blok yang bagus, dan menormalkan semua perbedaan antara versi iOS yang berbeda (Pengungkapan penuh: Saya penulis): github.com/lmirosevic/GBLocation
lms

Saya menemukan beberapa referensi di sini datacalculation.blogspot.in/2014/11/…
iOS Test

2
@nevanking Anda pak! butuh mahkota! Saya telah berjuang dengan masalah ini sejak perubahan dan belum menemukan "panduan" bagaimana cara memperbaikinya, yang ramah noob .. Panduan Anda membuat orang idiot seperti saya, menangani masalah saya sendiri. Terima kasih banyak atas tautannya.
Patrick R

Jawaban:


1086

Saya akhirnya memecahkan masalah saya sendiri.

Rupanya di iOS 8 SDK, requestAlwaysAuthorization(untuk lokasi latar belakang) atau requestWhenInUseAuthorization(lokasi hanya saat latar depan) CLLocationManagerdiperlukan sebelum memulai pembaruan lokasi.

Ada juga perlu NSLocationAlwaysUsageDescriptionatau NSLocationWhenInUseUsageDescriptiondimasukkan Info.plistdengan pesan yang akan ditampilkan di prompt. Menambahkan ini memecahkan masalah saya.

masukkan deskripsi gambar di sini

Semoga ini bisa membantu orang lain.

SUNTING: Untuk informasi yang lebih luas, lihat di: Core-Location-Manager-Changes-in-ios-8


6
dapatkah Anda membagikan nilai tepat yang diperbarui di Info.plist? Saya tidak dapat melihat kunci itu di Info.plist saya. Saya menambahkannya dan tetap tidak berfungsi. Saya menggunakan Swift, iOS8 dan XCode 6 beta 4
Vijay Kumar AB

4
@ Vjay - Anda harus mengedit file Info.plist dalam editor, tidak dapat mengatur kunci-kunci itu dalam Xcode (pada beta 6).
Kendall Helmstetter Gelner

11
Hanya pengingat, jika Anda tidak ingin menampilkan penjelasan khusus kepada pengguna, cukup setel kunci ini ke string kosong.
nonamelive

7
Anda perlu mempertahankan Manajer Lokasi Anda untuk membuatnya berfungsi. jadi jadikan CLLocationManager Anda sebagai properti yang kuat
Vassily

273
Saya 'CINTA' bahwa Anda tidak mendapatkan kesalahan, tidak ada peringatan, tidak ada pesan log, TIDAK ADA jika Anda meninggalkan entri plist. Pada dasarnya Apple telah membuat panggilan API yang TIDAK APA PUN jika Anda tidak memiliki entri plist yang sesuai. Terima kasih kepada @OrtwinGentz ​​untuk mengetahui hal ini.
MobileVet

314

Saya mencabut rambut saya dengan masalah yang sama. Xcode memberi Anda kesalahan:

Mencoba memulai MapKitpembaruan lokasi tanpa meminta otorisasi lokasi. Harus menelepon -[CLLocationManager requestWhenInUseAuthorization]atau -[CLLocationManager requestAlwaysAuthorization]pertama.

Tetapi bahkan jika Anda menerapkan salah satu metode di atas, itu tidak akan meminta pengguna kecuali ada entri di info.plist untuk NSLocationAlwaysUsageDescriptionatau NSLocationWhenInUseUsageDescription.

Tambahkan baris berikut ke info.plist Anda di mana nilai string mewakili alasan Anda perlu mengakses lokasi pengguna

<key>NSLocationWhenInUseUsageDescription</key>
<string>This application requires location services to work</string>

<key>NSLocationAlwaysUsageDescription</key>
<string>This application requires location services to work</string>

Saya pikir entri ini mungkin telah hilang sejak saya memulai proyek ini di Xcode 5. Saya kira Xcode 6 mungkin menambahkan entri default untuk kunci ini tetapi belum dikonfirmasi.

Anda dapat menemukan informasi lebih lanjut tentang dua Pengaturan ini di sini


13
xcode 6 tidak menambahkan kunci-kunci ini secara default, jika Anda bermaksud untuk mengimplementasikan CLLocationManager, Anda harus menambahkannya secara manual
Wesley Smith

1
Saya juga harus menambahkan ini secara manual, tidak dapat menambahkan melalui tampilan RawValues ​​dari info.plist di Xcode6!
Kendall Helmstetter Gelner

1
Saya mencari selamanya untuk ini. Pesan [CLLLocationManager authorizationStatus] saya hanya mengembalikan nilai <nil>. Setelah menambahkan kunci di atas, ia mulai mengembalikan masing-masing enumerasi untuk output pesan. Dari apa yang saya temukan ini adalah bug iOS 8 yang dikenal tetapi tidak bisa menemukan apa pun dalam konteks saya selama bertahun-tahun. Terima kasih banyak!
MrOli3000

4
Saya suka nilai string yang Anda masukkan
Chris Chen

1
Pesan akan muncul sebagai sub-pesan dalam Peringatan yang menanyakan apakah pengguna ingin membagikan lokasi mereka. Dengan demikian, hanya menjadi kosong (kosong) tampaknya paling masuk akal dalam aplikasi saya. Penjelasan tentang mengapa Anda ingin menggunakan lokasi juga masuk akal. Namun, NSLocationWhenInUseUsageDescription tidak berperilaku seperti yang diharapkan untuk saya (mis. Terus mendapatkan izin, meskipun nilai pengembaliannya benar). NSLocationAlwaysUsageDescription bekerja dengan baik.
arcady bob

104

Untuk memastikan bahwa ini kompatibel dengan iOS 7, Anda harus memeriksa apakah pengguna menjalankan iOS 8 atau iOS 7. Misalnya:

#define IS_OS_8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)

//In ViewDidLoad
if(IS_OS_8_OR_LATER) {
   [self.locationManager requestAlwaysAuthorization];
}

[self.locationManager startUpdatingLocation];

164
Cara yang lebih baik daripada memeriksa versi adalah memeriksa untuk melihat apakah objek memiliki pemilih itu, misalnya: if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) { ...
progrmr

1
Saya mengalami masalah hanya menerapkan solusi @ progrmr ketika membangun di Xcode 5, karena tidak tahu apa requestAlwaysAuthorizationmetode ini. Solusi tambahan saya adalah menggunakan baris ini di ifpernyataan bukan metode panggilan biasa: [self.locationManager performSelector:@selector(requestAlwaysAuthorization)];. Mungkin ini jelas bagi orang lain, tetapi butuh beberapa saat untuk mencari tahu. Saya pikir itu solusi yang tepat sampai Xcode 6 final dirilis.
VinceFior

2
Solusi yang tepat adalah membangun dengan Xcode 6. Jika Anda membangun dengan Xcode 5 Anda tidak perlu meminta otorisasi, itu otomatis.
progrmr

Anda mungkin ada benarnya. Kekhawatiran saya adalah bahwa saya ingin kode saya dikompilasi dalam Xcode 5 (meskipun itu tidak akan bekerja di iOS 8 kecuali dikompilasi dalam Xcode 6) sementara tim saya transisi ke Xcode 6. Tapi mungkin alur kerja yang lebih baik untuk menulis kode secara normal dan tidak bergabung sampai kita pindah ke Xcode 6 .. Terima kasih.
VinceFior

@VinceFior pendekatan yang disarankan adalah mengkompilasi dengan syarat menggunakan makro yang didefinisikan SDK __IPHONE_OS_VERSION_MAX_ALLOWED( #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000)
Steven Kramer

50
- (void)startLocationManager
{
    locationManager = [[CLLocationManager alloc] init];
    locationManager.delegate = self;
    locationManager.distanceFilter = kCLDistanceFilterNone; //whenever we move
    locationManager.desiredAccuracy = kCLLocationAccuracyBest;

    [locationManager startUpdatingLocation];
    [locationManager requestWhenInUseAuthorization]; // Add This Line


}

Dan ke File info.plist Anda masukkan deskripsi gambar di sini


1
Menemukan solusi serupa dengan cara yang lebih deskriptif di datacalculation.blogspot.in/2014/11/…
iOS Test

2
@Hemang: Menurut Dokumentasi Dev Apple: Aman untuk memulai layanan lokasi sebelum status otorisasi aplikasi Anda ditentukan. Meskipun Anda dapat memulai layanan lokasi, layanan tersebut tidak mengirimkan data apa pun hingga status otorisasi berubah menjadi kCLAuthorizationStatusAuthorizedAlways atau kCLAuthorizationStatusAuthorizedWhenInUse.
Andrew

Agak terlambat, tapi saya sarankan Anda menyembunyikan bagian yang tidak relevan dari file plist Anda, terutama FacebookAppID
Przemysław Wrzesiński

Terima kasih Tapi itu hanya contoh boneka :)
neo D1

Penting juga bahwa proyek menunjuk ke info.plist yang tepat (yang di mana kunci didefinisikan). Itu ditentukan dalam pengaturan pembangunan proyek di bawah File Info.plist.
clearlight

30

Menurut dokumen Apple:

Pada iOS 8, kehadiran NSLocationWhenInUseUsageDescriptionatau NSLocationAlwaysUsageDescriptionnilai kunci dalam file Info.plist aplikasi Anda diperlukan. Maka juga diperlukan untuk meminta izin dari pengguna sebelum mendaftar untuk pembaruan lokasi, baik dengan menelepon [self.myLocationManager requestWhenInUseAuthorization]atau[self.myLocationManager requestAlwaysAuthorization] tergantung pada kebutuhan Anda. String yang Anda masukkan ke Info.plist kemudian akan ditampilkan di dialog berikutnya.

Jika pengguna memberikan izin, itu bisnis seperti biasa. Jika mereka menolak izin, maka delegasi tidak diberitahu tentang pembaruan lokasi.


Saya menemukan deskripsi sederhana di sini di datacalculation.blogspot.in/2014/11/…
iOS Test

28
- (void)viewDidLoad
{

    [super viewDidLoad];
    self.locationManager = [[CLLocationManager alloc] init];

    self.locationManager.delegate = self;
    if([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]){
        NSUInteger code = [CLLocationManager authorizationStatus];
        if (code == kCLAuthorizationStatusNotDetermined && ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)] || [self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)])) {
            // choose one request according to your business.
            if([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationAlwaysUsageDescription"]){
                [self.locationManager requestAlwaysAuthorization];
            } else if([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationWhenInUseUsageDescription"]) {
                [self.locationManager  requestWhenInUseAuthorization];
            } else {
                NSLog(@"Info.plist does not contain NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription");
            }
        }
    }
    [self.locationManager startUpdatingLocation];
}

>  #pragma mark - CLLocationManagerDelegate

    - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
    {
        NSLog(@"didFailWithError: %@", error);
        UIAlertView *errorAlert = [[UIAlertView alloc]
                                   initWithTitle:@"Error" message:@"Failed to Get Your Location" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [errorAlert show];
    }

    - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
    {
        NSLog(@"didUpdateToLocation: %@", newLocation);
        CLLocation *currentLocation = newLocation;

        if (currentLocation != nil) {
            longitudeLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.longitude];
            latitudeLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.latitude];
        }
    }

Di iOS 8 Anda perlu melakukan dua hal tambahan agar lokasi berfungsi: Tambahkan kunci ke Info.plist Anda dan minta otorisasi dari manajer lokasi yang memintanya untuk memulai. Ada dua kunci Info.plist untuk otorisasi lokasi baru. Diperlukan satu atau kedua kunci ini. Jika tidak ada tombol di sana, Anda dapat memanggil startUpdatingLocation tetapi manajer lokasi tidak benar-benar memulai. Itu tidak akan mengirim pesan kegagalan ke delegasi (karena tidak pernah dimulai, tidak bisa gagal). Ini juga akan gagal jika Anda menambahkan satu atau kedua kunci tetapi lupa untuk secara eksplisit meminta otorisasi. Jadi hal pertama yang perlu Anda lakukan adalah menambahkan satu atau kedua kunci berikut ke file Info.plist Anda:

  • NSLocationWhenInUseUsageDescription
  • NSLocationAlwaysUsageDescription

Kedua tombol ini mengambil string

yang merupakan deskripsi mengapa Anda memerlukan layanan lokasi. Anda dapat memasukkan string seperti "Diperlukan lokasi untuk mencari tahu di mana Anda berada" yang, seperti di iOS 7, dapat dilokalisasi dalam file InfoPlist.strings.

masukkan deskripsi gambar di sini


19

Solusi saya yang dapat dikompilasi dalam Xcode 5:

#ifdef __IPHONE_8_0
    NSUInteger code = [CLLocationManager authorizationStatus];
    if (code == kCLAuthorizationStatusNotDetermined && ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)] || [self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)])) {
        // choose one request according to your business.
        if([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationAlwaysUsageDescription"]){
            [self.locationManager requestAlwaysAuthorization];
        } else if([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationWhenInUseUsageDescription"]) {
            [self.locationManager  requestWhenInUseAuthorization];
        } else {
            NSLog(@"Info.plist does not contain NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription");
        }
    }
#endif
    [self.locationManager startUpdatingLocation];

2
Solusi dinamis yang bagus, untuk digunakan di semua aplikasi. Saya akan mengubah urutan dan alih-alih memeriksa iphone 8.0, saya akan memeriksa apakah manajer lokasi merespons otorisasi dan kemudian menjalankan status otorisasi untuk mendapatkan kode. Ini akan membuatnya lebih universal.
zirinisp

Bekerja di xCode 7.2 juga.
Totoro

17

Kode lama untuk menanyakan lokasi tidak akan berfungsi di iOS 8. Anda dapat mencoba metode ini untuk otorisasi lokasi:

- (void)requestAlwaysAuthorization
{
    CLAuthorizationStatus status = [CLLocationManager authorizationStatus];

    // If the status is denied or only granted for when in use, display an alert
    if (status == kCLAuthorizationStatusAuthorizedWhenInUse || status ==        kCLAuthorizationStatusDenied) {
        NSString *title;
        title = (status == kCLAuthorizationStatusDenied) ? @"Location services are off" :   @"Background location is not enabled";
        NSString *message = @"To use background location you must turn on 'Always' in the Location Services Settings";

        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title
                                                            message:message
                                                           delegate:self
                                                  cancelButtonTitle:@"Cancel"
                                                  otherButtonTitles:@"Settings", nil];
        [alertView show];
    }
    // The user has not enabled any location services. Request background authorization.
    else if (status == kCLAuthorizationStatusNotDetermined) {
        [self.locationManager requestAlwaysAuthorization];
    }
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if (buttonIndex == 1) {
        // Send the user to the Settings for this app
        NSURL *settingsURL = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
        [[UIApplication sharedApplication] openURL:settingsURL];
    }
}

UIAlertView telah ditinggalkan. Anda harus menggunakan UIAlertController sebagai gantinya.
Pasan Premaratne

ya saya tahu ini sudah usang tetapi ini juga akan berhasil. tapi ya lebih baik gunakan UIAlertController untuk iOS8.
Nits007ak

12

Di iOS 8, Anda perlu melakukan dua hal tambahan agar lokasi berfungsi: Tambahkan kunci ke Info.plist Anda dan minta otorisasi dari manajer lokasi untuk memintanya memulai.

daftar info:

<key>NSLocationUsageDescription</key>
<string>I need location</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>I need location</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>I need location</string>

Tambahkan ini ke kode Anda

if (IS_OS_8_OR_LATER)
{
    [locationmanager requestWhenInUseAuthorization];

    [locationmanager requestAlwaysAuthorization];
}

1
tidak jelas apakah kodesemu Anda adalah panggilan preprosesor atau panggilan biasa
El Dude

1
Tambahkan ini ke file constants.h atau .pch Anda: #define IS_OS_8_OR_LATER ([[UIDevice currentDevice] .systemVersion floatValue]> = 8.0)
OxenBoxen

Mengapa Anda meminta keduanya, Anda harus menambahkan komentar yang menyebutkan hanya menggunakan satu atau yang lain tergantung pada kebutuhan aplikasi Anda
powerj1984

bagian info.plist cukup mudah dilakukan di Unity3d, tetapi bagaimana cara menambahkan bagian kode jika menggunakan unity3d? dimana?
CthulhuJon

11

Satu kesalahan umum untuk pengembang Swift:

Pertama, pastikan Anda menambahkan nilai pada daftar untuk salah satu NSLocationWhenInUseUsageDescriptionatau NSLocationAlwaysUsageDescription.

Jika Anda masih tidak melihat jendela yang muncul meminta otorisasi, lihat apakah Anda meletakkan garis var locationManager = CLLocationManager()dalam viewDidLoadmetode View Controller Anda . Jika Anda melakukannya, maka bahkan jika Anda menelepon locationManager.requestWhenInUseAuthorization(), tidak ada yang akan muncul. Ini karena setelah viewDidLoad dijalankan, variabel locationManager dideallocated (dihapus).

Solusinya adalah dengan menempatkan baris var locationManager = CLLocationManager()di bagian atas metode kelas.


9

Sebelumnya [locationManager startUpdatingLocation];, tambahkan permintaan layanan lokasi iOS8:

if([locationManager respondsToSelector:@selector(requestAlwaysAuthorization)])
    [locationManager requestAlwaysAuthorization];

Edit aplikasi Anda Info.plistdan tambahkan kunci NSLocationAlwaysUsageDescriptiondengan nilai string yang akan ditampilkan kepada pengguna (misalnya,We do our best to preserve your battery life. )

Jika aplikasi Anda hanya membutuhkan layanan lokasi saat aplikasi terbuka, ganti:

requestAlwaysAuthorizationdengan requestWhenInUseAuthorizationdan

NSLocationAlwaysUsageDescriptiondengan NSLocationWhenInUseUsageDescription.


9

Saya sedang mengerjakan aplikasi yang ditingkatkan ke iOS 8 dan layanan lokasi berhenti bekerja. Anda mungkin akan mendapatkan kesalahan di area Debug seperti:

Trying to start MapKit location updates without prompting for location authorization. Must call -[CLLocationManager requestWhenInUseAuthorization] or -[CLLocationManager requestAlwaysAuthorization] first.

Saya melakukan prosedur yang paling tidak mengganggu. Pertama-tama tambahkan NSLocationAlwaysUsageDescriptionentri ke info.plist Anda:

Masukkan deskripsi gambar di sini

Perhatikan saya tidak mengisi nilai untuk kunci ini. Ini masih berfungsi, dan saya tidak khawatir karena ini adalah aplikasi in-house. Juga, sudah ada judul yang meminta untuk menggunakan layanan lokasi, jadi saya tidak ingin melakukan sesuatu yang berlebihan.

Selanjutnya saya membuat persyaratan untuk iOS 8:

if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
    [_locationManager requestAlwaysAuthorization];
}

Setelah ini locationManager:didChangeAuthorizationStatus:metodenya adalah panggilan:

- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:  (CLAuthorizationStatus)status
{
    [self gotoCurrenLocation];
}

Dan sekarang semuanya bekerja dengan baik. Seperti biasa, lihat dokumentasi .


7

Solusi dengan kompatibilitas mundur:

SEL requestSelector = NSSelectorFromString(@"requestWhenInUseAuthorization");
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined &&
    [self.locationManager respondsToSelector:requestSelector]) {
    [self.locationManager performSelector:requestSelector withObject:NULL];
} else {
    [self.locationManager startUpdatingLocation];
}

Pengaturan NSLocationWhenInUseUsageDescription kunci di Info.plist Anda


2
Ini tidak benar, bagaimana dengan case kCLAuthorizationStatusDenied? itu melompat ke yang lain dan mulai memperbarui lokasi yang tidak benar!
electronix384128

@BenMarten Saya tidak berpikir itu penting. Anda harus menanganinya sendiri locationManager: (CLLocationManager *)manager didFailWithError: (NSError *)error. Namun, dia lupa untuk menambahkan startUpdatingLocation ke pernyataan if jadi setelah mereka menerima atau menolaknya, itu sebenarnya tidak memanggil startUpdateLocation.
Chris

6

Solusi dengan kompatibilitas mundur yang tidak menghasilkan peringatan Xcode:

SEL requestSelector = NSSelectorFromString(@"requestWhenInUseAuthorization");
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined &&
  [self.locationManager respondsToSelector:requestSelector]) {
((void (*)(id, SEL))[self.locationManager methodForSelector:requestSelector])(self.locationManager, requestSelector);
  [self.locationManager startUpdatingLocation];
} else {
  [self.locationManager startUpdatingLocation];
}

NSLocationWhenInUseUsageDescriptionKunci pengaturan di Info.plist.

Untuk iOS versi 11.0+ : NSLocationAlwaysAndWhenInUseUsageDescriptionKunci pengaturan di Info.plist. bersama dengan 2 kunci lainnya.


Ini tidak benar, bagaimana dengan case kCLAuthorizationStatusDenied? itu melompat ke yang lain dan mulai memperbarui lokasi yang tidak benar!
electronix384128

Ini cukup aneh, ini bekerja dengan baik untuk saya tidak baik-baik saja dengan baik memungkinkan dan tidak memungkinkan. Bahkan solusi Jacob terlihat akurat tetapi tidak bekerja untuk saya. Aneh tapi berhasil !!!
josh

Memanggil [self.locationManager startUpdatingLocation] tepat setelah requestWhenInUseAuthorization tidak ada gunanya
Kostia Kim

5

Ini masalah dengan ios 8 Tambahkan ini ke kode Anda

if (IS_OS_8_OR_LATER)
{
    [locationmanager requestWhenInUseAuthorization];

    [locationmanager requestAlwaysAuthorization];
}

dan ke info.plist:

 <key>NSLocationUsageDescription</key>
 <string>I need location</string>
 <key>NSLocationAlwaysUsageDescription</key>
 <string>I need location</string>
 <key>NSLocationWhenInUseUsageDescription</key>
 <string>I need location</string>

NSLocationUsageDescriptiontidak digunakan di iOS8 +
Carlos Ricardo

4

Untuk Mengakses Lokasi Pengguna di iOS 8 Anda harus menambahkan,

NSLocationAlwaysUsageDescription in the Info.plist 

Ini akan meminta izin kepada pengguna untuk mendapatkan lokasi mereka saat ini.


4

Prosedur Objective-C Ikuti instruksi di bawah ini:

Untuk iOS-11 Untuk iOS 11 lihat Jawaban ini: akses lokasi iOS 11

Perlu Tambahkan dua Tombol ke dalam daftar dan berikan pesan seperti gambar di bawah ini:

 1. NSLocationAlwaysAndWhenInUseUsageDescription 
 2. NSLocationWhenInUseUsageDescription
 3. NSLocationAlwaysUsageDescription

masukkan deskripsi gambar di sini Untuk iOS-10 ke bawah:

NSLocationWhenInUseUsageDescription

masukkan deskripsi gambar di sini

locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers;
if([locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]){
    [locationManager requestWhenInUseAuthorization];
}else{
    [locationManager startUpdatingLocation];
} 

Metode Delegasi

#pragma mark - Lolcation Update 
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
    NSLog(@"didFailWithError: %@", error);
    UIAlertView *errorAlert = [[UIAlertView alloc]
                               initWithTitle:@"Error" message:@"Failed to Get Your Location" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [errorAlert show];
}
-(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
    switch (status) {
        case kCLAuthorizationStatusNotDetermined:
        case kCLAuthorizationStatusRestricted:
        case kCLAuthorizationStatusDenied:
        {
            // do some error handling
        }
            break;
        default:{
            [locationManager startUpdatingLocation];
        }
            break;
    }
}
- (void)locationManager:(CLLocationManager *)manager
     didUpdateLocations:(NSArray *)locations
{
    CLLocation *location = [locations lastObject];
    userLatitude =  [NSString stringWithFormat:@"%f", location.coordinate.latitude] ;
    userLongitude =  [NSString stringWithFormat:@"%f",location.coordinate.longitude];
    [locationManager stopUpdatingLocation];
}

Prosedur Cepat

Ikuti instruksi di bawah ini:

Untuk iOS-11 Untuk iOS 11 lihat Jawaban ini: akses lokasi iOS 11

Perlu Tambahkan dua Tombol ke dalam daftar dan berikan pesan seperti gambar di bawah ini:

 1. NSLocationAlwaysAndWhenInUseUsageDescription 
 2. NSLocationWhenInUseUsageDescription
 3. NSLocationAlwaysUsageDescription

masukkan deskripsi gambar di sini Untuk iOS-10 ke bawah:

masukkan deskripsi gambar di sini

import CoreLocation
class ViewController: UIViewController ,CLLocationManagerDelegate {
var locationManager = CLLocationManager()

//MARK- Update Location 
func updateMyLocation(){
    locationManager.delegate = self;
    locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers;
    if locationManager.respondsToSelector(#selector(CLLocationManager.requestWhenInUseAuthorization)){
       locationManager.requestWhenInUseAuthorization()
    }
    else{
        locationManager.startUpdatingLocation()
    }
}

Metode Delegasi

//MARK: Location Update
func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
    NSLog("Error to update location :%@",error)
}
func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
    switch status {
    case .NotDetermined: break
    case .Restricted: break
    case .Denied:
            NSLog("do some error handling")
        break
    default:
        locationManager.startUpdatingLocation()
    }
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
     let location = locations.last! as CLLocation
    var latitude = location.coordinate.latitude
    var longitude = location.coordinate.longitude

}

Harap pastikan NSLocationAlwaysUsageDescription juga ditambahkan jika tidak Anda akan mendapatkan kesalahan saat mengunggah di app store.
Alok

Pesan Anda juga harus informatif jika tidak, Apple akan menolak aplikasi saat memperbarui proses.
Alok

3

Bagi mereka yang menggunakan Xamarin , saya harus menambahkan kunci NSLocationWhenInUseUsageDescriptionke info.plist secara manual karena itu tidak tersedia di dropdown di Xamarin 5.5.3 Build 6 atau XCode 6.1 - hanya NSLocationUsageDescriptionada dalam daftar, dan itu menyebabkan CLLocationManagerterus untuk gagal diam-diam.


2
        // ** Don't forget to add NSLocationWhenInUseUsageDescription in MyApp-Info.plist and give it a string

        self.locationManager = [[CLLocationManager alloc] init];
        self.locationManager.delegate = self;
        // Check for iOS 8. Without this guard the code will crash with "unknown selector" on iOS 7.
        if ([self.locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
            [self.locationManager requestWhenInUseAuthorization];
        }
        [self.locationManager startUpdatingLocation];


    // Location Manager Delegate Methods    
    - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
    {
        NSLog(@"%@", [locations lastObject]);

}

2

Pembantu kecil untuk Anda semua yang memiliki lebih dari satu file Info.plist ...

find . -name Info.plist | xargs -I {} /usr/libexec/PlistBuddy -c 'Add NSLocationWhenInUseUsageDescription string' {} 

Ini akan menambahkan tag yang diperlukan ke semua file Info.plist di direktori saat ini (dan subfolder).

Lainnya adalah:

find . -name Info.plist | xargs -I {} /usr/libexec/PlistBuddy -c 'Set NSLocationWhenInUseUsageDescription $YOURDESCRIPTION' {} 

Ini akan menambah deskripsi Anda ke semua file.



2

Saya mendapatkan kesalahan serupa di iOS9 (bekerja dengan Xcode 7 dan Swift 2): Mencoba memulai pembaruan lokasi MapKit tanpa meminta otorisasi lokasi. Harus menghubungi - [CLLocationManager requestWhenInUseAuthorization] atau - [CLLocationManager requestAlwaysAuthorization] terlebih dahulu. Saya mengikuti tutorial tetapi tutornya menggunakan iOS8 dan Swift 1.2. Ada beberapa perubahan pada Xcode 7 dan Swift 2, saya menemukan kode ini dan berfungsi dengan baik untuk saya (jika seseorang membutuhkan bantuan):

import UIKit
import MapKit
import CoreLocation

class MapViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {

    // MARK: Properties
    @IBOutlet weak var mapView: MKMapView!

    let locationManager = CLLocationManager()

    override func viewDidLoad() {
        super.viewDidLoad()

        self.locationManager.delegate = self
        self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
        self.locationManager.requestWhenInUseAuthorization()
        self.locationManager.startUpdatingLocation()
        self.mapView.showsUserLocation = true

    }

    // MARK: - Location Delegate Methods

    func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        let location = locations.last
        let center = CLLocationCoordinate2D(latitude: location!.coordinate.latitude, longitude: location!.coordinate.longitude)
        let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 1, longitudeDelta: 1))
        self.mapView.setRegion(region, animated: true)
    }

    func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
        print("Errors: " + error.localizedDescription)
    }
}

Akhirnya, saya masukkan ke info.plist: Information Property List: NSLocationWhenInUseUsUsageDescription Value: App membutuhkan server lokasi untuk staf


2

Untuk mengakses lokasi pengguna di iOS. Anda perlu menambahkan dua tombol

NSLocationWhenInUseUsageDescription

NSLocationAlwaysUsageDescription

ke dalam file Info.plist.

    <key>NSLocationWhenInUseUsageDescription</key>
    <string>Because I want to know where you are!</string>
    <key>NSLocationAlwaysUsageDescription</key>
    <string>Want to know where you are!</string>

Lihat gambar di bawah ini.

Gambar Info.plist


1
  1. Tambahkan kunci NSLocationWhenInUseUsageDescriptionatau NSLocationAlwaysUsageDescription(gunakan GPS latar belakang) dengan string yang meminta untuk menggunakan GPS pada masing-masing info.plistdari setiap target.

  2. Minta izin dengan menjalankan:

    [self initLocationManager: locationManager];

Dimana initLocationManager:

// asks for GPS authorization on iOS 8
-(void) initLocationManager:(CLLocationManager *) locationManager{

    locationManager = [[CLLocationManager alloc]init];

    if([locationManager respondsToSelector:@selector(requestAlwaysAuthorization)])
        [locationManager requestAlwaysAuthorization];
}

Ingat bahwa jika kunci tidak pada masing info.plist-masing untuk setiap target aplikasi tidak akan meminta pengguna. Aplikasi ini ifmenyediakan kompatibilitas dengan iOS 7 dan respondsToSelector:metode ini menjamin kompatibilitas di masa depan daripada hanya menyelesaikan masalah untuk iOS 7 dan 8.


0

Masalahnya bagi saya adalah bahwa kelas yang CLLocationManagerDelegateprivat, yang mencegah semua metode delegasi dipanggil. Kira itu bukan situasi yang sangat umum tetapi saya pikir saya akan menyebutkannya kalau-kalau ada yang membantu.


0

Saya menambahkan kunci mereka di InfoPlist.stringsdalam iOS 8.4, iPad Mini 2. Ia bekerja juga. Saya tidak menetapkan kunci apa pun, seperti NSLocationWhenInUseUsageDescriptiondi Info.plist.


InfoPlist.strings :

"NSLocationWhenInUseUsageDescription" = "I need GPS information....";

Berdasarkan utas ini , katanya as in iOS 7,, dapat dilokalisasi di InfoPlist.strings. Dalam pengujian saya, kunci-kunci itu dapat dikonfigurasi secara langsung dalam file InfoPlist.strings.

Jadi hal pertama yang perlu Anda lakukan adalah menambahkan satu atau kedua kunci berikut ke file Info.plist Anda:

  • NSLocationWhenInUseUsageDescription
  • NSLocationAlwaysUsageDescription

Kedua kunci ini mengambil string yang merupakan deskripsi mengapa Anda memerlukan layanan lokasi. Anda dapat memasukkan string seperti "Diperlukan lokasi untuk mencari tahu di mana Anda berada" yang, seperti di iOS 7 , dapat dilokalisasi dalam file InfoPlist.strings.


MEMPERBARUI:

Saya pikir @IOSmetode ini lebih baik. Tambahkan kunci Info.plistdengan nilai kosong dan tambahkan string terlokalisasi ke InfoPlist.strings.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.