ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [iOS] 푸시 알림에서 받은 url을 웹뷰에 띄우기, postman 푸시 테스트
    iOS 2024. 3. 15. 00:15

    앱에서 수신한 푸시 알림을 탭했을 때, 알림에서 받은 url을 웹뷰로 띄우는 방법입니다.

     

    xCode Project와 FCM Push Notification 연동은 여기를 참고해주시면 됩니다!

    테스트를 위해 푸시 서버에서 알림을 받는 대신 postman을 사용하겠습니다.

    우선 postman 푸시 테스트 방법 먼저 설명드리겠습니다.

     

    1. postman 푸시 테스트


    1) Firebase 프로젝트 > 프로젝트 설정 > 클라우드 메시징 에서 Cloud Messaging API 사용하기

    처음 키면 아마 사용 중지됨으로 되어있을텐데, 오른쪽 더보기에서 Google Cloud Console에서 API 관리를 들어가 사용 버튼을 누르면 사용하실 수 있습니다!

    2) 서버 키 복사해두기

    postman으로 푸시 알림을 보낼 때 사용될 서버 키를 복사해둡니다.

     

    3) postman > New Collection > New Request 에서 푸시 알림 설정

    https://fcm.googlepis.com/fcm/send 를 입력해줍니다. Method는 POST로 설정해줍니다.

    Headers에는 

    Authorization: key=(서버 키)

    Content-Type: application/json

    을 넣어줍니다.

     

    Body에는 raw 형식, JSON으로 설정하고

    푸시 알림 데이터를 넣어줍니다.

    data 값에는 link: url을 넣어줬습니다!

    이렇게 테스트 준비는 다 됐습니다! 테스트할 때 Send 버튼을 누르면 푸시 알림이 앱에 전송될 겁니다.

     

    2. 푸시 알림에서 받은 url로 웹뷰 이동하기


    서버로부터 받은 알림 데이터의 url을 웹뷰로 보여주기 위해서는 최상위 ViewController에서 WebViewController로 화면 전환을 해야합니다!

     

    따라서, 최상위 ViewController를 판단해줄 메서드를 작성해줍니다. 그다음으로 포그라운드, 백그라운드에서에 알림을 받느냐의 상황에 따라 url을 웹뷰로 보여주는 코드를 작성할 겁니다.

     

    1) 최상위 ViewController 판단 메서드 구현하기

     

    이 코드는 ViewController.swift에 작성해주시면 됩니다.

    extension UIViewController {
        var topViewController: UIViewController? {
            return self.topViewController(currentViewController: self)
        }
        
        // 최상위 뷰컨트롤러를 판단해주는 메서드
        func topViewController(currentViewController: UIViewController) -> UIViewController {
            if let tabBarController = currentViewController as? UITabBarController, let selectedViewController = tabBarController.selectedViewController {
                return self.topViewController(currentViewController: selectedViewController)
            } 
           	else if let navigationControler = currentViewController as? UINavigationController, let visibleViewController = navigationController.visibleController {
            	return self.topViewController(currentViewController: visibleController)
            }
            else if let presentedViewController = currentViewController.presentedViewController {
                return self.topViewController(currentViewController: presentedViewController)
            }
            else {
                return currentViewController
            }
        }
    }

    이 코드를 통해서 최상위 뷰컨트롤러인 topViewController가 tabBarController인지, navigationViewController인지, 일반 ViewController인지 알아낼 수 있습니다.

     

    이제 AppDelegate.swift에서 알림을 탭했을 때 포그라운드, 백그라운드에 따라 최상위 뷰컨트롤러에 웹뷰로 전환하는 코드를 작성합니다.

     

    2) 푸시 알림을 클릭했을 때 받은 알림 데이터 처리하기(포그라운드, 백그라운드)

     

    푸시 알림을 클릭했을 때 호출되는 함수는 userNotificationCenter(_:didReceive:) 입니다.

    /// 푸시클릭시
    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        print("🥺", #function)
    
    
        if let userInfo = response.notification.request.content.userInfo as? [String: Any] {
            print(userInfo)
    
            if let link = userInfo["link"] {
                print("푸시 눌러짐: \(link)")
                guard let viewController = (UIApplication.shared.connectedScenes.first?.delegate as? SceneDelegate)?.window?.rootViewController?.topViewController else { return }
    
                print("현재 ViewController: \(viewController)")
    
    		// 포그라운드일 때
                if UIApplication.shared.applicationState == .active {
                    print("포그라운드에서 클릭")
                    let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
                    let webVC = storyBoard.instantiateViewController(withIdentifier: "WebViewController") as! WebViewController
                    webVC.selectedURL = link as! String
    
                    viewController.present(webVC, animated: true, completion: nil)
                }
                else {	// 백그라운드일 때
                    print("백그라운드에서 클릭")
                    let userDefault = UserDefaults.standard
                    userDefault.set(link, forKey: "notiLink")
                    userDefault.synchronize()
                }
            } else {  // url 없을 경우
                print("푸시는 눌러졌지만, url에 값이 없음")
            }
    
        }
        completionHandler()
    }

     

     

    코드를 살펴보겠습니다.

     

    서버에서 알림 데이터에 "link"라는 키값으로 url을 보냈기 때문에

    아래와 같은 코드로 url을 가져와서 link 값이 있을 경우에만 처리합니다.

    if let userInfo = response.notification.request.content.userInfo as? [String: Any] {
        if let link = userInfo["link"] {
            // 여기서 코드 작성
        } else {
            print("link 값 없음")
        }
    }

     

    link에 값이 있으면 이 link를 웹뷰로 보여주는 작업을 해야합니다. 그 전에 최상위 뷰컨트롤러를 가져와야 하겠죠?

    아래 코드를 통해 최상위 뷰컨트롤러를 가져옵니다.

    guard let viewController = (UIApplication.shared.connectedScenes.first?.delegate as? SceneDelegate)?.window?.rootViewController?.topViewController else { return }

     

    그런 다음 포그라운드일 때와 백그라운드일 때를 나눠서 웹뷰를 보여줄 겁니다.

    포그라운드일 때는 앱이 이미 실행중이기 때문에 최상위 뷰컨트롤러에서 웹뷰로 전환해줄 겁니다.

    참고로 WebViewController는 WebKit를 사용해서 구현하였습니다. 이 부분은 다음에 포스팅하겠습니다.

     

    웹뷰에 보여줄 url 주소를 아까 받아온 link로 설정해준 뒤, 화면전환을 해줍니다.

    // 포그라운드일 때
    if UIApplication.shared.applicationState == .active {
        print("포그라운드에서 클릭")
        let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
        let webVC = storyBoard.instantiateViewController(withIdentifier: "WebViewController") as! WebViewController
        webVC.selectedURL = link as! String
    
        viewController.present(webVC, animated: true, completion: nil)
    }

     

    백그라운드에서 알림을 탭했을 때는 앱이 실행중이 아니기 때문에 앱 시작화면에서 WebViewController로 화면전환을 해줄 겁니다.

    우선 알림 서버로부터 받은 url을 UserDefaults에 키값으로 저장합니다.

    else {    // 백그라운드일 때
        print("백그라운드에서 클릭")
        let userDefault = UserDefaults.standard
        userDefault.set(link, forKey: "notiLink")
        userDefault.synchronize()
    }

     

    이렇게 저장된 UserDefaults에 link를 사용해서

    앱이 백그라운드 상태에서 포그라운드 상태로 전환됐을 때 웹뷰로 전환하면 됩니다.

    아래 코드는 앱을 켰을 때 처음 보이는 ViewController의 viewDidLoad()에 작성해주면 됩니다.

    // 백그라운드에서 포그라운드로 전환되면 실행하는 함수
    NotificationCenter.default.addObserver(forName: UIApplication.didBecomeActiveNotification, object: nil, queue: nil) { (Notification) in
    
        let notiLink: String? = self.UD.string(forKey: "notiLink")
    
        if (notiLink != nil) {
            print(notiLink ?? "link 값 없음")
            print("푸시에서 전달받은 url로 웹뷰 띄우기")
    
            let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
            let webVC = storyBoard.instantiateViewController(withIdentifier: "WebViewController") as! WebViewController
            webVC.selectedURL = notiLink ?? "nil"
    
            self.present(webVC, animated: true, completion: nil)
            self.UD.removeObject(forKey: "notiLink")
            self.UD.synchronize()
        }
    }

     

     

    3. 테스트 해보기


    1번 과정을 다 따라한 다음 테스트해볼 수 있습니다.

    send 버튼을 누르면 다음과 같이 알림이 뜹니다. (백그라운드, 앱 종료 상태일때도 알림이 뜹니다!)

     

     

     

    알림을 탭하면 웹뷰로 전환하여 서버에서 받아온 url 웹사이트를 보여줍니다.

     

     

     

    [참고]

    https://developer111.tistory.com/50

    https://nsios.tistory.com/191

Designed by Tistory.