พฤติกรรมของ API ตำแหน่งที่เปลี่ยนแปลงอย่างมีนัยสำคัญเมื่อยุติ / ระงับ?


108

นี่คือส่วนจากเอกสารCLLocationManager ที่อธิบายลักษณะการทำงานของแอปด้วยstartMonitoringSignificantLocationChanges :

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

ดังนั้นความเข้าใจของผมคือว่าถ้ายุติแอปของคุณ (และผมถือว่าถ้าคุณไม่โทรstopMonitoringSignificantLocationChangesจากapplicationWillTerminate ) คุณจะได้รับการตื่นขึ้นมาด้วยUIApplicationLaunchOptionsLocationKeyพารามิเตอร์การประยุกต์ใช้: didFinishLaunchingWithOptions เมื่อมาถึงจุดที่คุณสร้างของคุณCLLocationManagerโทรstartMonitoringSignificantLocationChangesและทำการประมวลผลที่ตั้งของพื้นหลังของคุณสำหรับระยะเวลาที่ จำกัด ดังนั้นฉันสบายดีกับบิตนี้

ย่อหน้าก่อนหน้านี้พูดถึงสิ่งที่เกิดขึ้นเมื่อแอปถูกยุติเท่านั้นไม่ได้แนะนำสิ่งที่คุณทำเมื่อแอปพลิเคชันถูกระงับ เอกสารสำหรับdidFinishLaunchingWithOptionsกล่าวว่า:

แอปพลิเคชันติดตามการอัปเดตตำแหน่งในพื้นหลังถูกล้างและตอนนี้ได้เปิดใช้งานใหม่แล้ว ในกรณีนี้พจนานุกรมจะมีคีย์ที่ระบุว่าแอปพลิเคชันถูกเปิดใช้งานอีกครั้งเนื่องจากเหตุการณ์ตำแหน่งใหม่

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

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

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

สิ่งนี้แสดงว่าคุณถูกปลุกด้วยข้อมูลตำแหน่งหากแอปของคุณถูกระงับ แต่ไม่ได้ระบุว่าคุณตื่นขึ้นมาอย่างไร:

  • ที่ไม่UIApplicationDelegateได้รับการติดต่อกลับบอกฉันว่าฉันกำลังกลับมาจากสถานะที่ถูกระงับในสภาพพื้นหลัง?
  • ผู้จัดการสถานที่ (ซึ่งถูกทำให้แห้งเมื่อแอปถูกระงับ) เริ่มรับlocationManager: didUpdateToLocation: fromLocation callbacks หรือไม่
  • ฉันต้องติดตั้งโค้ดในข้อความdidUpdateToLocationของฉันซึ่งจะตรวจสอบสถานะแอปพลิเคชันและทำการประมวลผลน้อยที่สุดหากอยู่ในโหมดพื้นหลังหรือไม่

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

คำตอบ:


80

ตั้งแต่ฉันถามคำถามนี้ฉันได้ทำการทดสอบเล็กน้อย (ส่วนใหญ่บนรถไฟระหว่างบ้านและที่ทำงาน) และได้รับการยืนยันว่าพฤติกรรมของแอปที่ถูกระงับเป็นไปตามที่ฉันสงสัยในตอนท้ายของคำถาม

นั่นคือแอพพลิเคระงับของคุณจะตื่นขึ้นมาคุณจะไม่ได้รับการเรียกกลับใด ๆ เกี่ยวกับผู้รับมอบสิทธิ์ของแอปแทนคุณได้รับการปรับปรุงสถานที่ของคุณผ่านการมีอยู่ของคุณCLLocationManagerDelegate คุณสามารถตรวจพบว่าคุณกำลังทำงานอยู่เบื้องหลังโดยการตรวจสอบapplicationStateและทำงานอย่าง จำกัด สำหรับกรณีที่คุณถูกปลุกจากสถานะที่ถูกระงับเพื่อทำการประมวลผลตำแหน่ง

[UIApplication sharedApplication].applicationState == UIApplicationStateBackground

ฉันได้ข้อสรุปนี้พร้อมกับสายรัดทดสอบสถานที่ซึ่งคุณสามารถดาวน์โหลดและทดลองใช้ได้ เป็นแอปที่ค่อนข้างเรียบง่ายที่ให้คุณเปิดการเปลี่ยนแปลงที่สำคัญและ GPS เปลี่ยน API ผ่าน UI และบันทึกคำตอบทั้งหมดที่คุณได้รับกลับมา

NBจุดที่หกในคำตอบก่อนหน้านี้ไม่ถูกต้อง แอปที่ถูกระงับการทำให้แห้งแบบ Freezeจะได้รับการเรียกกลับจากCLLocationManagerDelegateเมื่อถูกปลุกจากสถานะที่ถูกระงับ


1
ขีดฆ่า # 6 ในคำตอบของฉันเพื่อไม่ให้คนสับสน
Aaron

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

ขอบคุณมากสำหรับแอปตัวอย่างนี้มีประโยชน์มากสำหรับฉัน ฉันมีคำถาม: จะเกิดอะไรขึ้นถ้าฉันใช้บริการตำแหน่งมาตรฐานในพื้นหลังซึ่งไม่ใช่บริการสำคัญแอปจะเปิดใช้งานอีกครั้งหลังจากการยุติในกรณีนั้นหรือไม่ ฉันถามคำถามนี้โดยละเอียดที่นี่ฉันจะดีใจถ้าคุณช่วยให้ฉันเบาขึ้น:] stackoverflow.com/questions/12239967/…
aslisabanci

2
ไม่ทำงานบน ios7 stackoverflow.com/questions/18946881/…
Igor

คุณทราบหรือไม่ว่าแอปของคุณใช้เวลานานเท่าใดในการยุติการให้บริการ แล้วรับ appDelegate callback แทน? (เหมือน 30 นาทีหรือ 2 ชม. หรือ 5 ชม.) เหตุผลที่ผมถามก็เพราะว่าผมตั้งค่าภูมิภาคเพื่อตรวจสอบ พยายามหลายครั้งเพื่อดูแอปของฉันเปิดตัว แต่มีเพียงครั้งเดียวที่ฉันเปิดแอปขึ้นมาใหม่ ครั้งอื่น ๆdidExitRegionโทรกลับ แต่ผมก็ไม่สามารถที่จะstartLocationUpdatesออกจากที่นั่นเป็นมันไม่ได้ผ่านการเปิดตัวแอพพลิเค ...
น้ำผึ้ง

25

ความเข้าใจของฉันมีดังต่อไปนี้ (ฉันอยู่ระหว่างการเขียนแอปพลิเคชันที่อาศัย API นี้ แต่ยังไม่เสร็จสิ้นองค์ประกอบนี้เพียงพอที่จะเริ่มการทดสอบ):

  1. แอปพลิเคชันของคุณทำงานเป็นครั้งแรกคุณลงทะเบียนเพื่อstartMonitoringSignificantLocationChangesและจัดเตรียมฟังก์ชันการโทรกลับ ในขณะที่แอปพลิเคชันของคุณกำลังทำงานแอปพลิเคชันจะโทรกลับเมื่อใดก็ตามที่ได้รับการเปลี่ยนแปลงที่สำคัญ
  2. หากใบสมัครของคุณจะถูกนำไปพื้นหลัง UIApplication จะได้รับapplicationWillResignActiveตามapplicationDidEnterBackground
  3. หากแอปพลิเคชันของคุณถูกฆ่าในขณะที่ถูกระงับในพื้นหลังคุณจะไม่ได้รับแจ้ง แต่ถ้าใบสมัครของคุณถูกฆ่าตายในขณะที่มีการทำงาน (เบื้องหน้าหรือพื้นหลังเพื่อความรู้ของฉัน) คุณจะได้รับช่วงเวลาที่มีapplicationWillTerminate คุณไม่สามารถขอเวลาพื้นหลังเพิ่มเติมจากฟังก์ชันนี้ได้
  4. แม้จะถูกฆ่าในพื้นหลังระบบปฏิบัติการจะเปิดแอปพลิเคชันของคุณอีกครั้ง หากแอปพลิเคชันของคุณเปิดตัวโดยระบบปฏิบัติการเพื่อทำการเปลี่ยนแปลงคุณจะได้รับการเรียกให้แอปพลิเคชัน didFinishLaunchingWithOptions :

    if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey])

    จะช่วยให้คุณทราบว่าคุณกลับมาจากการเปลี่ยนตำแหน่งพื้นหลังหรือไม่

  5. ถ้าแทนคุณกำลังทำงานในพื้นหลังและแอปของคุณ relaunched ด้วยตนเองโดยผู้ใช้คุณจะได้รับapplicationWillEnterForegroundตามapplicationDidBecomeActive
  6. ไม่ว่าจะเกิดขึ้นอย่างไรเมื่อแอปพลิเคชันของคุณเปิดใช้งานอีกครั้ง (เว้นแต่ว่าจะยังคงทำงานอยู่ในพื้นหลังอันเป็นผลมาจากงานพื้นหลังและงานดังกล่าวได้เริ่มตรวจสอบการเปลี่ยนแปลงแล้ว) คุณต้องแจ้งให้เริ่มการตรวจสอบอย่างชัดเจนเพื่อstartMonitoringSignificantLocationChangesอีกครั้งเนื่องจากการเรียกกลับไม่เป็น ติดอีกต่อไปหลังจาก "ทำแห้งแบบเยือกแข็ง" และใช่คุณต้องติดตั้งโค้ดใน didUpdateToLocation เมื่อคุณได้แนบตัวจัดการตำแหน่งบางประเภทอีกครั้งเมื่อกลับมาจากสถานะที่ถูกระงับ

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

โอ้และถ้าโชคไม่ดีคุณปล่อยแอพที่ทำในสิ่งที่ฉันอยากทำฉันอาจจะร้องไห้ :)

โชคดี!


1
@Tegeril +1 ขอบคุณสำหรับคำตอบ ฉันเริ่มได้ยินเสียงจิ้งหรีดในเรื่องนี้ :) ฉันแปลกใจที่แอพเริ่มจากการถูกระงับจำเป็นต้องโทรใหม่ startMonitoringSignificantLocationChanges คุณมีลิงค์ไปยัง doco ที่อธิบายไว้หรือไม่? ความเข้าใจของฉันคือการโหลดจากสถานะที่ถูกระงับจะทำให้ออบเจ็กต์ทั้งหมดของคุณเป็นอินสแตนซ์เหมือนเดิมเมื่อแอปถูกระงับ ดังนั้นฉันคาดว่าคำขอเปลี่ยนแปลงที่สำคัญจะมีผล
RedBlueThing

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

Morgan Grainger ในฟอรัม Dev แนะนำสิ่งนี้: "คุณต้องสร้าง CLLocationManager ตั้งค่าผู้รับมอบสิทธิ์และเรียกใช้ startMonitoringSignificantLocationChanges เมื่อแอปพลิเคชันของคุณเปิดตัวมิฉะนั้นตำแหน่งหลักจะไม่มีที่สำหรับส่งการอัปเดต" ในบริบทของการรีสตาร์ทแอปพลิเคชันโดยไม่คำนึงถึงสถานะที่สิ้นสุดหรือถูกระงับ จาก "แอปถูกเปิดใช้งานอีกครั้งหลังจาก startMonitoringSignificantLocationChanges แล้วตอนนี้คืออะไร"
แอรอน

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

1
ฉันดีใจที่มีบางสิ่งที่สรุปออกมาจากสิ่งนี้น่าจะช่วยฉันได้ในอนาคต :)
แอรอน

1

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

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

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