[swift] Swift에서 푸시 알림을 사용하여 채팅 메시지 알림 제공하기

채팅 애플리케이션을 개발할 때, 새로운 채팅 메시지가 도착했을 때 사용자에게 푸시 알림을 보내는 기능은 매우 중요합니다. Swift에서는 이러한 기능을 구현하기 위해 Apple의 푸시 알림 서비스인 APNs(Apple Push Notification service)를 사용할 수 있습니다.

1. 프로젝트 설정

먼저 Xcode에서 프로젝트를 열고, 푸시 알림을 사용하려면 애플 개발자 계정이 필요합니다. 개발자 계정을 생성한 후 프로젝트 설정에서 해당 계정을 연결하세요.

2. APNs 인증서 만들기

APNs를 사용하기 위해 인증서를 만들어야 합니다.

  1. 애플 개발자 포털에 로그인한 다음, “Certificates, Identifiers & Profiles”로 이동하세요.
  2. “Identifiers” 탭에서 애플리케이션의 Bundle Identifier를 선택하고, “Push Notifications”을 활성화하세요.
  3. “Certificates” 탭으로 이동하고 “+” 버튼을 클릭하여 “Apple Push Notification service SSL (Sandbox & Production)”을 선택하세요.
  4. 인증서를 생성하기 위해 CSR(Certificate Signing Request)을 만들어야 합니다. Keychain Access를 실행하고, “Certificate Assistant” 메뉴에서 “Request a Certificate from a Certificate Authority”를 선택하세요. 이후 키 쌍을 생성하고, CSR 파일을 생성한 후 개발자 포털에서 이를 업로드하세요.
  5. 인증서를 다운로드하고 더블 클릭하여 Keychain에 설치하세요.

3. 푸시 알림 등록

푸시 알림을 사용하기 위해 앱 델리게이트 파일에 다음 코드를 추가해야 합니다.

import UserNotifications

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // APNs 등록 요청
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { (granted, error) in
            // 등록 실패 처리
            if let error = error {
                print("Failed to register for remote notifications: \(error.localizedDescription)")
                return
            }
            // 등록 성공 처리
            if granted {
                DispatchQueue.main.async {
                    UIApplication.shared.registerForRemoteNotifications()
                }
            }
        }
        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()
        print("Device Token: \(token)")
    }

    // 푸시 알림 등록 실패 시 호출되는 메서드
    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
        print("Failed to register for remote notifications: \(error.localizedDescription)")
    }
}

위 코드에서 AppDelegate 클래스는 앱 델리게이트의 일부로 사용됩니다. application(_:didFinishLaunchingWithOptions:) 메서드 내에서 UNUserNotificationCenterrequestAuthorization 메서드를 호출하여 사용자에게 푸시 알림 권한을 요청합니다. 푸시 알림 권한이 부여되면, 앱을 등록하고 기기 토큰을 얻기 위해 application(_:didRegisterForRemoteNotificationsWithDeviceToken:) 메서드가 호출됩니다.

4. 서버와 연동

푸시 알림을 사용하기 위해서는 백엔드 서버와의 연동이 필요합니다. 서버는 앱의 기기 토큰을 저장하고, 새로운 메시지가 도착했을 때 해당 토큰을 사용하여 푸시 알림을 보냅니다. 서버에서는 APNs 사용을 위한 인증서와 토큰을 사용하여 알림을 전송하는 프로세스를 구현해야 합니다.

5. 푸시 알림 보내기

서버와의 연동이 완료되면, 푸시 알림을 보내는 코드를 구현할 수 있습니다. 서버에서 새로운 채팅 메시지가 도착했을 때, 이 알림을 푸시 알림으로 변환하여 사용자에게 전송합니다.

예를 들어, 다음 코드는 푸시 알림을 보내는 함수를 구현한 예입니다.

import UIKit
import UserNotifications

func sendPushNotification(to deviceTokens: [String], title: String, body: String) {
    let apnsAuthKey = "<Your APNs Auth Key>"
    let apnsKeyID = "<Your APNs Key ID>"
    let apnsTeamID = "<Your Team ID>"

    let headers = [
        "Authorization": "Bearer \(apnsAuthKey)",
        "apns-id": UUID().uuidString,
        "apns-priority": "10",
        "apns-topic": "<Your Bundle ID>"
    ]

    let payload = [
        "aps": [
            "alert": [
                "title": title,
                "body": body
            ],
            "badge": 1,
            "sound": "default"
        ]
    ]

    let session = URLSession.shared

    for deviceToken in deviceTokens {
        let urlString = "https://api.push.apple.com/3/device/\(deviceToken)"
        guard let url = URL(string: urlString) else { return }

        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.allHTTPHeaderFields = headers
        request.httpBody = try? JSONSerialization.data(withJSONObject: payload, options: [])

        let task = session.dataTask(with: request) { (data, response, error) in
            if let error = error {
                print("Failed to send push notification: \(error.localizedDescription)")
            }
        }
        task.resume()
    }
}

// 사용 예시:
let deviceTokens = ["<Device Token 1>", "<Device Token 2>", "<Device Token 3>"]
let title = "새로운 메시지 도착"
let body = "안녕하세요! 새로운 메시지가 도착했습니다."

sendPushNotification(to: deviceTokens, title: title, body: body)

위 코드에서 sendPushNotification 함수는 APNs 서버로 HTTP 요청을 보내는 방식으로 푸시 알림을 전송합니다. 함수의 인자로는 푸시 알림을 받을 디바이스의 토큰 배열, 알림 제목, 알림 본문을 전달합니다.

결론

Swift를 사용하여 채팅 메시지 알림을 푸시 알림으로 제공하는 방법을 알아보았습니다. 프로젝트 설정, APNs 인증서 생성, 푸시 알림 등록, 서버와의 연동, 푸시 알림 보내기 등의 단계를 거쳐 구현할 수 있습니다. 이러한 기능을 통해 사용자가 실시간으로 메시지를 받을 수 있으며, 좀 더 편리한 채팅 경험을 제공할 수 있습니다.

참고 자료