แอปพลิเคชัน WillEnterForeground vs. applicationDidBecomeActive, แอปพลิเคชัน WillResignActive กับ applicationDidEnterBackground


215

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

applicationWillEnterForeground vs applicationDidBecomeActive - ความแตกต่างคืออะไร

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

applicationWillResignActive vs. applicationDidEnterBackground - ความแตกต่างคืออะไร

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

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

ขอบคุณ

คำตอบ:


449

เมื่อตื่นขึ้นมาคือเรียกใช้แอป (ทั้งผ่านการกระโดดสลับแอปหรือ URL) applicationWillEnterForeground:ที่เรียกว่า มันจะดำเนินการเพียงครั้งเดียวเมื่อแอปพร้อมใช้งานหลังจากถูกใส่ลงในพื้นหลังในขณะที่applicationDidBecomeActive:อาจถูกเรียกหลายครั้งหลังจากเปิดตัว ซึ่งทำให้applicationWillEnterForeground:เหมาะสำหรับการติดตั้งที่ความต้องการที่จะเกิดขึ้นเพียงครั้งเดียวหลังจากสังข์

applicationWillEnterForeground: ถูกเรียก:

  • เมื่อแอปถูกเปิดใหม่
  • ก่อน applicationDidBecomeActive:

applicationDidBecomeActive: ถูกเรียก:

  • เมื่อเปิดแอปครั้งแรกหลังจากนั้น application:didFinishLaunchingWithOptions:
  • หลังจากapplicationWillEnterForeground:ถ้าไม่มี URL ที่จะจัดการ
  • หลังจากนั้นapplication:handleOpenURL:ถูกเรียก
  • หลังจากapplicationWillResignActive:หากผู้ใช้ละเว้นการหยุดชะงักเช่นการโทรหรือ SMS

applicationWillResignActive: ถูกเรียก:

  • เมื่อมีการหยุดชะงักเช่นโทรศัพท์
    • หากผู้ใช้รับสายapplicationDidEnterBackground:เรียก
    • หากผู้ใช้ละเว้นการโทรapplicationDidBecomeActive:ถูกเรียก
  • เมื่อกดปุ่มโฮมหรือผู้ใช้สลับแอป
  • เอกสารบอกว่าคุณควร
    • หยุดงานชั่วคราว
    • ปิดการใช้งานตัวจับเวลา
    • หยุดเกมชั่วคราว
    • ลดอัตราเฟรม OpenGL

applicationDidEnterBackground: ถูกเรียก:

  • หลังจาก applicationWillResignActive:
  • เอกสารบอกว่าคุณควรจะ:
    • ปล่อยทรัพยากรที่ใช้ร่วมกัน
    • บันทึกข้อมูลผู้ใช้
    • ตัวจับเวลาไม่ถูกต้อง
    • บันทึกสถานะแอปเพื่อให้คุณสามารถกู้คืนได้หากแอปถูกยกเลิก
    • ปิดใช้งานการอัปเดต UI
  • คุณมีเวลา 5 วินาทีในการทำสิ่งที่คุณต้องการและกลับวิธีการ
    • หากคุณไม่กลับมาภายใน ~ 5 วินาทีแอปจะถูกยกเลิก
    • คุณสามารถขอเวลาเพิ่มเติมด้วย beginBackgroundTaskWithExpirationHandler:

เอกสารอย่างเป็นทางการ


10
อีกหนึ่งสิ่งที่จะเพิ่ม หากคุณเปิดรายการแอปพื้นหลังจากแอปของคุณ (คลิกสองครั้งที่ปุ่มโฮม) จากนั้นกลับไปที่รายการนั้น (เลือกตัวอย่างแอพของคุณ) - -applicationWillEnterForeground:จะไม่ถูกเรียกเฉพาะ-applicationDidEnterBackground:(สมมติว่า iOS ไม่คิดว่าเป็นการเปิดตัวใหม่)
kpower

@kpower ใช่ว่าเพียงยากไร้คอของฉัน ... ไม่เคยจะคิดว่า willEnterForeground จะไม่ถูกเรียกในกรณีที่ว่า ...
theeye

มันapplicationWillEnterForeground:จะไม่ถูกเรียกทุกครั้งจากพื้นหลังไปยังเบื้องหน้าใช่ไหม! ฉันไม่พบกรณีที่ไม่มีการเรียกโดยไม่ต้องapplicationDidBecomeActiveหลังจากนั้น
Desmond DAI

มันไม่ถูกต้อง applicationWillResignActive สามารถเรียกใช้ได้โดยไม่ต้องใช้แอปพลิเคชันตัวแก้ไขพื้นหลัง
MichaelGofron

27

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

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
    return YES;
}

- (void)applicationWillResignActive:(UIApplication *)application
{
    /*
     Sent when the application is about to move from active to inactive state. 
     This can occur for certain types of temporary interruptions (such as an 
     incoming phone call or SMS message) or when the user quits the application 
     and it begins the transition to the background state.
     Use this method to pause ongoing tasks, disable timers, and throttle down 
     OpenGL ES frame rates. Games should use this method to pause the game.
     */
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    /*
     Use this method to release shared resources, save user data, invalidate 
     timers, and store enough application state information to restore your 
     application to its current state in case it is terminated later. 
     If your application supports background execution, this method is called 
     instead of applicationWillTerminate: when the user quits.
     */
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    /*
     Called as part of the transition from the background to the active state; 
     here you can undo many of the changes made on entering the background.
     */
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    /*
     Restart any tasks that were paused (or not yet started) while the 
     application was inactive. If the application was previously in the 
     background, optionally refresh the user interface.
     */
}

- (void)applicationWillTerminate:(UIApplication *)application
{
    /*
     Called when the application is about to terminate.
     Save data if appropriate.
     See also applicationDidEnterBackground:.
     */
}

สำหรับคำอธิบายโดยละเอียดเพิ่มเติมโปรดดูเอกสารทางการของUIApplicationDelegate


ลิงค์ตาย
Phlippie Bosman

แก้ไขคำอธิบายและลิงก์ 2019 ในตอนนี้
tomjpsun

13

ฉันยังสับสนเล็กน้อยกับคำตอบของ Dano ดังนั้นฉันจึงทำการทดสอบเล็กน้อยเพื่อรับกระแสของเหตุการณ์ในบางสถานการณ์สำหรับการอ้างอิงของฉัน แต่อาจเป็นประโยชน์กับคุณเช่นกัน นี่เป็นแอพที่ไม่ได้ใช้UIApplicationExitsOnSuspendใน info.plist สิ่งนี้ดำเนินการในเครื่องจำลอง iOS 8 + ได้รับการยืนยันด้วยอุปกรณ์ iOS 7 โปรดแก้ตัวชื่อตัวจัดการเหตุการณ์ของ Xamarin พวกมันคล้ายกันมาก

  • การเริ่มต้นและการเปิดตัวที่ตามมาทั้งหมดจากสถานะที่ไม่ทำงาน:

FinishedLaunching

OnActivated

  • การหยุดชะงัก (การโทร, เลื่อนลงบน, เลื่อนขึ้นล่าง):
  • ปุ่ม Home กดสองครั้งที่แสดงรายการแอพที่ไม่ได้ใช้งานแล้วเลือกแอพของเราอีกครั้ง:

OnResignActivation


OnActivated

  • ปุ่ม Home กดสองครั้งที่แสดงแอพที่ไม่ใช้งานเลือกแอพอื่นจากนั้นเปิดแอปของเราใหม่:
  • ปุ่ม Home กดครั้งเดียวแล้วเปิดใหม่:
  • ล็อค (ปุ่มเปิด / ปิด) จากนั้นปลดล็อค:

OnResignActivation

DidEnterBackground


WillEnterForeground

OnActivated

  • ปุ่ม Home กดสองครั้งและยกเลิกแอปของเรา: (การเปิดใหม่ในภายหลังเป็นกรณีแรก)

OnResignActivation

DidEnterBackground

DidEnterBackground (iOS 7 เท่านั้น)

ใช่DidEnterBackgroundมีการเรียกสองครั้งในอุปกรณ์ iOS7 ทั้งสองครั้งสถานะ UIApplication เป็นพื้นหลัง อย่างไรก็ตาม iOS 8 simulator ไม่ได้ จำเป็นต้องทำการทดสอบบนอุปกรณ์ iOS 8 ฉันจะอัปเดตคำตอบของฉันเมื่อฉันได้รับมันหรือคนอื่นสามารถยืนยันได้


9

applicationWillEnterForeground ถูกเรียก:

เมื่อแอพเปิดใหม่ (มาจากพื้นหลังเป็นพื้นหน้า) วิธีนี้ไม่ได้เรียกใช้เมื่อแอพเริ่มขึ้นเป็นครั้งแรกเช่นเมื่อapplicationDidFinishLaunchถูกเรียก แต่เมื่อมาจากพื้นหลัง applicationDidBecomeActive

applicationDidBecomeActive ถูกเรียก

เมื่อแอปเปิดตัวครั้งแรกหลังจากdidFinishLaunching นั้นapplicationWillEnterForegroundหากไม่มี URL ที่จะจัดการ หลังจากนั้นapplication:handleOpenURL:ถูกเรียก หลังจากapplicationWillResignActiveหากผู้ใช้ละเว้นการหยุดชะงักเช่นการโทรหรือ SMS หลังจากหายไปจาก AlertView ที่ใดก็ได้จากแอปพลิเคชัน


คุณมีโอกาสรู้ไหมว่าสิ่งนี้เปลี่ยนไปจาก iOS 7 หรือไม่? ฉันจำได้ว่า (ฉันอาจเข้าใจผิด) กำลังทำสิ่งต่าง ๆ (iOS 5/6) ในแอปพลิเคชัน WillEnterForeground และเรียกใช้เมื่อแอปเปิดตัวครั้งแรก ณ ตอนนี้ใน 7.1 / 8 คุณสมัครถูกต้อง WillEnterForeground จะไม่ถูกเรียกเมื่อเปิดตัว
จินยองคิม

7

applicationWillResignActive ถูกเรียกเมื่อระบบขอสิทธิ์ (ใน iOS 10) ในกรณีที่มีใครบางคนประสบปัญหาเดียวกับฉัน ...


แนวคิดใดที่เรียกวิธีหลังจากการขออนุญาตป๊อปยกเลิก? ฉันมีปัญหานี้stackoverflow.com/questions/26059927/…
Suresh Durishetti

5

ใน iOS 8+ มีความแตกต่างเล็กน้อย แต่สำคัญสำหรับการโทรศัพท์

ใน iOS 7 หากผู้ใช้โทรออกทั้งแอปพลิเคชัน WillResignActive: และ applicationDidEnterBackground: จะถูกเรียก แต่ในแอปพลิเคชันเฉพาะ iOS 8+WillResignActive: ถูกเรียกใช้


1

สำหรับ iOS 13+ จะใช้วิธีการต่อไปนี้:

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