program story

iOS 푸시 알림 : 앱이 백그라운드에있을 때 사용자가 알림을 탭했는지 감지하는 방법은 무엇입니까?

inputbox 2020. 8. 13. 08:18
반응형

iOS 푸시 알림 : 앱이 백그라운드에있을 때 사용자가 알림을 탭했는지 감지하는 방법은 무엇입니까?


이 주제와 관련된 많은 스택 오버플로 스레드가 있지만 여전히 좋은 해결책을 찾지 못했습니다.

앱이 배경에 없으면, 내가 확인하실 수 있습니다 launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]application:didFinishLaunchingWithOptions:이 통지에서 연 것 있는지 확인하기 위해 전화.

앱이 백그라운드에 있으면 모든 게시물 application:didReceiveRemoteNotification:에서 애플리케이션 상태 를 사용 하고 확인하도록 제안합니다 . 그러나 내가 실험 한 것처럼 (또한이 API의 이름에서 알 수 있듯이)이 메서드는 탭하는 대신 알림을받을 때 호출됩니다.

따라서 문제는 앱이 시작된 다음 백그라운드로 설정되고 알림이 수신 된 경우 application:didReceiveNotification( application:didFinishLaunchWithOptions:이 시점에서 트리거되지 않음) 사용자가 알림을 탭하거나 탭하여 앱을 다시 시작했는지 어떻게 알 수 있다는 것입니다. 앱 아이콘? 사용자가 알림을 탭한 경우 해당 알림에 언급 된 페이지가 열릴 것으로 예상되기 때문입니다. 그렇지 않으면 안됩니다.

handleActionWithIdentifier사용자 지정 작업 알림에 사용할 수 있지만 사용자가 알림 본문을 탭할 때가 아니라 사용자 지정 작업 버튼을 탭할 때만 트리거됩니다.

감사.

편집하다:

아래 답변 하나를 읽은 후 이런 식으로 내 질문을 명확히 할 수 있다고 생각했습니다.

이 두 가지 시나리오를 어떻게 차별화 할 수 있습니까?

(A) 1. 앱이 백그라운드로 이동합니다. 2. 통지 접수 3. 사용자가 알림을 탭합니다. 4. 앱이 포 그라운드로 들어감

(B) 1. 앱이 백그라운드로 이동합니다. 2. 통지 접수 3. 사용자가 알림을 무시하고 나중에 앱 아이콘을 탭합니다. 4. 앱이 포 그라운드로 들어감

이후로는 application:didReceiveRemoteNotification:2 단계에서 두 경우 모두에서 실행됩니다.

또는 application:didReceiveRemoteNotification:(A)에 대해서만 3 단계에서 트리거 되어야 하지만 어떻게 든 내 앱을 잘못 구성하여 2 단계에서 볼 수 있습니까?


OK 마침내 알아 냈습니다.

대상 설정에서 ➝ 기능 탭 ➝ 백그라운드 모드에서 "원격 알림"을 ​​선택 application:didReceiveRemoteNotification:하면 알림이 도착하는 즉시 (앱이 백그라운드에있는 한) 트리거되며,이 경우 알 수있는 방법이 없습니다. 사용자는 알림을 탭합니다.

해당 상자를 선택 취소 application:didReceiveRemoteNotification:하면 알림을 탭할 때만 트리거됩니다.

이 체크 박스를 선택하면 앱 델리게이트 메서드 중 하나가 작동하는 방식이 변경된다는 것은 조금 이상합니다. 이 확인란을 선택하면 Apple은 알림 수신 및 알림 탭에 대해 두 가지 다른 위임 방법을 사용합니다. 대부분의 개발자는 알림이 탭되었는지 여부를 항상 알고 싶어합니다.

이 문제를 겪는 다른 사람들에게 도움이되기를 바랍니다. Apple은 또한 여기에 명확하게 문서화하지 않았 으므로 알아내는 데 시간이 걸렸습니다.

여기에 이미지 설명 입력


나는 당신과 똑같은 것을 찾고 있었고 실제로 원격 알림이 필요하지 않은 솔루션을 찾았습니다.

사용자가 탭했는지, 앱이 백그라운드에 있는지 또는 활성화되었는지 확인하려면 다음에서 애플리케이션 상태를 확인하면됩니다.

-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{

    if(application.applicationState == UIApplicationStateActive) {

        //app is currently active, can update badges count here

    }else if(application.applicationState == UIApplicationStateBackground){

        //app is in background, if content-available key of your notification is set to 1, poll to your backend to retrieve data and update your interface here

    }else if(application.applicationState == UIApplicationStateInactive){

        //app is transitioning from background to foreground (user taps notification), do what you need when user taps here

    }

자세한 정보 확인 :

UIKit 프레임 워크 참조> UIApplication 클래스 참조> UIApplicationState


iOS / XCode 에 따르면 : 알림 또는 스프링 보드 앱 아이콘을 클릭하여 앱이 시작되었는지 확인하는 방법은 무엇입니까? 다음과 같이 didReceiveLocalNotification에서 애플리케이션 상태를 확인해야합니다.

if ([UIApplication sharedApplication].applicationState == UIApplicationStateInactive)
{
    // user has tapped notification
}
else
{
    // user opened app from app icon
}

나에게 완전히 이해가되지는 않지만 작동하는 것 같습니다.


누군가가 신속한 3.0에서 원하는 경우

switch application.applicationState {
    case .active:
        //app is currently active, can update badges count here
        break
    case .inactive:
        //app is transitioning from background to foreground (user taps notification), do what you need when user taps here
        break
    case .background:
        //app is in background, if content-available key of your notification is set to 1, poll to your backend to retrieve data and update your interface here
        break
    default:
        break
    }

신속한 4

switch UIApplication.shared.applicationState {
case .active:
    //app is currently active, can update badges count here
    break
case .inactive:
    //app is transitioning from background to foreground (user taps notification), do what you need when user taps here
    break
case .background:
    //app is in background, if content-available key of your notification is set to 1, poll to your backend to retrieve data and update your interface here
    break
default:
    break
}

"백그라운드 모드"> "원격 알림"이 선택되어있는 경우 == 예, 알림 이벤트를 탭하면 다음 위치에 도착합니다.

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

그것은 나를 도왔다. 즐기세요 :)


나도이 문제에 부딪 혔지만 새로운 UserNotifications프레임 워크 가있는 iOS 11에서 .

여기에서는 다음과 같습니다.

  • New Launch: application:didFinishLaunchingWithOptions:
  • Received in Foreground: application:didReceiveRemoteNotification:fetchCompletionHandler:
  • Received in Background: userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:

In my case, background mode OFF did not make any difference. However when the app was suspended and the user tapped the notification, I could handle the case in this callback method:

func userNotificationCenter(_ center: UNUserNotificationCenter,
                            didReceive response: UNNotificationResponse,
                            withCompletionHandler completionHandler: @escaping () -> Void) {

}

For iOS 10 and above put this in AppDelegate, to get to know notification is tapped(works even app is closed or open)

func userNotificationCenter(_ center: UNUserNotificationCenter,
                                didReceive response: UNNotificationResponse,
                                withCompletionHandler completionHandler: @escaping () -> Void) {
print("notification tapped here")
}

There are two Funcs to handle received PushNotification inside :

class PushNotificationManager: NSObject, MessagingDelegate, UNUserNotificationCenterDelegate{

}

As I tested the first on trigger as soon as Notification arrived

@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {

    completionHandler(UNNotificationPresentationOptions.alert)

    //OnReceive Notification
    let userInfo = notification.request.content.userInfo
    for key in userInfo.keys {
         Constants.setPrint("\(key): \(userInfo[key])")
    }

    completionHandler([])

}

And second one when Tapped on Notification:

@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {

    //OnTap Notification
    let userInfo = response.notification.request.content.userInfo
    for key in userInfo.keys {
        Constants.setPrint("\(key): \(userInfo[key])")
    }

    completionHandler()
}

Too I tested it with both Remote Notification(in Background Modes) On/Off state.


You can configure your push notification's payload to call app delegate’s application:didReceiveRemoteNotification:fetchCompletionHandler: method when the app is in background. You can set some flag here so that when user launch your application next time, you can perform your operation.

From apple’s documentation you should use this methods to download new content associated with push notification. Also for this to work, you have to enable Remote notification from Background modes and your push notification payload must contain content-available key with its value set to 1. From more info please see Using Push Notifications to Initiate a Download section from apple doc here.

또 다른 방법은 푸시 알림 페이로드에 배지 개수를 포함하는 것입니다. 따라서 다음에 응용 프로그램을 시작할 때 응용 프로그램 배지 수를 확인할 수 있습니다. 0보다 크면 작업을 수행하고 서버에서 배지 카운트를 0 / 지 웁니다.

이것이 도움이되기를 바랍니다.

참고 URL : https://stackoverflow.com/questions/32061897/ios-push-notification-how-to-detect-if-the-user-tapped-on-notification-when-the

반응형