objective-c - مشاركة - وتمكينك




خدمات الموقع لا تعمل في iOS 8 (18)

  1. Add key NSLocationWhenInUseUsageDescription or NSLocationAlwaysUsageDescription (background GPS use) with string asking to use GPS on each info.plist from each target.

  2. Ask for permission by running:

    [self initLocationManager:locationManager];

Where initLocationManager is:

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

    locationManager = [[CLLocationManager alloc]init];

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

Remember that if the keys are not on each info.plist for each target the app will not ask the user. The if provides compatibility with iOS 7 and the respondsToSelector: method guarantees future compatibility rather than just solving the issue for iOS 7 and 8.

لا يعمل تطبيقي الذي يعمل بشكل جيد على iOS 7 مع iOS 8 SDK.

لا CLLocationManager موقعًا ، ولا أرى تطبيقي ضمن الإعدادات -> خدمات الموقع أيضًا. أجريت بحثًا في Google حول المشكلة ، ولكن لم يحدث شيء. ماذا يمكن أن يكون الخطأ؟


أحصل على خطأ مشابه في iOS9 (العمل مع Xcode 7 و Swift 2): محاولة بدء تحديثات موقع MapKit دون المطالبة بتفويض الموقع. يجب الاتصال - [CLLocationManager requestWhenInUseAuthorization] أو - [CLLocationManager requestAlwaysAuthorization] أولاً. كنت أتابع برنامجًا تعليميًا ولكن المعلم كان يستخدم iOS8 و Swift 1.2. هناك بعض التغييرات في Xcode 7 و Swift 2 ، وجدت هذه الشفرة وهي تعمل بشكل جيد بالنسبة لي (إذا احتاج شخص ما إلى مساعدة):

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

وأخيرًا ، أضع ذلك في info.plist: قائمة بيانات المعلومات: NSLocationWhenInUseUsageDescription Value: يحتاج التطبيق إلى خوادم الموقع للموظفين


الحل مع التوافق مع الإصدارات السابقة:

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

الإعداد NSLocationWhenInUseUsageDescription الرئيسية في Info.plist الخاص بك


انتهيت من حل مشكلتي الخاصة.

على ما يبدو في iOS 8 SDK ، requestWhenInUseAuthorization (لموقع الخلفية) أو requestWhenInUseAuthorization (الموقع فقط عند المقدمة) استدعاء CLLocationManager مطلوب قبل بدء تحديثات الموقع.

يجب أن يكون هناك أيضًا NSLocationAlwaysUsageDescription أو NSLocationWhenInUseUsageDescription في Info.plist مع رسالة ليتم عرضها في Info.plist . إضافة هذه تحل مشكلتي.

آمل أن يساعد شخص آخر.

تعديل: للحصول على مزيد من المعلومات الشاملة ، ألقِ نظرة على: nevan.net/2014/09/core-location-manager-changes-in-ios-8



حل بتوافق مع الإصدارات السابقة لا ينتج عنه تحذيرات 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];
}

الإعداد NSLocationWhenInUseUsageDescription الرئيسية في Info.plist الخاص بك.

بالنسبة إلى الإصدار 11.0 والإصدارات الأحدث من نظام التشغيل iOS : الإعداد NSLocationAlwaysAndWhenInUseUsageDescription في Info.plist . جنبا إلى جنب مع مفاتيح 2 أخرى.


قبل [locationManager startUpdatingLocation]; ، قم بإضافة طلب خدمات موقع iOS8:

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

عدّل Info.plist وأضف مفتاح NSLocationAlwaysUsageDescription مع قيمة السلسلة التي سيتم عرضها للمستخدم (على سبيل المثال ، We do our best to preserve your battery life. ) We do our best to preserve your battery life.

إذا كان تطبيقك يحتاج إلى خدمات الموقع فقط أثناء فتح التطبيق ، فيمكنك استبدال:

requestWhenInUseAuthorization with requestWhenInUseAuthorization and

NSLocationAlwaysUsageDescription with NSLocationWhenInUseUsageDescription .


كنت أسحب شعري بنفس المشكلة. يعطيك Xcode الخطأ:

محاولة بدء تحديثات موقع MapKit دون المطالبة بتفويض الموقع. يجب الاتصال -[CLLocationManager requestWhenInUseAuthorization] أو -[CLLocationManager requestAlwaysAuthorization] أولاً.

ولكن حتى في حالة تنفيذ أحد الأساليب المذكورة أعلاه ، فلن يُطالب المستخدم ما لم يكن هناك إدخال في info.plist لـ NSLocationAlwaysUsageDescription أو NSLocationWhenInUseUsageDescription .

أضف السطور التالية إلى info.plist حيث تمثل قيم السلسلة السبب الذي تحتاج إليه للوصول إلى موقع المستخدمين

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

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

أعتقد أن هذه الإدخالات قد تكون مفقودة منذ أن بدأت هذا المشروع في Xcode 5. أعتقد أن Xcode 6 قد يضيف إدخالات افتراضية لهذه المفاتيح ولكن لم يتم تأكيدها.

يمكنك العثور على مزيد من المعلومات حول هذين الإعدادين here


للتأكد من توافقها مع نظام التشغيل iOS 7 ، يجب عليك التحقق مما إذا كان المستخدم يعمل بنظام iOS 8 أو iOS 7. على سبيل المثال:

#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];

للوصول إلى موقع المستخدم في iOS 8 ، سيكون عليك إضافة ،

NSLocationAlwaysUsageDescription in the Info.plist 

سيطلب هذا من المستخدم الحصول على إذن للحصول على موقعه الحالي.


مساعد صغير لكل من لديه أكثر من ملف Info.plist ...

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

سيقوم بإضافة العلامة المطلوبة إلى كافة ملفات Info.plist في الدليل الحالي (والمجلدات الفرعية).

آخر هو:

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

سيضيف وصفك إلى جميع الملفات.


من أجل الوصول إلى موقع المستخدمين في دائرة الرقابة الداخلية. تحتاج إلى إضافة مفتاحين

NSLocationWhenInUseUsageDescription

NSLocationAlwaysUsageDescription

في ملف 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>

انظر أدناه الصورة.


وفقًا لمستندات Apple:

اعتبارًا من iOS 8 ، NSLocationWhenInUseUsageDescription وجود NSLocationWhenInUseUsageDescription أو قيمة مفتاح NSLocationAlwaysUsageDescription في ملف Info.plist لتطبيقك. ومن الضروري أيضًا طلب إذن من المستخدم قبل التسجيل للحصول على تحديثات الموقع ، إما عن طريق الاتصال [self.myLocationManager requestWhenInUseAuthorization] أو [self.myLocationManager requestAlwaysAuthorization] وفقًا [self.myLocationManager requestAlwaysAuthorization] . سيتم عرض السلسلة التي أدخلتها في Info.plist في مربع الحوار التالي.

إذا منح المستخدم الإذن ، فسيتم العمل كالمعتاد. إذا رفضوا الإذن ، فلا يتم إبلاغ المفوض بتحديثات الموقع.


أحد الأخطاء الشائعة لمطوري Swift:

تأكد أولاً من إضافة قيمة إلى NSLocationWhenInUseUsageDescription إما ل NSLocationWhenInUseUsageDescription أو NSLocationAlwaysUsageDescription .

إذا كنت لا تزال لا ترى نافذة منبثقة تطلب منك التفويض ، فابحث لمعرفة ما إذا كنت تقوم بوضع السطر var locationManager = CLLocationManager() في طريقة viewDidLoad View Controller الخاصة viewDidLoad . إذا قمت بذلك ، حتى إذا قمت بالاتصال على locationManager.requestWhenInUseAuthorization() ، فلن يظهر أي شيء. وهذا لأنه بعد تنفيذ viewDidLoad ، يتم إلغاء تخصيص متغير locationManager (مسح).

الحل هو تحديد موقع السطر var locationManager = CLLocationManager() أعلى طريقة الفئة.


I add those key in InfoPlist.strings in iOS 8.4, iPad mini 2. It works too. I don't set any key, like NSLocationWhenInUseUsageDescription , in my Info.plist .

InfoPlist.strings :

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

nevan.net/2014/09/core-location-manager-changes-in-ios-8 , it said, as in iOS 7 , can be localized in the InfoPlist.strings. In my test, those keys can be configured directly in the file InfoPlist.strings .

So the first thing you need to do is to add one or both of the > following keys to your Info.plist file:

  • NSLocationWhenInUseUsageDescription
  • NSLocationAlwaysUsageDescription

Both of these keys take a string which is a description of why you need location services. You can enter a string like “Location is required to find out where you are” which, as in iOS 7 , can be localized in the InfoPlist.strings file.

UPDATE:

I think @IOS 's method is better. Add key to Info.plist with empty value and add localized strings to InfoPlist.strings .


The problem for me was that the class that was the CLLocationManagerDelegate was private, which prevented all the delegate methods from being called. Guess it's not a very common situation but thought I'd mention it in case t helps anyone.


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


}

وإلى ملف info.plist الخاص بك


- (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];
        }
    }

في نظام التشغيل iOS 8 ، يلزمك إجراء أمرين إضافيين للحصول على عمل في الموقع: أضف مفتاحًا إلى Info.plist واطلب تفويضًا من مدير الموقع ليطلب منه البدء. هناك نوعان من مفاتيح Info.plist لتفويض الموقع الجديد. واحد أو كل من هذه المفاتيح مطلوب. إذا لم يكن أي من المفاتيح موجودًا ، فيمكنك الاتصال startUpdatingLocation ولكن لن يتم تشغيل مدير الموقع فعليًا. لن يرسل رسالة فاشلة إلى المفوض سواء (بما أنه لم يبدأ ، فلن يفشل). سوف تفشل أيضًا إذا أضفت مفتاحًا واحدًا أو كليهما ولكنك تنسى طلب الترخيص بشكل صريح. لذا فإن أول شيء يجب عليك فعله هو إضافة واحد من المفاتيح التالية إلى ملف Info.plist:

  • NSLocationWhenInUseUsageDescription
  • NSLocationAlwaysUsageDescription

كل من هذه المفاتيح تأخذ سلسلة

وهو وصف لماذا تحتاج إلى خدمات الموقع. يمكنك إدخال سلسلة مثل "الموقع مطلوب لمعرفة مكان وجودك" والذي يمكن ، كما هو الحال في نظام التشغيل iOS 7 ، أن يتم ترجمته في ملف InfoPlist.strings.





cllocationmanager