Apakah mungkin untuk mengetahui apakah aplikasi diluncurkan / dibuka dari pemberitahuan push?
Saya kira acara peluncuran dapat ditangkap di sini:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if (launchOptions != nil) {
// Launched from push notification
NSDictionary *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
}
}
Namun, bagaimana saya bisa mendeteksi itu dibuka dari pemberitahuan push ketika aplikasi di latar belakang?
Jawaban:
Lihat kode ini:
sama dengan
sumber
terlambat tapi mungkin bermanfaat
Saat aplikasi tidak berjalan
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
disebut ..
di mana Anda perlu memeriksa pemberitahuan push
sumber
Masalah yang kami miliki adalah memperbarui tampilan dengan benar setelah aplikasi diluncurkan. Ada urutan rumit dari metode siklus hidup di sini yang membingungkan.
Metode Siklus Hidup
Pengujian kami untuk iOS 10 mengungkapkan urutan metode siklus hidup berikut untuk berbagai kasus:
Masalah
Ok, jadi sekarang kita perlu:
Yang sulit adalah bahwa memperbarui tampilan harus terjadi ketika aplikasi benar-benar menjadi aktif, yang merupakan metode siklus hidup yang sama dalam semua kasus.
Sketsa solusi kami
Berikut adalah komponen utama dari solusi kami:
notificationUserInfo
variabel instan pada AppDelegate.notificationUserInfo = nil
keduanyaapplicationWillEnterForeground
dandidFinishLaunchingWithOptions
.notificationUserInfo = userInfo
indidReceiveRemoteNotification:inactive
applicationDidBecomeActive
selalu memanggil metode khususopenViewFromNotification
dan lulusself.notificationUserInfo
. Jikaself.notificationUserInfo
nihil maka kembali lebih awal, jika tidak buka buka berdasarkan status notifikasi yang ditemukan diself.notificationUserInfo
.Penjelasan
Saat membuka dari push
didFinishLaunchingWithOptions
atauapplicationWillEnterForeground
selalu dipanggil segera sebelumnyadidReceiveRemoteNotification:inactive
, jadi kami atur ulang notificationUserInfo dalam metode ini sehingga tidak ada status basi. Kemudian, jikadidReceiveRemoteNotification:inactive
dipanggil, kami tahu kami membuka dari sebuah push jadi kami mengaturself.notificationUserInfo
yang kemudian diambil olehapplicationDidBecomeActive
untuk meneruskan pengguna ke tampilan yang benar.Ada satu kasus terakhir yaitu jika pengguna membuka aplikasi di dalam pengalih aplikasi (yaitu dengan mengetuk dua kali tombol beranda saat aplikasi berada di latar depan) dan kemudian menerima pemberitahuan push. Dalam hal ini hanya
didReceiveRemoteNotification:inactive
dipanggil, dan baik WillEnterForeground maupun didFinishLaunching tidak dipanggil sehingga Anda memerlukan kondisi khusus untuk menangani kasus itu.Semoga ini membantu.
sumber
receive
metode ketika keadaan aplikasi aktif atau aplikasi melanjutkan. Itu bisa menyebabkan masalah dengan mengubah VC ketika aplikasi masih tidak aktif. Solusi Anda tampak hebat, sampai Apple mengubah siklus hidup lagi.applicationWillResignActive
dipanggil dan kemudianapplicationDidBecomeActive
. Jadi setelahapplicationWillResignActive
dipanggil jangan simpan notifikasi yang diterima sampaiapplicationDidEnterBackground
atauapplicationDidBecomeActive
dipanggil.Ini adalah posting yang sudah usang ... tetapi masih belum ada solusi aktual untuk masalah ini (seperti yang ditunjukkan dalam berbagai komentar).
Alasannya dapat dilihat dalam aliran panggilan ketika pemberitahuan tiba,
application:didReceiveRemoteNotification...
dipanggil saat pemberitahuan diterima DAN lagi ketika pemberitahuan diketuk oleh pengguna. Karena itu, Anda tidak dapat mengetahui hanya dengan melihat
UIApplicationState
apakah pengguna mengetuknya.Selain itu, Anda tidak perlu lagi menangani situasi 'permulaan yang dingin' dari aplikasi
application:didFinishLaunchingWithOptions...
sepertiapplication:didReceiveRemoteNotification...
yang dipanggil lagi setelah diluncurkan di iOS 9+ (mungkin 8 juga).Jadi, bagaimana Anda bisa tahu jika pengguna mengetuk rantai kejadian? Solusi saya adalah dengan menandai waktu di mana aplikasi mulai keluar dari latar belakang atau mulai dingin dan kemudian memeriksa waktu masuk
application:didReceiveRemoteNotification...
. Jika kurang dari 0,1, maka Anda dapat yakin keran memicu startup.Swift 2.x
Cepat 3
Saya telah menguji ini untuk kedua kasus (aplikasi di latar belakang, aplikasi tidak berjalan) di iOS 9+ dan itu berfungsi seperti pesona. 0,1s juga cukup konservatif, nilai sebenarnya adalah ~ 0,002s jadi 0,01 juga baik-baik saja.
sumber
UNNotificationCenter
API, khususnya metode UNNotificationCenterDelegate.userNotificationCenter(UNUserNotificationCenter, didReceive: UNNotificationResponse, withCompletionHandler: @escaping () -> Void)
Metode panggilan API itu hanya bila pengguna benar-benar mengetuk notifikasi.applicationWillEnterForeground
panggilan, sebagai hasilnya, solusi gagal mendeteksi keran.UNUserNotificationCenter.current().delegate
padaapplication:didFinishLaunchingWithOptions
, aplikasi akan memanggiluserNotificationCenter(didReceive response)
setelah keran dalam kasus yang Anda jelaskanSaat aplikasi dihentikan, dan pengguna mengetuk notifikasi push
Ketika aplikasi di latar belakang, dan pengguna mengetuk pemberitahuan push
Bergantung pada aplikasi Anda, itu juga dapat mengirimkan Anda dorongan diam-diam dengan
content-available
di dalamaps
, jadi waspadai hal ini juga :) Lihat https://stackoverflow.com/a/33778990/1418457sumber
Swift 2.0 Untuk Status 'Tidak Berjalan' (Pemberitahuan Lokal & Jarak Jauh)
sumber
Di
application:didReceiveRemoteNotification:
cek apakah Anda telah menerima pemberitahuan ketika aplikasi Anda di latar depan atau latar belakang.Jika diterima di latar belakang, luncurkan aplikasi dari notifikasi.
sumber
Untuk cepat:
sumber
Ya, Anda dapat mendeteksi dengan metode ini di appDelegate :
Untuk Pemberitahuan lokal:
sumber
jika seseorang menginginkan jawabannya dengan cepat 3
sumber
Posting ini untuk pengguna Xamarin.
Kunci untuk mendeteksi apakah aplikasi diluncurkan melalui pemberitahuan push adalah
AppDelegate.FinishedLaunching(UIApplication app, NSDictionary options)
metode, dan kamus opsi yang diteruskan.The pilihan kamus akan memiliki kunci ini di dalamnya jika pemberitahuan lokal:
UIApplication.LaunchOptionsLocalNotificationKey
.Jika itu notifikasi jarak jauh, itu akan menjadi
UIApplication.LaunchOptionsRemoteNotificationKey
.Ketika kuncinya adalah
LaunchOptionsLocalNotificationKey
, objeknya bertipeUILocalNotification
. Anda kemudian dapat melihat notifikasi dan menentukan notifikasi spesifik yang mana.Pro-tip:
UILocalNotification
tidak memiliki pengenal di dalamnya, sepertiUNNotificationRequest
halnya. Masukkan kunci kamus di UserInfo yang berisi requestId sehingga saat mengujiUILocalNotification
, Anda akan memiliki requestId khusus yang tersedia untuk mendasarkan beberapa logika.Saya menemukan bahwa bahkan pada iOS 10 + perangkat yang saat membuat pemberitahuan lokasi menggunakan
UNUserNotificationCenter
'sAddNotificationRequest
&UNMutableNotificationContent
, bahwa ketika aplikasi tidak berjalan (saya membunuh itu), dan diluncurkan dengan menekan pemberitahuan di pusat pemberitahuan, bahwa kamus masih mengandung yangUILocalNotificaiton
objek.Ini berarti bahwa kode saya yang memeriksa peluncuran berbasis pemberitahuan akan berfungsi pada perangkat iOS8 dan iOS 10+
sumber
Langsung dari dokumentasi untuk
Jika aplikasi sedang berjalan dan menerima notifikasi jarak jauh, aplikasi memanggil metode ini untuk memproses notifikasi.
Implementasi Anda terhadap metode ini harus menggunakan notifikasi untuk mengambil tindakan yang sesuai.
Dan sedikit kemudian
Jika aplikasi tidak berjalan ketika pemberitahuan push tiba, metode meluncurkan aplikasi dan memberikan informasi yang sesuai dalam kamus opsi peluncuran.
Aplikasi tidak memanggil metode ini untuk menangani pemberitahuan push itu.
Sebaliknya, implementasi Anda terhadap
atau
metode perlu mendapatkan data payload pemberitahuan push dan merespons dengan tepat.
sumber
Saya akan mulai dengan bagan status yang saya buat untuk penggunaan saya sendiri untuk memvisualisasikannya dengan lebih akurat dan untuk mempertimbangkan semua status lainnya: https://docs.google.com/spreadsheets/d/e/2PACX-1vSdKOgo_F1TZwGJBAED4C_7cml0bEATqeL3P9UK9MzUdAgAcU ? gid = 0 & single = true
Dengan menggunakan bagan ini, kita dapat melihat apa yang sebenarnya diperlukan untuk mengembangkan sistem penanganan notifikasi yang kuat yang bekerja di hampir semua kasus penggunaan yang mungkin.
Solusi lengkap ↓
Catatan: Jawaban yang serupa disarankan dalam komentar pada jawaban Eric, namun lembar negara membantu dalam menemukan semua skenario yang mungkin seperti yang saya lakukan di aplikasi saya.
Silakan temukan kode lengkap di bawah ini dan beri komentar di bawah ini jika ada kasus khusus yang tidak ditangani:
AppDelegate
NotificationUtils : Di sinilah Anda dapat menulis semua kode Anda untuk bernavigasi ke berbagai bagian aplikasi, menangani Database (CoreData / Realm) dan melakukan semua hal lain yang perlu dilakukan ketika pemberitahuan diterima.
sumber
sumber
Hanya ada satu cara yang dapat diandalkan, dan hanya berfungsi untuk iOS 10+ :
Menggunakan metode
UNUserNotificationCenter
implementUNUserNotificationCenterDelegate
:sumber
Kamu bisa memakai:
untuk menangani notifikasi push jarak jauh.
Periksa dokumentasi di sini
sumber
Saya belum mencobanya, tetapi mungkin Anda bisa mengirimkan pemberitahuan kepada diri sendiri? http://nshipster.com/nsnotification-and-nsnotificationcenter/
sumber
sumber
Masalah dengan pertanyaan ini adalah bahwa "pembukaan" aplikasi tidak didefinisikan dengan baik. Suatu aplikasi diluncurkan dengan dingin dari keadaan tidak berjalan, atau diaktifkan kembali dari keadaan tidak aktif (misalnya dari beralih kembali ke itu dari aplikasi lain). Inilah solusi saya untuk membedakan semua kemungkinan keadaan ini:
Dan
MXDefaults
hanya sedikit pembungkusNSUserDefaults
.sumber
Untuk
swift
sumber
Xcode 10 Swift 4.2
sumber
Untuk iOS 10+, Anda dapat menggunakan metode ini untuk mengetahui kapan notifikasi Anda diklik terlepas dari keadaan aplikasi.
sumber
Jawaban M.Othman benar untuk aplikasi yang tidak mengandung delegasi adegan Untuk Aplikasi Delegasi Scene Ini berfungsi untuk saya di iOS 13
Berikut adalah kode untuk yang harus dituliskan akan menghubungkan adegan
Kode untuk delegasi aplikasi untuk mendukung versi sebelumnya didFinishLaunchingWithOptions
sumber
Untuk Pengguna Swift:
Jika Anda ingin meluncurkan halaman berbeda pada pembukaan dari push atau sesuatu seperti itu, Anda perlu memeriksanya
didFinishLaunchingWithOptions
seperti:sumber
DALAM SWIFT:
Saya menjalankan Pemberitahuan Push (dengan pengambilan latar belakang). Ketika aplikasi saya di latar belakang dan saya menerima pemberitahuan push, saya menemukan bahwa didReceiveRemoteNotification di appDelegate akan dipanggil dua kali; satu kali ketika notifikasi diterima dan lainnya ketika pengguna mengklik pada notifikasi notifikasi.
Untuk mendeteksi jika pemberitahuan notifikasi diklik, cukup periksa apakah nilai mentah applicationState == 1 di dalam didReceiveRemoteNotification di appDelegate.
Saya harap ini membantu.
sumber
Ketika aplikasi di latar belakang sebagai shanegao dapat Anda gunakan
Tetapi jika Anda ingin meluncurkan aplikasi dan ketika aplikasi ditutup dan Anda ingin men-debug aplikasi Anda, Anda dapat pergi ke Edit Skema dan di menu kiri pilih Jalankan dan kemudian dalam peluncuran pilih Tunggu untuk dieksekusi akan diluncurkan dan kemudian Anda meluncurkan aplikasi ketika Anda klik pemberitahuan push
Edit Skema> Jalankan> Tunggu untuk dieksekusi akan diluncurkan
sumber