iOS จะเปิดแอพของฉันเป็นพื้นหลังหรือไม่หากผู้ใช้นั้นถูกบังคับให้ออกจากระบบ?


219

ฉันเรียกใช้การดึงพื้นหลังโดยใช้การcontent-availableตั้งค่าสถานะในการแจ้งเตือนแบบพุช ฉันมีfetchและremote-notification UIBackgroundModesเปิดใช้งาน

นี่คือการใช้งานที่ฉันใช้ใน AppDelegate.m ของฉัน:

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
    NSLog(@"Remote Notification Recieved");
    UILocalNotification *notification = [[UILocalNotification alloc] init];
    notification.alertBody =  @"Looks like i got a notification - fetch thingy";
    [application presentLocalNotificationNow:notification];
    completionHandler(UIBackgroundFetchResultNewData);

}

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

อย่างไรก็ตามเมื่อแอพไม่ได้ทำงานและได้รับการแจ้งเตือนแบบพุชด้วยการcontent-availableตั้งค่าสถานะแอพจะไม่เปิดใช้งานและdidRecieveRemoteNotificationจะไม่เรียกวิธีการมอบสิทธิ์

วิดีโอ WWDC มีอะไรใหม่ใน Multitasking (# 204 จาก WWDC 2013) แสดงสิ่งนี้:ป้อนคำอธิบายรูปภาพที่นี่

มันบอกว่าแอปพลิเคชัน "เปิดใช้เป็นพื้นหลัง" เมื่อได้รับการแจ้งเตือนแบบพุชด้วยการcontent-availableตั้งค่าสถานะ

ทำไมแอพของฉันไม่เปิดใช้งานเป็นพื้นหลัง

ดังนั้นคำถามที่แท้จริงคือ:

iOS จะทำงานพื้นหลังหลังจากที่ผู้ใช้บังคับให้ออกจากแอพหรือไม่


คุณจะตรวจสอบว่าแอปเปิดตัวในพื้นหลังได้อย่างไร?
runmad

1
@runmad ฉันเข้าสู่ระบบพวงของอึใน- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
ซานตาคลอส

คุณเข้าสู่ระบบได้อย่างไรเพียงแค่ NSLog? คุณจะต้องตั้งค่า Launch เป็นคู่มือในการตั้งค่ารูปแบบแอพของคุณ (ดูคำตอบ)
runmad

@runmad ดูความคิดเห็นคำตอบ
ซานตาคลอส

@HaimBenchimol Djd คุณได้รับการตอบกลับรายงานข้อผิดพลาดของคุณหรือไม่ ฉันไม่ได้ไปรายงานข้อผิดพลาดของตัวเอง
ซานตาคลอส

คำตอบ:


215

UPDATE2:

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


UDPDATE1:

เอกสารที่ได้รับการชี้แจงสำหรับiOS8 เอกสารสามารถอ่านได้ที่นี่ นี่คือข้อความที่ตัดตอนมาที่เกี่ยวข้อง:

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


แม้ว่าสิ่งนี้จะไม่ได้รับการอธิบายอย่างชัดเจนจากวิดีโอ WWDC การค้นหาอย่างรวดเร็วในฟอรัมนักพัฒนาซอฟต์แวร์กลับกลายเป็นว่า:

https://devforums.apple.com/message/873265#873265 (จำเป็นต้องเข้าสู่ระบบ)

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

โพสต์นั้นเป็นของพนักงาน Apple ดังนั้นฉันคิดว่าฉันเชื่อใจได้ว่าข้อมูลนี้ถูกต้อง

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


2
สำหรับฉันเพิ่มการกระทำใน "didFinishLaunchingWithOptions" เมื่อเปิดตัวเลือกที่ไม่ทำงาน ฉันมีวิธีการเดียวกันที่นี่เช่นเดียวกับใน "didreceiveRemoteNotification"
harsh.prasad

@ harsh.prasad ที่น่าสนใจ ปัญหาคือแอพไม่ได้เปิดตัวเมื่อแอพถูกฆ่าจากตัวสลับแอพ
ซานตาคลอส

3
ไม่จำเป็นต้องแสดงแอปในตัวสลับแอปหากได้รับการแจ้งเตือนแบบเงียบ มันสามารถเปิดตัวในพื้นหลังโดยไม่ต้องเพิ่มลงในแอพสลับและได้รับอนุญาตให้เรียกใช้และ "ทำในสิ่งที่" แล้วออก แอพที่ใช้งานนานเกินไปจะถูกฆ่าในลักษณะเดียวกับที่มีอยู่แล้ว
MindJuice

1
@ chrizstone การแก้ปัญหาคือสิ่งนี้เป็นพฤติกรรมที่ตั้งใจและคุณไม่สามารถทำอะไรกับมันได้
ซานตาคลอส

1
@JPK เอ่อการแจ้งเตือนแบบพุชเองไม่ได้รับผลกระทบ มันเป็นเพียงการทำงานพื้นหลังที่จะไม่ทำงานหลังจากที่มันถูกบังคับให้ออก
ซานตาคลอส

70

คุณสามารถเปลี่ยนการตั้งค่าการเปิดตัวเป้าหมายของคุณใน "Manage Scheme" เป็นWait for <app>.app to be launched manuallyซึ่งช่วยให้คุณสามารถดีบักได้โดยการตั้งค่าเบรกพอยต์application: didReceiveRemoteNotification: fetchCompletionHandler:และส่งการแจ้งเตือนแบบพุช

ฉันไม่แน่ใจว่ามันจะแก้ปัญหาได้ แต่อาจช่วยคุณในการแก้ไขข้อบกพร่องในตอนนี้

ภาพหน้าจอ


ดังนั้นสิ่งนี้จึงช่วยได้ แต่ปัญหายังคงมีอยู่
ซานตาคลอส

แปลก. ฉันคิดว่าคุณมีการตรวจสอบแฟลชมากกว่าทุกครั้งในการตั้งค่าของคุณ ฯลฯ ?
runmad

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

ฉันสงสัยว่าการแจ้งเตือนการเปิดใช้ทริกเกอร์มีการกำหนดระบบหรือไม่ ตัวอย่างเช่นหาก iOS กำหนดว่าไม่ใช่เวลาที่ยอดเยี่ยมในการเปิดใช้แอปในขณะนี้ระบบอาจเลื่อนออกไปจนถึงภายหลัง อาจลองและปิดแอปที่รันอยู่ / พื้นหลังทั้งหมดแล้วดูว่าเกิดอะไรขึ้น ฉันแค่คาดเดาในจุดนี้: - /
runmad

แค่ลองดู ไม่มีอะไรเกิดขึ้นเหมือนปกติ ฉันอาจถามฟอรัม dev
ซานตาคลอส

37

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

โดยสรุป PushKit กรอบงานใหม่ใน iOS 8 เป็นกลไกการแจ้งเตือนแบบพุชใหม่ที่สามารถเปิดแอปของคุณเป็นพื้นหลังโดยไม่มีการแจ้งเตือนด้วยภาพแม้แอพของคุณจะถูกฆ่าโดยการปัดออกจากตัวสลับแอปอย่างน่าอัศจรรย์ จากตัวสลับแอป

การอ้างอิง PushKit จาก Apple:

เฟรมเวิร์ก PushKit จัดเตรียมคลาสสำหรับแอป iOS ของคุณเพื่อรับการพุชจากเซิร์ฟเวอร์ระยะไกล การกดสามารถเป็นหนึ่งในสองประเภท: มาตรฐานและ VoIP การพุชแบบมาตรฐานสามารถส่งการแจ้งเตือนเช่นเดียวกับใน iOS เวอร์ชันก่อนหน้า VoIP push ให้ฟังก์ชันการทำงานเพิ่มเติมนอกเหนือจากการพุชแบบมาตรฐานที่จำเป็นสำหรับแอพ VoIP เพื่อดำเนินการตามความต้องการของการพุชก่อนที่จะแสดงการแจ้งเตือนแก่ผู้ใช้

ในการปรับใช้คุณสมบัติใหม่นี้โปรดอ้างอิงบทช่วยสอนนี้: https://zeropush.com/guide/guide-to-pushkit-and-voip - ฉันได้ทำการทดสอบบนอุปกรณ์ของฉันแล้วและทำงานได้ตามที่คาดไว้


9
ดูเหมือนว่าคุณจะต้องตั้งค่าแอปเป็น VoIP หากแอพของคุณไม่ใช่แอพ VoIP จริงๆมันจะไม่ถูกปฏิเสธในระหว่างการตรวจสอบใช่หรือไม่
duncanc4

6
น่าเสียดายที่ทราบว่ากระบวนการตรวจสอบของ Apple นั้นเป็นตรรกะว่าแอปพลิเคชันนั้นถูกปฏิเสธ
Kepa Santos

3
ใช้สำหรับ VoIP หากไม่ได้ใช้ VoIP สำหรับผู้ใช้สิ่งนี้จะเพิ่มความเสี่ยงในการถูกปฏิเสธการตรวจสอบอย่างมาก
คริส

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

PushKit สงวนไว้สำหรับ VoIP, ผู้ให้บริการไฟล์และเฝ้าดูภาวะแทรกซ้อน ไม่สามารถใช้ได้สำหรับกรณีการใช้งานคำตอบนี้อธิบาย
ระงับ

15

จริง ๆ แล้วถ้าคุณต้องการทดสอบการดึงข้อมูลพื้นหลังคุณต้องเปิดใช้งานหนึ่งตัวเลือกในรูปแบบ:

เปิดใช้งานการดึง bg

อีกวิธีหนึ่งที่คุณสามารถทดสอบได้: จำลองการดึง bg

นี่คือข้อมูลทั้งหมดเกี่ยวกับคุณสมบัติใหม่นี้: http://www.objc.io/issue-5/multitasking.html


4

ฉันลองใช้สิ่งนี้มาหลายวันแล้วและคิดว่าเป็นวันที่ฉันได้เปิดตัวแอปอีกครั้งในพื้นหลังแม้ว่าผู้ใช้จะฆ่า แต่ก็ไม่สามารถทำซ้ำพฤติกรรมนั้นได้

มันเป็นเรื่องที่โชคร้ายที่พฤติกรรมแตกต่างไปจากเดิมอย่างสิ้นเชิง บน iOS 6 หากคุณฆ่าแอพจากไอคอน jiggling มันจะยังคงถูกเรียกใช้งานอีกครั้งในทริกเกอร์ SLC ทีนี้ถ้าคุณฆ่าโดยการปัดนี่จะไม่เกิดขึ้น

มันเป็นพฤติกรรมที่แตกต่างกันและผู้ใช้ที่จะได้รับข้อมูลที่เป็นประโยชน์จากแอพของเราต่อไปหากพวกเขาฆ่ามันใน iOS 6 ตอนนี้จะไม่เกิดขึ้น

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


2
นั่นคือสิ่งที่เราทำ (applicationWillTerminate) แต่ฉันไม่เชื่อว่ามันให้การแจ้งเตือนในระหว่างการล้างหน่วยความจำอย่างน้อยไม่ได้อยู่ใน iOS 7 ฉันสังเกตเห็นว่ามันแสดงให้เห็นการแจ้งเตือนก่อนรีบูตสำหรับการอัพเกรดระบบปฏิบัติการ หายากมันไม่ได้ดูแย่เกินไป
snarshad

"บน iOS 6 หากคุณฆ่าแอพจากไอคอน jiggling มันจะยังคงตื่นขึ้นมาใหม่ในทริกเกอร์ SLC ตอนนี้ถ้าคุณฆ่าโดยการปัดนิ้วมันจะไม่เกิดขึ้น" สิ่งนี้จะเกิดขึ้นมันเป็นความถดถอยชั่วคราวใน iOS 7 เวอร์ชั่นแรก
funkybro

3

สิ่งนี้อาจช่วยคุณได้

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

ที่มา: https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html


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