IOS sẽ khởi chạy ứng dụng của tôi vào nền nếu ứng dụng bị người dùng bỏ quyền?


219

Tôi đang kích hoạt tìm nạp nền bằng cách sử dụng content-availablecờ trên thông báo đẩy. Tôi có fetchremote-notification UIBackgroundModeskích hoạt.

Đây là cách triển khai tôi đang sử dụng trong AppDelegate.m của mình:

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

}

Khi ứng dụng đang chạy ẩn, nó hoạt động tốt. (Thông báo được nhận và ứng dụng kích hoạt thông báo cục bộ "có vẻ như tôi đã nhận được thông báo", như mã ở trên sẽ làm).

Tuy nhiên, khi ứng dụng không chạy và nhận được thông báo đẩy bằng content-availablecờ, ứng dụng sẽ không được khởi chạydidRecieveRemoteNotificationphương thức ủy nhiệm không bao giờ được gọi.

Video WWDC có gì mới với đa nhiệm (# 204 từ WWDC 2013) cho thấy điều này:nhập mô tả hình ảnh ở đây

Nó nói rằng ứng dụng được "khởi chạy vào nền" khi nhận được thông báo đẩy cùng với content-availablecờ.

Tại sao ứng dụng của tôi không khởi chạy vào nền?

Vì vậy, câu hỏi thực sự là:

IOS sẽ thực hiện các tác vụ nền sau khi người dùng đã thoát khỏi ứng dụng?


Làm thế nào bạn kiểm tra xem ứng dụng khởi chạy trong nền?
runmad

1
@runmad Tôi đăng nhập một loạt các crap trong- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
Santa Claus

Làm thế nào bạn đăng nhập nó, chỉ NSLog? Bạn sẽ phải đặt Khởi chạy thành thủ công trong cài đặt chương trình ứng dụng của mình (xem câu trả lời)
runmad

@runmad xem bình luận về câu trả lời
Santa Claus

@HaimBenchimol Djd bạn có nhận được phản hồi cho báo cáo lỗi của mình không? Tôi đã không nhận được để nộp báo cáo lỗi của riêng tôi.
Santa Claus

Câu trả lời:


215

CẬP NHẬT2:

Bạn có thể đạt được điều này bằng cách sử dụng khung PushKit mới, được giới thiệu trong iOS 8. Mặc dù PushKit được sử dụng cho VoIP. Vì vậy, việc sử dụng của bạn nên dành cho VoIP liên quan nếu không có nguy cơ bị từ chối ứng dụng. (Xem câu trả lời này ).


UDPDATE1:

Tài liệu đã được làm rõ cho iOS8 . Các tài liệu có thể được đọc ở đây . Đây là một đoạn trích có liên quan:

Sử dụng phương pháp này để xử lý các thông báo từ xa đến cho ứng dụng của bạn. Không giống như application:didReceiveRemoteNotification:phương thức, chỉ được gọi khi ứng dụng của bạn đang chạy ở nền trước, hệ thống gọi phương thức này khi ứng dụng của bạn đang chạy ở nền trước hoặc nền. Ngoài ra, nếu bạn bật chế độ nền thông báo từ xa, hệ thống sẽ khởi chạy ứng dụng của bạn (hoặc đánh thức nó từ trạng thái treo) và đặt nó ở trạng thái nền khi có thông báo đẩy. Tuy nhiên, hệ thống không tự động khởi chạy ứng dụng của bạn nếu người dùng buộc phải thoát ứng dụng. Trong tình huống đó, người dùng phải khởi chạy lại ứng dụng của bạn hoặc khởi động lại thiết bị trước khi hệ thống cố gắng tự động khởi động lại ứng dụng của bạn.


Mặc dù video WWDC không được làm rõ, một tìm kiếm nhanh trên các diễn đàn dành cho nhà phát triển đã bật lên:

https://devforums.apple.com/message/873265#873265 (yêu cầu đăng nhập)

Ngoài ra, hãy nhớ rằng nếu bạn tắt ứng dụng của mình từ trình chuyển đổi ứng dụng (nghĩa là vuốt lên để tắt ứng dụng) thì HĐH sẽ không bao giờ khởi chạy lại ứng dụng bất kể thông báo đẩy hay tìm nạp nền. Trong trường hợp này, người dùng phải khởi chạy lại ứng dụng một cách thủ công một lần và sau đó từ đó trở đi, các hoạt động nền sẽ được gọi. - pmarcos

Bài đăng đó là của một nhân viên Apple vì vậy tôi nghĩ rằng tôi có thể tin tưởng rằng thông tin này là chính xác.

Vì vậy, có vẻ như khi ứng dụng bị giết từ trình chuyển đổi ứng dụng (bằng cách vuốt lên), ứng dụng sẽ không bao giờ được khởi chạy, ngay cả đối với các lần tải nền theo lịch trình.


2
Đối với tôi, thêm hành động trong "didFinishLaunchingWithOptions" khi khởi chạy các tùy chọn không phải là công việc. Tôi có phương pháp tương tự ở đây như trong "didreceiveRemoteNotification"
khắc nghiệt.prasad

@ khắc nghiệt.prasad thật thú vị. Vấn đề là ứng dụng không được khởi chạy khi ứng dụng đã bị giết từ trình chuyển đổi ứng dụng.
Ông già Noel

3
Không cần hiển thị ứng dụng trong trình chuyển đổi ứng dụng nếu nhận được một cú đẩy im lặng. Nó có thể được khởi chạy trong nền mà không cần thêm nó vào trình chuyển đổi ứng dụng và được phép chạy và "làm việc của nó" và sau đó thoát. Các ứng dụng duy trì hoạt động quá lâu sẽ bị giết theo cùng một cách như chúng đã có.
MindJuice

1
@chrizstone Giải pháp là đây là hành vi có chủ đích và bạn không thể làm gì với nó.
Ông già Noel

1
@JPK Uh, thông báo đẩy bản thân không bị ảnh hưởng. Nó chỉ thực hiện các nhiệm vụ nền tảng sẽ không hoạt động sau khi nó bị buộc thôi việc.
Ông già Noel

70

Bạn có thể thay đổi cài đặt khởi chạy của mục tiêu trong "Quản lý lược đồ" thành Wait for <app>.app to be launched manually, cho phép bạn gỡ lỗi bằng cách đặt điểm dừng application: didReceiveRemoteNotification: fetchCompletionHandler:và gửi thông báo đẩy để kích hoạt khởi chạy nền.

Tôi không chắc nó sẽ giải quyết được vấn đề, nhưng nó có thể hỗ trợ bạn gỡ lỗi ngay bây giờ.

ảnh chụp màn hình


Vì vậy, điều này đã giúp nhưng vấn đề vẫn còn tồn tại
Santa Claus

Lạ thật. Tôi cho rằng bạn đã kiểm tra nhiều hơn tất cả các đèn flash được đặt trong bảng của bạn, v.v.?
runmad

Ngoài ra, tôi biết tôi có mọi thứ được đặt đúng bởi vì khi ứng dụng ở chế độ nền, mọi thứ đều hoạt động hoàn hảo. Chỉ khi ứng dụng không chạy, nó không hoạt động.
Ông già Noel

Tôi tự hỏi nếu một kích hoạt khởi động thông báo đẩy được xác định hệ thống. Ví dụ: nếu iOS xác định đây không phải là thời điểm tuyệt vời để khởi chạy ứng dụng ngay bây giờ thì có thể hoãn lại cho đến sau này. Có lẽ thử và đóng tất cả các ứng dụng đang chạy / nền và xem điều gì xảy ra? Tôi chỉ đoán ở điểm này: - /
runmad

chỉ cần thử nó Không có gì xảy ra, giống như bình thường. Tôi có thể hỏi trên các diễn đàn dev.
Ông già Noel

37

Câu trả lời là CÓ, nhưng không nên sử dụng 'Tải xuống nền' hoặc 'Thông báo từ xa'. PushKit là câu trả lời bạn mong muốn.

Tóm lại, PushKit, khung mới trong ios 8, là cơ chế thông báo đẩy mới có thể âm thầm khởi chạy ứng dụng của bạn xuống nền mà không có lời nhắc cảnh báo trực quan ngay cả ứng dụng của bạn đã bị giết bằng cách vuốt ra khỏi trình chuyển đổi ứng dụng, thật đáng ngạc nhiên bạn thậm chí không thể nhìn thấy nó từ trình chuyển đổi ứng dụng.

Tham khảo PushKit từ Apple:

Khung PushKit cung cấp các lớp cho các ứng dụng iOS của bạn để nhận các lần đẩy từ các máy chủ từ xa. Đẩy có thể là một trong hai loại: tiêu chuẩn và VoIP. Đẩy tiêu chuẩn có thể cung cấp thông báo giống như trong các phiên bản iOS trước. Các đẩy VoIP cung cấp chức năng bổ sung trên đầu đẩy tiêu chuẩn cần thiết cho các ứng dụng VoIP để thực hiện xử lý theo yêu cầu của việc đẩy trước khi hiển thị thông báo cho người dùng.

Để triển khai tính năng mới này, vui lòng tham khảo hướng dẫn này: https://zeropush.com/guide/guide-to-pushkit-and-voip - Tôi đã thử nghiệm nó trên thiết bị của mình và nó hoạt động như mong đợi.


9
Có vẻ như với tôi bạn phải đặt ứng dụng của mình là sử dụng VoIP. Nếu ứng dụng của bạn không thực sự là một ứng dụng VoIP, liệu nó có bị từ chối trong quá trình xem xét không?
duncanc4

6
Thật không may, khi biết quá trình xác nhận của Apple, sẽ rất hợp lý khi ứng dụng bị từ chối.
Kepa Santos

3
Được sử dụng cho VoIP. Nếu không sử dụng VoIP cho người dùng, điều này sẽ làm tăng đáng kể nguy cơ từ chối xem xét.
Chris

Có vẻ như các nhà cung cấp lớn đang sử dụng cơ sở này như một cái cớ để chạy các công cụ trong nền và Apple đang bị mù. Trở thành một tính năng của Android tại thời điểm đó.
TCB13

PushKit được dành riêng cho VoIP, Nhà cung cấp tệp và Xem các biến chứng. Nó không có sẵn cho các trường hợp sử dụng câu trả lời này mô tả.
quellish

15

Trên thực tế nếu bạn cần kiểm tra tìm nạp nền, bạn cần kích hoạt một tùy chọn trong sơ đồ:

cho phép tìm nạp bg

Một cách khác để bạn có thể kiểm tra nó: mô phỏng bg tìm nạp

Dưới đây là thông tin đầy đủ về tính năng mới này: http://www.objc.io/su-5/multitasking.html


4

Tôi đã thử các biến thể khác nhau của điều này trong nhiều ngày và tôi nghĩ trong một ngày tôi đã khởi chạy lại ứng dụng ở chế độ nền, ngay cả khi người dùng vuốt sang giết, nhưng tôi không thể sao chép hành vi đó.

Thật không may là hành vi này khá khác so với trước đây. Trên iOS 6, nếu bạn tắt ứng dụng từ các biểu tượng gây cười, nó vẫn sẽ được đánh thức lại trên các kích hoạt SLC. Bây giờ, nếu bạn giết bằng cách vuốt, điều đó không xảy ra.

Đó là một hành vi khác và người dùng, những người sẽ tiếp tục nhận thông tin hữu ích từ ứng dụng của chúng tôi nếu họ đã giết nó trên iOS 6, giờ thì không.

Chúng tôi cần phải thúc đẩy người dùng mở lại ứng dụng ngay bây giờ nếu họ đã vuốt để giết nó và vẫn đang mong đợi một số hành vi thông báo mà chúng tôi đã sử dụng để cung cấp cho họ. Tôi lo lắng điều này sẽ không rõ ràng đối với người dùng khi họ vuốt một ứng dụng đi. Rốt cuộc, họ có thể dọn dẹp hoặc muốn sắp xếp lại các ứng dụng được hiển thị ở mức tối thiểu.


2
Đó chính xác là những gì chúng tôi đã làm (applicationWillTerminate), nhưng tôi không tin rằng nó đã đưa ra thông báo trong quá trình thanh lọc bộ nhớ, ít nhất là không phải trên iOS 7. Tôi đã nhận thấy rằng nó hiển thị thông báo ngay trước khi khởi động lại để nâng cấp hệ điều hành, nhưng đó là như vậy hiếm khi nó không có vẻ quá xấu.
snarshad

"Trên iOS 6, nếu bạn tắt ứng dụng từ các biểu tượng gây cười, nó vẫn sẽ được đánh thức lại trên trình kích hoạt SLC. Bây giờ, nếu bạn giết bằng cách vuốt, điều đó không xảy ra." Điều này hiện đang xảy ra, đó là một hồi quy tạm thời trong phiên bản đầu tiên của iOS 7.
funkybro

3

Điều này có thể giúp bạn

Trong hầu hết các trường hợp, hệ thống không khởi chạy lại ứng dụng sau khi chúng bị người dùng buộc phải thoát. Một ngoại lệ là các ứng dụng định vị, trong iOS 8 trở lên được khởi chạy lại sau khi bị người dùng buộc phải thoát. Tuy nhiên, trong các trường hợp khác, người dùng phải khởi chạy ứng dụng một cách rõ ràng hoặc khởi động lại thiết bị trước khi hệ thống có thể tự động khởi chạy vào nền. Khi bật bảo vệ mật khẩu trên thiết bị, hệ thống sẽ không khởi chạy ứng dụng trong nền trước khi người dùng mở khóa thiết bị trước.

Nguồn: https://developer.apple.com/lvern/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecut/BackgroundExecut.html


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.