簡體   English   中英

應用程序終止時處理推送通知

[英]Handling Push Notifications when App is Terminated

當我的應用程序未運行並收到推送通知時,如果我單擊該通知,則會啟動應用程序 - 但它不會提示用戶使用我設置的警報視圖,詢問他們是否要查看通知的內容與否。 它剛剛啟動,並坐在那里。

推送通知在應用程序運行時可以完美運行——無論是作為活動應用程序還是在后台運行——但是當應用程序沒有運行時,沒有任何東西可以正常工作。

我嘗試在應用程序中注銷launchOptions NSDictionary:didFinishLaunchingWithOptions:以查看它帶來的負載-但它顯示為“(null)”。 所以它基本上什么都不包含 - 這沒有意義,因為它不應該包含通知的負載嗎?

任何人都知道如何在應用程序未運行時使推送通知到達時工作?

我的意思是當應用程序處於非運行狀態時如何處理推送通知。 如果您收到許多通知並且您沒有打開應用程序,也沒有點擊系統的通知面板怎么辦。 您如何保留這些推動以供以后檢索。

1)當應用程序在后台運行時當應用程序在前台運行時應用application:didReceiveRemoteNotification:方法將調用如下。

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
    if (application.applicationState == UIApplicationStateInactive)
    {
        // opened from a push notification when the app was on background
        NSLog(@"userInfo->%@", [userInfo objectForKey:@"aps"]);
    }
    else if(application.applicationState == UIApplicationStateActive)
    {
        // a push notification when the app is running. So that you can display an alert and push in any view
        NSLog(@"userInfo->%@", [userInfo objectForKey:@"aps"]);
    }
}

2)當應用程序未啟動(關閉)時,將調用application:didFinishedLaunchingWithOptions方法。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    if (launchOptions != nil)
    {
        // opened from a push notification when the app is closed
        NSDictionary* userInfo = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
        if (userInfo != nil)
        {
             NSLog(@"userInfo->%@", [userInfo objectForKey:@"aps"]);
        }
    }
    else
    {
        // opened app without a push notification.
    }
}

3)沒有辦法刪除特定的通知。 從您的應用程序中刪除所有通知以便當用戶從其中一個應用程序打開應用程序時它們不會顯示在通知中心的方法是將應用程序徽章設置為 0。

根據您的問題,當您打開應用程序時,無法保留所有通知,最好調用 api 以從后端/服務器獲取所有通知,這就是 Facebook 的做法。

您可以使用getDeliveredNotifications(completionHandler:)方法檢索發送到您的應用程序的通知。 請注意,這只返回當前顯示在通知中心的通知,而不是用戶手動清除的通知。

UNUserNotificationCenter.current().getDeliveredNotifications { notifications in

    // notifications: An array of UNNotification objects representing the local
    // and remote notifications of your app that have been delivered and are still
    // visible in Notification Center. If none of your app’s notifications are
    // visible in Notification Center, the array is empty.

    // As said in the documentation, this closure may be executed in a background
    // thread, so if you want to update your UI you'll need to do the following:
    DispatchQueue.main.sync { /* or .async {} */ 
        // update UI
    }
}

該應用程序不會在后台處理推送通知,操作系統的真正作用是在您按下通知后喚醒應用程序。 您可以通過以下方式捕捉這一時刻:

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    { 

        if ([launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]) {
      // Your app has been awoken by a notification...
        }
   }

無法在應用程序端處理此問題。 您需要在服務器上維護未讀徽章計數。 當應用程序被殺死時,徽章值會從服務器更新。

因此,當您隨時打開應用程序時,您需要調用 Web 服務來獲取所需的通知並更新標簽欄的標記(如果使用)。

在終止狀態下收到通知后執行操作 - iOS 13 - 場景委托

最近我遇到了一個問題,當我的應用程序處於終止狀態時,我收到了遠程推送通知。 在最新的 iOS 版本中,Scene delegate 負責處理視圖生命周期方法,而不是 App Delegate。

較早的 iOS 版本 - 由 App Delegate 處理 當應用程序終止並收到遠程推送通知時,有效負載會反映在 App 委托的 didfinishLaunchingWithOptions 方法中。 使用此方法的啟動參數,可以獲取有效負載數據並執行任何交互。

新的 iOS 版本 - 由場景委托處理類似地,當應用程序終止並收到遠程推送通知時,有效負載會反映在場景委托的場景(willConnectTo 會話)中。 使用此方法的connectingOption 參數,可以獲取有效負載數據並執行任何交互。

提示:一旦視圖控制器設置為根視圖控制器,要執行任何交互或將此有效負載傳遞給另一個視圖控制器,請保持幾秒鍾的延遲以傳遞數據。

示例代碼:

guard let windowScene = (scene as? UIWindowScene) else { return }
window = UIWindow(frame: windowScene.coordinateSpace.bounds)
window?.windowScene = windowScene
 
if defaults.string(forKey: UserDefaultsKeys.TenantID.rawValue) != nil && connectionOptions.notificationResponse != nil {
   
  let rootViewController = UINavigationController(rootViewController: DashboardVC())
  window?.rootViewController = rootViewController
  window?.makeKeyAndVisible()
   
  DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
    NotificationCenter.default.post(
      name: .passApnsDataToDashboardNotification,
      object: nil,
      userInfo: connectionOptions.notificationResponse?.notification.request.content.userInfo)
  }
   
}

您可以在通過這樣的通知啟動以前終止的應用程序后顯示警報:

DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.1) { // display the alert }

對於您的用例,BGTask 是最好的解決方案,它可以調用服務器並獲取數據並更新您的數據庫,以便下次您立即獲得可用數據。

BGTask 調度由操作系統基於 7 個因素(如應用使用情況、電池壽命、速率限制等)完成,如果您的應用不執行任何 BGTask(您可以通過將其保存到 UserDefalts 輕松檢查),您可以顯式獲取服務器數據當應用程序上線時。

僅供參考:

您可以配置和使用UserNotificaions來接收本地/遠程通知

https://developer.apple.com/documentation/usernotifications?language=objc

- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
         withCompletionHandler:(void(^)(void))completionHandler

https://developer.apple.com/documentation/usernotifications/unusernotificationcenterdelegate/1649501-usernotificationcenter?language=objc

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM