ช่องโต้ตอบการอนุญาตตำแหน่งปัจจุบันจะหายไปเร็วเกินไป


175

แอพของฉันรับตำแหน่งของผู้ใช้รับพิกัดและให้ระยะทางไปหรือกลับจากปลายทางหรือที่มาของพวกเขา จุดหมายปลายทางที่เป็นไปได้ทั้งหมดเหล่านี้จะแสดงในมุมมองตารางดังนั้นฉันจะให้ผู้ใช้ประสานงานพร้อมกันกับการเติมตาราง สิ่งเดียวคือมุมมองการแจ้งเตือนที่ขอตำแหน่งของผู้ใช้จะปรากฏขึ้นและหายไปอย่างรวดเร็วจึงเป็นไปไม่ได้ที่จะคลิก!

มีวิธีใดที่จะแสดงการแจ้งเตือนนี้ด้วยตนเองเมื่อแอปโหลดครั้งแรก ฉันพยายามรับตำแหน่งของผู้ใช้เมื่อแอปโหลดขึ้นเพื่อลองและบังคับให้การแจ้งเตือนปรากฏขึ้น แต่นั่นไม่ได้ผล

คำตอบ:


699

ในขณะที่ยากต่อการติดตามการแก้ปัญหาสำหรับเรื่องนี้ค่อนข้างง่าย

จากการทดลองและข้อผิดพลาดมากมายฉันพบว่าในขณะที่กล่องโต้ตอบการเข้าถึงตำแหน่งปรากฏขึ้นเมื่อคุณพยายามเข้าถึงบริการบอกตำแหน่งในแอปเป็นครั้งแรกกล่องโต้ตอบจะหายไปเอง (โดยไม่มีการโต้ตอบกับผู้ใช้) CLLocationManagerวัตถุถูกปล่อยออกมาก่อน ผู้ใช้ตอบกลับไปยังกล่องโต้ตอบ

ฉันกำลังสร้างCLLocationManagerตัวอย่างในviewDidLoadวิธีการของฉัน เนื่องจากนี่เป็นอินสแตนซ์ในตัวเครื่องของวิธีการนั้นอินสแตนซ์ถูกปล่อยโดย ARC หลังจากวิธีการดำเนินการเสร็จสิ้น ทันทีที่มีการเผยแพร่อินสแตนซ์กล่องโต้ตอบจะหายไป การแก้ปัญหาค่อนข้างง่าย เปลี่ยนCLLocationManagerอินสแตนซ์จากการเป็นตัวแปรระดับเมธอดเป็นตัวแปรอินสแตนซ์ระดับคลาส ตอนนี้CLLocationManagerอินสแตนซ์จะถูกเปิดใช้งานเมื่อคลาสไม่ได้ถูกโหลด


117
ฉันหวังว่าฉันจะให้ +100
coder

1
เพิ่งพบปัญหาเดียวกันกับ Xamarin.iOS ทำให้ขอบเขตคลาส CLLocationManager และกล่องโต้ตอบยังคงมองเห็นได้
Krumelur

1
Yaaaaa .... ถ้าคุณสามารถไปข้างหน้าและยกระดับตัวเองนั่นจะ greeeeeaaaat (อย่างจริงจังนี่เป็นเรื่องใหญ่สำหรับฉันเช่นกัน)
Garfonzo

2
ฉันต้องเข้าร่วมปาร์ตี้นี้ด้วย ที่นี่รับอินเทอร์เน็ต High Five จากฉัน!
Matthieu Riegler

3
ใครก็ตามที่มีปัญหานี้ใน Swift ต้องแน่ใจว่าคุณย้ายการประกาศของ LocationManager นอก viewDidLoad ไชโย!
KD

5

อาการเดียวกันสาเหตุที่แตกต่าง: อย่าโทรติดต่อกันstartUpdatingLocationมากกว่าหนึ่งครั้งมากกว่าหนึ่งครั้งในแถว

ฉันมีสิ่งที่มีโครงสร้างโดยไม่ตั้งใจเช่นรหัสถูกโทรโดยไม่ตั้งใจ startUpdatingLocationครั้งที่สองในแถวซึ่งดูเหมือนจะไม่ดี อาจมีบางอย่างเกี่ยวกับการเลือกคิวเนื่องจากฉันรอเพื่อเริ่มอัปเดตที่รอผลการขอเครือข่าย แต่ฉันไม่จำเป็นต้องใช้เวทมนตร์ GCD ใด ๆ ในการแก้ไข ... เพียงแค่ต้องการให้แน่ใจว่าฉัน ไม่ได้เริ่มต้นซ้ำ

หวังว่าใครบางคนสามารถได้รับประโยชน์จากความเจ็บปวดของฉัน :)


5

ฉันต้องเผชิญกับสถานการณ์ที่คล้ายกัน หลังจากตรวจแก้จุดบกพร่องฉันพบ

let locationManager = CLLocationManager()

ถูกเรียกในขอบเขตวิธี แต่มันควรจะเรียกว่าทั่วโลก

ทำไม?

สรุป locationManager ได้รับการปล่อยตัวหลังจากที่วิธีการได้กลับมา แต่ไม่ควรปล่อยจนกว่าผู้ใช้จะให้หรือไม่อนุญาต


4

ฉันตกอยู่ในปัญหาเดียวกัน (อย่างน้อยก็ตามอาการ) ในกรณีของฉันปัญหาเกิดขึ้นใน- (void)applicationWillResignActive:(UIApplication *)application;วิธีการที่ฉันปล่อยCLLocationManagerอินสแตนซ์ของฉันเป็นส่วนหนึ่งของการเตรียมการเปลี่ยนพื้นหลัง เมื่อฉันลบมันและทิ้งไว้เฉพาะใน- (void)applicationDidEnterBackground:(UIApplication *)application;ปัญหาจะหายไป
ส่วนที่ยุ่งยากคือการแจ้งเตือนตำแหน่งหลักจะระงับแอปพลิเคชันของคุณในขณะที่ยังอยู่ในเบื้องหน้า
หวังว่ามันจะช่วยคุณได้ใช้เวลามากในการหาไอ้นั่น :)


4

ฉันรู้ว่านี่เป็นคำตอบที่ช้ามาก แต่อาจช่วยใครซักคน ฉันยังประสบปัญหาเดียวกันและใช้เวลาหนึ่งชั่วโมงเพื่อระบุปัญหา ตอนแรกรหัสของฉันเป็นแบบนี้

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

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

    [locationManager release];

ตอนนี้การแจ้งเตือนตำแหน่งหายไปอย่างรวดเร็ว เมื่อฉันไม่ใส่เครื่องหมายข้อคิดเห็นบรรทัดสุดท้ายมันจะทำงานได้อย่างถูกต้อง

   // [locationManager release];

3
นี่เป็นเรื่องจริง ข้อแม้เดียวที่ฉันจะเพิ่มในคำตอบนี้คือเมื่อโครงการของคุณเปิดใช้งาน ARC คุณไม่จำเป็นต้องรวมคำชี้แจงการเปิดตัวในรหัสของคุณและคุณจะยังคงพบปัญหานี้ วิธีเดียวที่จะแก้ไขปัญหาในสถานการณ์นั้นคือทำให้ตัวแปรระดับคลาสแทนระดับวิธี
Zoli

3

ฉันพบปัญหานี้ แต่การแก้ไขปัญหาในกรณีของฉันแตกต่างจากคำตอบที่ยอมรับโดยสิ้นเชิง

ในแอพของฉันฉันโทรstopUpdatingLocationจากapplicationWillResignActiveจากนี่เป็นปัญหาเนื่องจากapplicationWillResignActiveถูกเรียกเมื่อกล่องโต้ตอบการอนุญาตปรากฏขึ้น นี่เป็นสาเหตุที่เกิดstopUpdatingLocationขึ้นทันทีหลังจากstartUpdatingLocationนั้นซึ่งเป็นเหตุผลที่กล่องโต้ตอบจะหายไปทันที

การแก้ปัญหาคือเพียงโทรstopUpdatingLocationจากapplicationDidEnterBackgroundแทน


2

สิ่งนี้เกิดขึ้นกับฉันขณะใช้ iOS Simulator ฉันพิจารณาแล้วว่ามันเกิดขึ้นเพราะ Run Scheme ของฉันจำลองตำแหน่ง ฉันคิดว่านี่มีผลเช่นเดียวกับการโทรlocationManager.startUpdatingLocation()เมื่อเปิดตัวและดังนั้นจึงเป็นการปิดกล่องโต้ตอบ

การยกเลิกการทำเครื่องหมายในช่อง "อนุญาตการจำลองตำแหน่ง" ในกล่องโต้ตอบแก้ไขแบบแผนช่วยแก้ไขปัญหาได้ เมื่อทำงานได้ตามที่คุณต้องการและตั้งค่าการอนุญาตคุณสามารถเปิดใช้งานการจำลองตำแหน่งอีกครั้งและตัวจำลองจะทำงานได้ดีหลังจากนั้น


สิ่งนี้ได้ผลสำหรับฉัน อย่างน้อยฉันก็จะเห็นกล่องโต้ตอบ
CppChase

2

Swift 4 และ iOS 11 :

ตรวจสอบให้แน่ใจว่าได้เพิ่มบรรทัดความเป็นส่วนตัว (ทั้งเสมอและเมื่อใช้ ) ลงใน.plistไฟล์ของคุณและเพิ่มCoreLocationFramework ในโครงการของคุณ

กล่องโต้ตอบการอนุญาตตำแหน่งปรากฏขึ้นอย่างถูกต้องเมื่อฉันเปลี่ยน:

locationManager.requestAlwaysAuthorization()

ด้วย:

locationManager.requestWhenInUseAuthorization()

PS . ฉันได้พยายามทุกคำแนะนำและทุกล้มเหลว (การอนุญาตการร้องขอไปยังviewDidLoad, varแทนletสำหรับ locationManager ไม่ได้เริ่มต้นstartUpdatingLocation()หลังจาก request..I คิดว่ามันเป็นข้อผิดพลาดและผมหวังว่าพวกเขาจะแก้ปัญหาได้โดยเร็วที่สุดเท่าที่เป็นไปได้ ..


ฉันได้ปฏิบัติตามคำแนะนำทั้งหมดด้วย แต่ฉันก็ยังมีปัญหาเดิมอยู่เสมอ กล่องโต้ตอบการอนุญาตให้ใช้สถานที่ปรากฏขึ้นชั่วครู่แล้วหายไปทันที จากนั้นสิทธิ์การใช้งานไดอะล็อกการแจ้งเตือนของฉันจะปรากฏขึ้น (อันนี้เป็นเรื่องปกติ) เมื่อฉันกดยอมรับหรือปฏิเสธการอนุญาตให้ใช้ตำแหน่งอื่นจะปรากฏขึ้น (คราวนี้จะยังคงอยู่

@BitoQ ใช่สำหรับฉันด้วย สถานการณ์เดียวกัน แต่อย่างน้อยเราจะเห็นกล่องโต้ตอบนี้ฉันหวังว่าด้วย iOS 11.1 ถัดไปพวกเขาจะแก้ไขข้อผิดพลาดนี้ ..
Alessandro Ornano

1

โซลูชัน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
    }
}

0

คุณกำหนดตัวแปร locationManager เป็นวัตถุส่วนใหญ่

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

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

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

0

ฉันได้พบกับสถานการณ์เดียวกันกับคุณ

  • โซลูชันของฉันเปลี่ยนจากตัวแปรโลคัลเป็นอินสแตนซ์สมาชิก
  • สาเหตุก็คืออินสแตนซ์ในเครื่องไม่ถูกต้องหลังจากวิธีการเสร็จสิ้นซึ่งรวมถึงตัวแปรท้องถิ่น (ของการขยาย locationManager ของฉัน)
  • Env ของฉัน: Xcode9.3.1
#import 
@Interface ViewController ()

@end

@implementation ViewController
@synthesize locManager; // หลัง
- (เป็นโมฆะ) viewDidLoad {
    [super viewDidLoad];
    // ทำการตั้งค่าเพิ่มเติมหลังจากโหลดมุมมองโดยทั่วไปจากปลายปากกา

    // MyLocationService * locManager = [[BSNLocationService alloc] init: nil]; // ก่อนหน้า loc ผู้รับมอบสิทธิ์ไม่ทำงานเนื่องจากอินสแตนซ์ไม่ถูกต้องหลังจากวิธีนี้
    self-> locManager = [[MyLocationService alloc] init: nil]; // หลัง
    locManager.startService;
}

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.