programing

앱이 포그라운드 iOS에 있는 동안 푸시 알림 받기

linuxpc 2023. 4. 26. 23:02
반응형

앱이 포그라운드 iOS에 있는 동안 푸시 알림 받기

저는 제 앱에서 푸시 알림 서비스를 사용하고 있습니다.앱이 백그라운드에 있을 때 알림 화면(iOS 기기 상단에서 아래로 스와이프할 때 표시되는 화면)에서 알림을 볼 수 있습니다.그러나 응용 프로그램이 포그라운드에 있는 경우 대리자 방법

- (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo

가 호출되지만 알림 화면에 알림이 표시되지 않습니다.

앱이 백그라운드인지 포그라운드인지에 관계없이 알림 화면에 알림을 표시하고 싶습니다.해결책을 찾느라 피곤합니다.어떤 도움이든 대단히 감사합니다.

앱이 포그라운드에 있는 동안 배너 메시지를 표시하려면 다음 방법을 사용합니다.

iOS 10, Swift 3/4:

// This method will be called when app received push notifications in foreground
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) 
{
    completionHandler([.alert, .badge, .sound])
}

iOS 10, Swift 2.3:

@available(iOS 10.0, *)
func userNotificationCenter(center: UNUserNotificationCenter, willPresentNotification notification: UNNotification, withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void)
{
    //Handle the notification
    completionHandler(
       [UNNotificationPresentationOptions.Alert,
        UNNotificationPresentationOptions.Sound,
        UNNotificationPresentationOptions.Badge])
}

또한 앱 대리인을 알림 센터의 대리인으로 등록해야 합니다.

import UserNotifications

// snip!

class AppDelegate : UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate

// snip!

   func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

      // set the delegate in didFinishLaunchingWithOptions
      UNUserNotificationCenter.current().delegate = self
      ...
   }

아래의 코드가 당신에게 도움이 될 것입니다.

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo  {
    application.applicationIconBadgeNumber = 0;             
    //self.textView.text = [userInfo description];
    // We can determine whether an application is launched as a result of the user tapping the action
    // button or whether the notification was delivered to the already-running application by examining
    // the application state.

    if (application.applicationState == UIApplicationStateActive) {                
        // Nothing to do if applicationState is Inactive, the iOS already displayed an alert view.                
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Did receive a Remote Notification" message:[NSString stringWithFormat:@"Your App name received this notification while it was running:\n%@",[[userInfo objectForKey:@"aps"] objectForKey:@"alert"]]delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alertView show];          
    }    
}

목표 C

여기에 이미지 설명 입력

위해서iOS 10우리는 통합이 필요합니다.willPresentNotification를 림알배 방법시에 foreground.

앱이 포그라운드 모드(활성)인 경우

- (void)userNotificationCenter:(UNUserNotificationCenter* )center willPresentNotification:(UNNotification* )notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler {
    NSLog( @"Here handle push notification in foreground" ); 
    //For notification Banner - when app in foreground
    
    completionHandler(UNNotificationPresentationOptionAlert);
    
    // Print Notification info
    NSLog(@"Userinfo %@",notification.request.content.userInfo);
}

누구나 관심을 가질 수 있도록 상단에 시스템 푸시 배너처럼 보이지만 닫기 버튼(작은 파란색 X)과 사용자 지정 작업을 위한 메시지를 탭할 수 있는 옵션을 추가하는 사용자 지정 보기를 만들었습니다.또한 사용자가 이전 알림을 읽거나 무시할 시간이 생기기 전에 두 개 이상의 알림이 도착한 경우도 지원합니다(쌓일 수 있는 알림 수 제한 없음...).

GitHub 링크: AGPush참고

사용법은 기본적으로 온라인입니다.

[AGPushNoteView showWithNotificationMessage:@"John Doe sent you a message!"];

iOS7에서는 이렇게 보입니다. (iOS6에는 iOS6 모양과 느낌이 있습니다...)

여기에 이미지 설명 입력

응용 프로그램이 포그라운드에서 실행 중인 경우 iOS는 알림 배너/경보를 표시하지 않습니다.그것은 의도적인 것입니다.하지만 우리는 사용함으로써 그것을 이룰 수 있습니다.UILocalNotification과 같이

  • 시 합니다.
    알림. 로컬합니다.활성 상태인 경우 UI 로컬 알림을 실행합니다.

    if (application.applicationState == UIApplicationStateActive ) {
    
        UILocalNotification *localNotification = [[UILocalNotification alloc] init];
        localNotification.userInfo = userInfo;
        localNotification.soundName = UILocalNotificationDefaultSoundName;
        localNotification.alertBody = message;
        localNotification.fireDate = [NSDate date];
        [[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
    }
    

스위프트:

if application.applicationState == .active {
    var localNotification = UILocalNotification()
    localNotification.userInfo = userInfo
    localNotification.soundName = UILocalNotificationDefaultSoundName
    localNotification.alertBody = message
    localNotification.fireDate = Date()
    UIApplication.shared.scheduleLocalNotification(localNotification)
}

Xcode 10 Swift 4.2

앱이 포그라운드에 있을 때 푸시 알림을 표시하려면 -

1단계: AppDelegate 클래스에 대리자 UNUserNotificationCenterDelegate를 추가합니다.

class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {

2단계: UNUser Notification Center 대리자 설정

let notificationCenter = UNUserNotificationCenter.current()
notificationCenter.delegate = self

3단계: 이 단계에서는 앱이 포그라운드에 있을 때도 푸시 알림을 표시할 수 있습니다.

func userNotificationCenter(_ center: UNUserNotificationCenter,
                                willPresent notification: UNNotification,
                                withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        completionHandler([.alert, .sound])

    }

4단계: 이 단계는 선택 사항입니다.앱이 포그라운드에 있는지 확인하고 포그라운드에 있는지 확인한 후 로컬 푸시 알림을 표시합니다.

func application(_ application: UIApplication,didReceiveRemoteNotification userInfo: [AnyHashable: Any],fetchCompletionHandler completionHandler:@escaping (UIBackgroundFetchResult) -> Void) {

        let state : UIApplicationState = application.applicationState
        if (state == .inactive || state == .background) {
            // go to screen relevant to Notification content
            print("background")
        } else {
            // App is in UIApplicationStateActive (running in foreground)
            print("foreground")
            showLocalNotification()
        }
    }

로컬 알림 기능 -

fileprivate func showLocalNotification() {

        //creating the notification content
        let content = UNMutableNotificationContent()

        //adding title, subtitle, body and badge
        content.title = "App Update"
        //content.subtitle = "local notification"
        content.body = "New version of app update is available."
        //content.badge = 1
        content.sound = UNNotificationSound.default()

        //getting the notification trigger
        //it will be called after 5 seconds
        let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 1, repeats: false)

        //getting the notification request
        let request = UNNotificationRequest(identifier: "SimplifiedIOSNotification", content: content, trigger: trigger)

        //adding the notification to notification center
        notificationCenter.add(request, withCompletionHandler: nil)
    }

스위프트 5용

에 대한 의 확인을 " 앱딜정제다공니합를러"를 합니다.UNUserNotificationCenterDelegate

2)UNUserNotificationCenter.current().delegate = selfdidFinishLaunch

의 방법을 구다니합현을법의 합니다.AppDelegate.

func userNotificationCenter(_ center: UNUserNotificationCenter,
                                willPresent notification: UNNotification,
                                withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
     print("Push notification received in foreground.")
     completionHandler([.alert, .sound, .badge])
}

바로 그거야!

응용 프로그램이 포그라운드에서 실행 중인 경우 iOS는 알림 배너/경보를 표시하지 않습니다.그것은 의도적인 것입니다.당신은 앱이 포그라운드에 있는 동안 알림을 받는 상황에 대처하기 위해 코드를 작성해야 합니다.가장 적절한 ▁a▁to▁number▁a▁you▁badge▁in(ification추▁not합니▁adding다for▁the가▁example,).UITabBar알림 센터)에서 확인할 수 있습니다.

배너 알림을 모방한 고유한 알림을 만들 수 있습니다.

한 가지 방법은 배너처럼 보이고 애니메이션을 만들고 터치에 응답할 수 있는 사용자 정의 보기를 만드는 것입니다.이러한 점을 염두에 두고 더욱 우수한 기능을 갖춘 배너를 만들 수 있습니다.

또는 이를 수행하는 API를 찾아 프로젝트에 포드 파일로 추가할 수 있습니다.

다음은 제가 사용한 몇 가지 예입니다.

https://github.com/terryworona/TWMessageBarManager

https://github.com/toursprung/TSMessages

앱이 활성 상태(포그라운드 또는 오픈)일 때 푸시 알림을 받을 코드입니다.UNUser Notification Center 문서

@available(iOS 10.0, *)
func userNotificationCenter(center: UNUserNotificationCenter, willPresentNotification notification: UNNotification, withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void)
{
     completionHandler([UNNotificationPresentationOptions.Alert,UNNotificationPresentationOptions.Sound,UNNotificationPresentationOptions.Badge])
}

한 경우 code: userInfo를 합니다.notification.request.content.userInfo

delegate 메서드에 completionHandler 행을 추가하면 동일한 문제가 해결되었습니다.

//Called when a notification is delivered to a foreground app.
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {

completionHandler([.alert, .badge, .sound])
} 

swift 5가 PushNotification 사전을 구문 분석하는 경우

    func application(_ application: UIApplication, didReceiveRemoteNotification data: [AnyHashable : Any]) {
            if application.applicationState == .active {
                if let aps1 = data["aps"] as? NSDictionary {
                    if let dict = aps1["alert"] as? NSDictionary {
                        if let strTitle = dict["title"] as? String , let strBody = dict["body"] as? String {
                            if let topVC = UIApplication.getTopViewController() {
                                //Apply your own logic as per requirement
                                print("strTitle ::\(strTitle) , strBody :: \(strBody)")
                            }
                        }
                    }
                }
            }
        }

상단 배너를 표시하는 상단 뷰 컨트롤러를 가져오려면 다음과 같이 하십시오.

extension UIApplication {

    class func getTopViewController(base: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? {

        if let nav = base as? UINavigationController {
            return getTopViewController(base: nav.visibleViewController)

        } else if let tab = base as? UITabBarController, let selected = tab.selectedViewController {
            return getTopViewController(base: selected)

        } else if let presented = base?.presentedViewController {
            return getTopViewController(base: presented)
        }
        return base
    }
}

앱에서 딜러는 아래 코드를 사용합니다.

import UIKit
import UserNotifications
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
 var currentToken: String?
 var window: UIWindow?
 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        application.registerForRemoteNotifications()
        let center = UNUserNotificationCenter.current()
        center.requestAuthorization(options: [.alert, .sound, .badge]) { (granted, error) in

            // Enable or disable features based on authorization.
            if granted == true
            {
                print("Allow")
                UIApplication.shared.registerForRemoteNotifications()
            }
            else
            {
                print("Don't Allow")
            }
        }
        UNUserNotificationCenter.current().delegate = self

        return true
    }
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data){
        let tokenParts = deviceToken.map { data -> String in
            return String(format: "%02.2hhx", data)
        }
        let token = tokenParts.joined()
        currentToken = token  //get device token to delegate variable

    }
 public class var shared: AppDelegate {
        return UIApplication.shared.delegate as! AppDelegate
    }
 func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
         completionHandler([.alert, .badge, .sound])
    }
}

iOS 14+

.alert는 더 이상 사용하지 않으며 .banner를 사용하여 다음과 같은 대답을 수행합니다.

class AppDelegate: NSObject, UIApplicationDelegate, UNUserNotificationCenterDelegate {
    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil
    ) -> Bool {
        UNUserNotificationCenter.current().delegate = self

        return true
    }

    func userNotificationCenter(
        _ center: UNUserNotificationCenter,
        willPresent notification: UNNotification,
        withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void
    ) {
        completionHandler([.banner, .badge, .sound])
    }
}

이를 위한 최선의 접근 방식은 다음과 같습니다.UNUserNotificationCenterDelegateAppDelegate을 이용하여extension AppDelegate: UNUserNotificationCenterDelegate이 사용 때 수 .

그리고 이 방법을 실행합니다.

func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        completionHandler(.alert)
    }

이 메서드는 응용 프로그램이 포그라운드에 있는 경우에만 대리자에게 호출됩니다.

최종 구현:

extension AppDelegate: UNUserNotificationCenterDelegate {
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        completionHandler(.alert)
    }
}

.didFinishLaunchingWithOptions 행을 합니다.

UNUserNotificationCenter.current().delegate = self

수정할 수 있습니다.

completionHandler(.alert) 

와 함께

completionHandler([.alert, .badge, .sound]))

iOS 14+에서도 작동하므로 알림이나 보기를 수동으로 처리할 필요가 없습니다. iOS가 작업을 수행하도록 하기만 하면 됩니다.

알림을 받는 내부에서는 아래 코드로 대체합니다.

func userNotificationCenter(
    _ center: UNUserNotificationCenter,
    willPresent notification: UNNotification,
    withCompletionHandler completionHandler:
    @escaping (UNNotificationPresentationOptions) -> Void
  ) {
    
    if (UIApplication.shared.applicationState == .inactive || UIApplication.shared.applicationState == .background) {
      if #available(iOS 14.0, *) {
        completionHandler([[.banner, .sound]])
      } else {
        completionHandler([.alert, .sound])
      }
    } else {
      if #available(iOS 14.0, *) {
        completionHandler([[.banner]])
      } else {
        completionHandler([.alert])
      }
    }
  }

주의해야 할 주요 사항은 지면에 배너가 표시되지 않는 동안 소리를 사용하지 않는 것입니다.

위에서 언급한 바와 같이, 당신은 다음을 사용해야 합니다.UserNotification.framework이를 위해하지만 제 목적을 위해서는 어쨌든 앱에서 보여줘야 하고 갖고 싶었습니다.iOS 11스타일, 그래서 제가 작은 도우미 뷰를 만들었습니다. 누군가에게 유용할 수도 있습니다.

GitHub iOS 11 푸시 알림 보기

100% 작업 테스트 완료

첫번째 가져오기

import UserNotifications

그런 다음 클래스에 대리인을 추가합니다.

UN 사용자 알림 센터 대표자


class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate

앱이 열려 있고 알림이 오는 동안에는 다음 방법이 책임집니다.

선물할 것

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

           let alertVC = UIAlertController.init(title: title, message: body, preferredStyle: .alert)

            alertVC.addAction(UIAlertAction.init(title: appLan_share.Ok_txt, style: .default, handler: {
                _ in
                   //handle tap here or navigate somewhere…..                
            }))

            vc?.present(alertVC, animated: true, completion: nil)

            print("notification Data: \(content.userInfo.values)")
                completionHandler([.alert, .sound])



}

또한 현재 응용프로그램 상태를 확인하여 응용프로그램 상태를 처리할 수 있습니다.

또한 앱이 실행되지 않는 경우 다음 방법이 푸시 알림을 처리합니다.

받았습니까?

func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        let userInfo = response.notification.request.content.userInfo
        let aps = userInfo["aps"] as? [String: Any]
        let alert = aps?["alert"] as? [String: String]

}

응용프로그램이 포그라운드 상태이면 현재 동일한 응용프로그램을 사용하고 있음을 의미합니다.따라서 일반적으로 상단에 알림을 표시할 필요가 없습니다.

그러나 이 경우에도 알림을 표시하려면 사용자에게 알림을 받았다는 것을 보여주기 위해 사용자 정의 알림 보기 또는 토스트와 같은 사용자 정의 보기를 만들어야 합니다.

앱에 그런 기능이 있으면 상단에 배지를 표시할 수도 있습니다.

@Danial Martine이 말했듯이 iOS는 알림 배너/경보를 표시하지 않습니다.그것은 의도적인 것입니다.하지만 정말로 그것을 해야 한다면 한 가지 방법이 있습니다.저도 마찬가지로 이것을 달성했습니다.

1.Parse FrameWork에서 Parse Framework를 다운로드합니다.

2.수입#import <Parse/Parse.h>

3.didReceiveRemoteNotification Method에 다음 코드를 추가합니다.

 - (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
{
    [PFPush handlePush:userInfo];
}

PFPush는 원격 알림을 처리하는 방법에 대해 주의를 기울일 것입니다. App이 포그라운드에 있으면 알림을 표시하고 그렇지 않으면 알림을 맨 위에 표시합니다.

언급URL : https://stackoverflow.com/questions/14872088/get-push-notification-while-app-in-foreground-ios

반응형