SeSAC_iOS_Day 56 | TIL

린다·2021년 12월 16일
0

SSAC_iOS_Dev

목록 보기
27/33
post-thumbnail

📂 Push Notification

전에 Wandoo! 프로젝트 진행할 때 local notification을 개발해야되는데 remote notification과 local notification을 구분하지 못하고 remote notification을 공부해서 프로젝트에 연결시킬뻔 한적이 있다...ㅋㅋㅋㅋ 그때 공부했던 부분을 돌이켜보며 오늘 수업 복습을...🙃

✔️ APNs(Apple Push Notification Provider)

: 각 디바이스로 보내려고 하는 메세지를 받고 신뢰도를 검사해서 각 디바이스로 푸시알림을 보내줌 -> 모든 푸시 알림을 보내기 위한 중재센터

Provider가 APNs에 메세지를 보냄 → APNs에서 인증서를 확인해서 신뢰하는 Provider인지 확인 → 각 디바이스로 알림 보내줌

→ APNs는 Provider와 Device사이에 각각의 인증서가 필요함

✔️ Provider ↔ APNs

  • Token-based provider connection trust
  • Certificate-based provider connection trust
    : Apple에서 제공한 공급자 인증서를 이용하는 방법(Bundle Identifier를 대상으로 동작) → p8 방식 이용

  1. Provider가 APNs 서버로 TLS 연결 설정
  2. APNs로부터 Certificate 발급받음
  3. Apple-provisioned provider Certificate를 포함해서 APNs에게 보냄(Apple Developer 사이트로부터 발급받을 수 있는 자격증명서)
  4. 해당 증명서가 유효하다면 둘 사이에 연결이 설정됨

✔️ APNs ↔ Device

  • 각 디바이스에는 암호화 인증서개인 암호화 키가 있음
  • 이를 Device의 운영체제에서 기본으로 제공하고 KeyChain에 저장됨
  • APNs는 인증서 및 키를 기반으로 장치에 대한 연결을 인증하고 유효성 검사를 함
  • 연결이 설정되면 앱이 APN에 등록되고 원격 알림을 위한 앱별 장치 토큰을 받을 수 있음
  • APNs에서 앱별로 토큰을 발급하는데 NSData 타입으로 인코딩돼있음. APNs에서만 이를 디코딩할 수 있음
  • 기기 토큰을 받고나서 Provider에게 연결하고 토큰을 전달해야함. 앱으로 푸쉬 알림을 보내기 위해서는 꼭 장치 토큰을 포함해야하기 때문에!!
  • 기기 토큰을 받고 나서야 Provider는 Device로 푸쉬알림을 보낼 수 있음.
  • APNs에서도 이 토큰을 받고 수신자, 발신자가 모두 신뢰되면 그때 푸쉬알림을 보내줌

✔️ Local Notification을 위해 설정해줘야하는 과정

  1. Apple Developer Site
    1-1. 푸시알림을 보내고자 하는 프로그램의 App Identifier 등록(Push Notification 등록)
    1-2. 푸시 알림 인증키 발급
  • 개발자 계정을 구매하면 개발/배포에 관련된 키는 자동으로 발급돼있음
  • 하지만 푸시 알림용 인증키는 구분돼있기 때문에 추가적으로 발급받아서 다운받아야함(p8형식)
  • p8은 public key라서 여러 앱에서 사용할 수 있고 만료기간도 없음. p12는 private key라서 각 앱별로 필요함. 1년마다 갱신도 필요함.
  • p8 vs p12 : p12는 p8 등장 이후 사용되지 않음, p8 사용이 권장됨
  1. Xcode App - Capabilities
  • Push Notification, Background Modes(Remote Notifiaction 체크) 추가해줘야함
  1. Firebase 연동
    3-1. 프로젝트 설정 - 클라우드 메시징 - APNs 인증키 업로드(키 ID & 팀 ID)
    3-2. 코드 구현(AppDelegate)
  • 알림 등록(권한 요청) & UNUserNotificationCenterDelegate 프로토콜 채택
        if #available(iOS 10.0, *) {
          // For iOS 10 display notification (sent via APNS)
          UNUserNotificationCenter.current().delegate = self

          let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
          UNUserNotificationCenter.current().requestAuthorization(
            options: authOptions,
            completionHandler: { _, _ in }
          )
        } else {
          let settings: UIUserNotificationSettings =
            UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
          application.registerUserNotificationSettings(settings)
        }

        application.registerForRemoteNotifications()
  • firebase가 푸시 메세지를 대신 전송할 수 있도록 대리자 설정 & MessagingDelegate 프로토콜 채택
        Messaging.messaging().delegate = self
        
        // 현재 사용중인 토큰 가져오기
        Messaging.messaging().token { token, error in
          if let error = error {
            print("Error fetching FCM registration token: \(error)")
          } else if let token = token {
            print("FCM registration token: \(token)")
              // 화면에 보여줄 필요가 없기 때문에 삭제하면 됨
//            self.fcmRegTokenMessage.text  = "Remote FCM registration token: \(token)"
          }
        }
  • 등록된 토큰이 갱신될 때 마다 모니터링하기 위한 코드
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
  print("Firebase registration token: \(String(describing: fcmToken))")

  let dataDict: [String: String] = ["token": fcmToken ?? ""]
  NotificationCenter.default.post(
    name: Notification.Name("FCMToken"),
    object: nil,
    userInfo: dataDict
  )
  // TODO: If necessary send token to application server.
  // Note: This callback is fired at each app startup and whenever a new token is generated.
}
  • APN 토큰을 FCM 등록 토큰에 매핑
func application(application: UIApplication,
                 didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
  Messaging.messaging().apnsToken = deviceToken
}
  1. Foreground 일 때 알림 처리(로컬/리모트 동일)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        completionHandler([.alert, .badge, .sound])
    }

0개의 댓글