programing

iOS 푸시 알림: 앱이 백그라운드에서 사용자가 알림을 눌렀는지 어떻게 감지합니까?

fastcode 2023. 4. 15. 09:30
반응형

iOS 푸시 알림: 앱이 백그라운드에서 사용자가 알림을 눌렀는지 어떻게 감지합니까?

이 토픽에 관한 stackoverflow 스레드가 많이 있습니다만, 아직 좋은 해결책을 찾지 못했습니다.

앱이 백그라운드에 없으면 확인할 수 있습니다.launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]application:didFinishLaunchingWithOptions:알림에서 열렸는지 확인하려고 전화합니다.

백그라운드에 경우 에서 이 앱의 합니다.application:didReceiveRemoteNotification:어플리케이션 상태를 확인합니다.그러나 제가 실험한 것처럼(그리고 이 API의 이름에서도 알 수 있듯이) 이 메서드는 알림이 수신되면 탭이 아닌 호출됩니다.

설정되어 때application:didReceiveNotification )application:didFinishLaunchWithOptions:이 시점에서는 트리거되지 않습니다). 사용자가 알림을 눌러서 앱을 다시 시작했는지 아니면 앱 아이콘을 눌러서 다시 시작했는지 어떻게 알 수 있습니까?사용자가 알림을 누르면 해당 알림에서 언급된 페이지가 열리기 때문입니다.★★★★★★★★★★★★★★★★★★★★★★★★★★★

나는 할 수 있다handleActionWithIdentifier커스텀 액션 알림의 경우는 커스텀액션 버튼을 누를 때만 트리거 됩니다.사용자가 통지 본문을 탭 할 때는 트리거 되지 않습니다.

감사해요.

편집:

아래의 답변을 읽고, 나는 이렇게 내 질문을 명확하게 할 수 있다고 생각했다.

다음 2가지 시나리오를 어떻게 구분할 수 있을까요?

(A) 1.앱이 백그라운드로 이동, 2.알림 수신, 3.알림 사용자 탭, 4.앱이 포그라운드로 들어갑니다.

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

★★application:didReceiveRemoteNotification:경우 .

'아까', '아까보다' 이렇게 해야 돼요.application:didReceiveRemoteNotification:스텝 3에서 트리거되는 것은 (A)에 한해서입니다만, 어떤 이유로 앱을 잘못 설정했기 때문에 스텝 2로 표시하고 있는 것입니까?

그래, 드디어 알았어.

설정 ]탭 Modes에서 [ Notifications [Capabilities]back [ Background Mode ][ Remote Notifications ]를 선택합니다.application:didReceiveRemoteNotification:(앱이 백그라운드에 있는 한) 알림이 도착하자마자 트리거되며, 이 경우 사용자가 알림을 탭할지 여부를 알 수 없습니다.

를 끄면 " " " " 가 됩니다.application:didReceiveRemoteNotification:알림을 누를 때만 트리거됩니다.

이 체크박스를 켜면 앱 위임 메서드 중 하나가 변경되는 것은 조금 이상합니다.이 체크박스를 켜면 애플은 알림 수신과 알림 탭으로 두 가지 위임 방법을 사용합니다.대부분의 개발자들은 항상 알림이 도청되는지 여부를 알고 싶어한다고 생각합니다.

이것이 이 문제에 부딪힌 다른 사람들에게 도움이 되기를 바랍니다.애플도 여기에 명확하게 기록하지 않았기 때문에 알아내는 데 시간이 걸렸습니다.

여기에 이미지 설명 입력

저는 당신과 같은 것을 찾고 있었습니다만, 실제로 리모트 통지가 필요 없는 솔루션을 발견했습니다.

사용자가 탭했는지, 앱이 백그라운드에서 실행 중인지, 활성 상태인지를 확인하려면 에서 애플리케이션 상태를 확인하기만 하면 됩니다.

-(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 Framework Reference ]> [ UIApplication Class Reference ]> [ UIApplication State ]

iOS/XCode에 따르면 알림 또는 스프링보드 아이콘을 클릭번으로 앱이 시작되었는지 어떻게 알 수 있습니까?다음과 같이 didReceiveLocalNotification에서 응용 프로그램 상태를 확인해야 합니다.

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

전혀 이해가 가지 않지만, 효과가 있는 것 같습니다.

만, 에서는 새로운 11이 되어 있습니다.UserNotifications프레임워크

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

  • 출시: ★★★★★★★★★★★★★★★★★★★★:application:didFinishLaunchingWithOptions:
  • 상태로부터 : 「」 「」application(_:didReceiveRemoteNotification:fetchCompletionHandler:)
  • : ★★★★★★★★★★★★★★★★★★★★★★★★★★ ★userNotificationCenter(_:willPresent:withCompletionHandler:)
  • 됨: " " " " "userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:

만약 누군가가 그것을 swift 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
    }

swift 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
}

"Background Modes" > "Remote notifications(원격 알림)"가 선택되어 있는 경우 == "YES(예)"를 누르면 알림 이벤트가 나타납니다.

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

도움이 됐어요.즐겨주세요 :)

된 Push 는 "Push Notification" 2개 안에 .PushNotificationManager 링크:

class PushNotificationManager: NSObject, MessagingDelegate, UNUserNotificationCenterDelegate{

}

알림이 도착하자마자 첫 번째 트리거를 테스트했더니

@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([])
    
}

알림을 탭했을 때의 두 번째 기능:

@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()
}

또, 리모트 통지(백그라운드 모드)의 온/오프 상태에서도 테스트했습니다.

iOS 10 이상에서는 AppDelegate에서 알림이 탭되었음을 알 수 있습니다(앱이 닫히거나 열려 있는 경우에도 작업).

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

내 경우 백그라운드모드 OFF는 아무런 차이가 없습니다.그러나 앱이 정지되어 사용자가 알림을 탭했을 때, 저는 이 콜백 방식으로 케이스를 처리할 수 있었습니다.

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

}

SWIFT 5.1

UIApplication.State앱에서 지문(모달 표시)을 읽으면 알림도 위쪽 표시줄에 표시되므로 사용자가 클릭해야 하기 때문에 작동하지 않았습니다.

작성했습니다.

public static var isNotificationFromApp: Bool = false

AppDelegate그리고 나는 그것을 설정했다.true내가 처음에viewController그리고 제 통지에storyboard/viewController확인만 하면 :)

도움이 되었으면 좋겠다

시행착오를 거듭한 후 도입 타깃 변경으로 해결.

iOS Deployment Target 9.0 10.0, XCode 버전 11.6(11E708)에서도 같은 문제가 발생했습니다.- 앱이 백그라운드에 있을 때 알림을 눌러 위임 메서드 호출을 받지 못했습니다.

이것을 해결한 것은, 타겟을 iOS 11.0으로 변경하는 것이었습니다.드디어 콜드 스타트 시나리오와 백그라운드 시나리오에서 알림 탭으로 전화를 받기 시작했습니다.UNUserNotificationCenterdidReceive:★★★★★★ 。

「하다」는willReceive:이제 (예상대로)는 포그라운드시나리오에서도 콜을 받습니다.

내가 사용하는 페이로드는 다음과 같습니다.해 주세요★★★★★★★★★★★★★★★★★★★★★★★★ 없음content-available , 「」mutable-contentdisclossible을 클릭합니다.

{
  "aps": {
    "sound": "default",
    "badge": 1,
    "alert": {
      "body": "test",
      "title": "test"
    }
  }
}

앱 실행 중(포그라운드) 또는 사용자 탭 중 알림이 수신되었는지 여부를 알 수 있는 '해키' 방법이 있습니다.

TLDR 버전:
사이클은 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★」applicationWillEnterForeground배경화면에서도 볼 수 있어요.따라서 사용자가 탭합니다.

★★★★
(여러 번 언급했듯이) 가장 먼저 필터링해야 할 것은 앱이 비활성 상태인지 여부입니다.

if application.applicationState == .inactive // You can ignore all the rest

백그라운드 상태는 발생하지 않고, 확실히 전경이 되어도 액티브하게 됩니다.앱 상태에 대한 나머지 문제는 실제로 비활성화(사용자가 제어 센터를 풀)하거나 사용자가 탭하여 여는 입니다.
두 경우 모두 상태는 다음과 같습니다.inactive.
그러나 사용자가 알림을 탭하면 앱이 먼저 처리됩니다.applicationWillEnterForeground★★★★★★★★★★★★★★와의 시간차를 확인하는 applicationWillEnterForeground로로 합니다.didReceiveRemoteNotification을 사용하다

// In AppDelegate

var applicationWillEnterForegroundTime = Date()

func applicationWillEnterForeground(_ application: UIApplication) {
    applicationWillEnterForegroundTime = Date()
}

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    
    if application.applicationState == .inactive,
       Date().timeIntervalSince(applicationWillEnterForegroundTime) < 1.0 {
        // Push notification was opened by user tap
    }
}

알렉스가 말한 것처럼 우리는userNotificationCenter(_:didReceive:withCompletionHandler:)(doc) 통지에 대한 사용자 응답을 캡처하는 방법.의 대표를 설정해야 합니다.UNUserNotificationCenterapplication(_:didFinishLaunchingWithOptions:) ★★★★★★★★★★★★★★★★★」application(_:willFinishLaunchingWithOptions:)AppDelegate 。기본적으로 제가 한 일은 다음과 같습니다.

첫번째,

import UserNotifications

번째, 째, 들을 만듭니다.AppDelegateUNUserNotificationCenterDelegate

@UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
// your app delegate code
}

번째,, 리, 리, 정, 정, of, thirdUNUserNotificationCenter를 제기하다AppDelegate에 inside inside inside application(_:willFinishLaunchingWithOptions:)

func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
    UNUserNotificationCenter.current().delegate = self
    return true
}

userNotificationCenter(_:didReceive:withCompletionHandler:)

func userNotificationCenter(_ center: UNUserNotificationCenter,
           didReceive response: UNNotificationResponse,
           withCompletionHandler completionHandler: @escaping () -> Void) {
    let application = UIApplication.shared
    if response.actionIdentifier == UNNotificationDefaultActionIdentifier {
        let userInfo = response.notification.request.content.userInfo
        self.handlePushNotification(application, userInfo: userInfo)
    }
}

마지막으로 ★★★★★★★★★★★★★★★★★★★★★★★★」handlePushNotificationMethod이는 알림을 처리하기 위한 모든 로직을 구현하는 개인 방법입니다.

func handlePushNotification(userInfo: [AnyHashable : Any]) {
    if let aps = userInfo["aps"] as? NSDictionary {
    ...
    }
}

방법 「 」 「 」 )userNotificationCenter(_:didReceive:withCompletionHandler:)는 사용자가 때 또는 할 때 는 사용자가 알림을 탭할 때 또는 사용자가 알림에 대해 어떤 액션을 수행할 때 호출됩니다.저 같은 경우에는 알림만 받고 싶었어요. 그 액션을 .'아이디' '아이디'

이용 가능 여부에 주의해 주십시오.UserNotifications구현 중에 프레임워크가 필요합니다.

하여 앱의 payload를 할 수 .application:didReceiveRemoteNotification:fetchCompletionHandler:★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★사용자가 다음에 프로그램을 시작할 때 작업을 수행할 수 있도록 여기서 플래그를 설정할 수 있습니다.

Apple 문서에서 푸시 알림과 관련된 새 콘텐츠를 다운로드하려면 이 방법을 사용해야 합니다.이하려면 , 「Remote 」를 하게 할 가 있습니다.또, 푸시 에 「Remote notification from Background mode」가 포함되어 있을 가 있습니다.content-available키 값을 1로 설정합니다.자세한 내용은 여기를 참조하십시오.푸시 알림을 사용하여 다운로드 시작 섹션을 참조하십시오.

다른 방법은 푸시 알림 페이로드에 배지 수를 설정하는 것입니다.따라서 다음 번에 애플리케이션을 시작할 때 애플리케이션 배지 수를 확인할 수 있습니다.0보다 큰 경우는, 조작을 실행해, 서버로부터의 배지 카운트도 제로/클리어 합니다.

도움이 되시길 바랍니다.

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

반응형