푸시
Game Chat에서 푸시 알림은 사용자들에게 중요한 정보나 업데이트를 실시간으로 알려주는 핵심 기능입니다.
이 푸시 알림 서비스를 통해 사용자는 앱이 백그라운드에 있거나 장치가 활성 상태가 아닐 때도 중요한 메시지를 놓치지 않게 됩니다. 아래는 Game Chat의 푸시 알림 기능에 대한 세부 설명입니다.
푸시 알림의 주요 기능
실시간 알림 : 새 메시지, 멤버 변경, 이벤트 초대 등과 같은 채팅 관련 알림을 사용자에게 즉시 전송합니다.
커스터마이징 가능 : 알림의 형태와 내용을 애플리케이션의 요구 사항에 맞게 사용자 정의할 수 있습니다.
다중 플랫폼 지원 : iOS, Android 등 다양한 모바일 운영체제에 대해 푸시 알림을 지원하여, 사용자 기반을 넓힐 수 있습니다.
배터리 및 데이터 효율성 : 최신 푸시 기술을 사용하여 배터리 소모와 데이터 사용을 최소화하면서도 효율적으로 알림을 전달합니다.
대화형 알림 : 사용자가 알림 자체에서 직접 대응할 수 있도록 대화형 요소를 포함시킬 수 있습니다. 예를 들어, 메시지에 바로 답장하거나, 초대에 응답할 수 있습니다.
푸시 알림의 구현 방법
푸시 알림 서비스를 구현하기 위해 Game Chat API는 몇 가지 핵심 요소를 제공합니다:
푸시 토큰 등록 : 사용자 장치의 푸시 토큰을 Game Chat 서버에 등록하여, 해당 장치에 알림을 보낼 수 있게 합니다.
알림 설정 관리 : 사용자는 자신의 알림 선호도에 따라 알림을 받을지 여부를 설정할 수 있습니다.
백엔드 통합 : 서버 측에서는 Game Chat의 백엔드와 통합하여 실시간으로 푸시 알림을 생성하고 전송할 수 있습니다.
보안 및 개인 정보 보호
데이터 암호화 : 모든 푸시 알림은 전송 중 암호화되어, 외부의 접근으로부터 보호됩니다.
개인 정보 보호 정책 준수 : Game Chat은 사용자의 개인 정보 보호를 매우 중요하게 여기며, 관련 법률 및 규정을 준수하여 알림 서비스를 제공합니다.
푸시 알림 기능을 통해 Game Chat은 사용자의 참여를 유도하고, 앱 사용률을 높이며, 사용자 경험을 향상시키는 데 크게 기여합니다. 사용자는 중요한 커뮤니케이션을 놓치지 않고, 언제 어디서나 연결되어 있을 수 있습니다.
Android(Kotlin)
Firebase Console 에서 Andoird 앱을 추가 후, 다운로드한 "google-services.json' 파일을 프로젝트 앱 모듈의 루트 폴더에 추가합니다.
파일 추가 후 bundle.gradle.kts 내 아래 내용을 추가합니다.
Copy plugins {
.. .
id ( "com.google.gms.google-services" )
.. .
}
dependencies {
.. .
implementation ( "com.google.firebase:firebase-messaging-ktx:23.2.1" )
.. .
}
푸시 허용 권한 팝업을 요청 합니다.
Copy import com.nbase.sdk.Permission
NChat. setEnablePush ( true )
NChat. requestPermission ( this , Permission.NOTIFICATION)
// initialize 전에 호출이 되어야 합니다.
Connect 이후 푸시 수신 여부 설정을 위해 setPushState 를 호출합니다.
Copy NChat. setPushState ( PushState ([PUSH], [AD], [NIGHT])) { state, e ->
if (e != null ) {
// 오류
} else {
// 성공
}
}
ID Type Description 푸시 수신 On/ Off (true = On)
Android(Kotlin) 푸시 클릭 이벤트
안드로이드 푸시 클릭 핸들러를 설정 할 수 있습니다.
Copy NChat. setNotificationClickedHandler { notification ->
val title = notification.title
val content = notification.body
val channel = notification. data ?. get ( "channel" ) ?: ""
val imageUrl = notification. data ?. get ( "imageUrl" ) ?: ""
val url = notification. data ?. get ( "url" ) ?: ""
val metadata = notification. data ?. get ( "metadata" ) ?: ""
// 푸시 클릭 시 원하는 동작을 정의합니다.
}
Android (Java)
프로젝트의 build.gradle 내 아래 repo를 추가합니다.
Copy allprojects {
repositories {
...
google()
// nbase repo
maven { url "https://repo.nbase.io/repository/nbase-releases" }
...
}
}
app 모듈의 build.gradle 내 아래 내용을 추가합니다.
Copy dependencies {
...
implementation ("io.nbase:nbasesdk:3.0.78")
implementation ("io.nbase:nbase-adapter-cloudchat:1.0.17")
implementation ("com.google.firebase:firebase-messaging-ktx:23.2.1")
...
}
Android (Java) 푸시 클릭 이벤트
안드로이드 푸시 클릭 핸들러를 설정 할 수 있습니다.
Copy NChat.INSTANCE.setNotificationClickedHandler(notification -> {
// 푸시 클릭 시 원하는 동작을 정의합니다.
String title = notification.getTitle();
String content = notification.getBody();
String channel = notification.getData() != null ? notification.getData().get("channel") : "";
});
Android 푸시 데이터
안드로이드 푸시 클릭 핸들러를 통해 전달되는 값에 대한 리스트입니다.
Key Description 채팅방 푸시의 경우 푸시가 발생한 CHANNEL_ID
iOS(Swift)
앱푸시 발송 권한을 추가합니다. Target 의 Signing & Capabilites으로 들어와 좌상단의 + Capability > Push Notifications 를 선택하여 추가합니다.
AppDelegate.swift 생성 혹은 이미 생성된 AppDelegate.swift 내 아래 내용을 정의합니다.
Copy import UIKit
import NChat
class AppDelegate : NSObject , UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// 푸시 알림 권한 요청
UNUserNotificationCenter. current () . requestAuthorization ( options : [.alert, . sound , .badge] ) { granted, error in
print ( "Permission granted: \(granted) " )
}
UNUserNotificationCenter. current () .delegate = self
application. registerForRemoteNotifications ()
// 메인 윈도우 설정
window = UIWindow ( frame : UIScreen.main.bounds )
let initialViewController = UIViewController ()
initialViewController. view .backgroundColor = .white
window ? .rootViewController = initialViewController
window ? . makeKeyAndVisible ()
return true
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
// 디바이스 토큰을 문자열로 변환
let tokenParts = deviceToken. map { data in String ( format : "%02.2hhx" , data ) }
let token = tokenParts. joined ()
// sandbox 환경에서 푸시를 수신하려면 sandbox: true
NChat. setPushToken ( token : token, sandbox : false )
}
func application ( _ application : UIApplication, didFailToRegisterForRemoteNotificationsWithError error : Error ) {
print ( "RegisterForRemoteNotifications Failed: \(error.localizedDescription) " )
}
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
if #available ( iOS 14.0 , * ) {
completionHandler ( [.banner, .list, . sound , .badge] )
} else {
completionHandler ( [.alert, . sound , .badge] )
}
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
do {
try handleNotificationClick ( userInfo : userInfo, actionIdentifier : response.actionIdentifier )
} catch let error as NotificationError {
print ( "NotificationError: \(error.localizedDescription) " )
} catch {
print ( "UnexpectedError: \(error.localizedDescription) " )
}
// NChat 라이브러리의 푸시 알림 처리 함수 호출
NChat. handlePushNotification ( userInfo : userInfo )
completionHandler ()
}
}
// 알림 관련 오류 정의
enum NotificationError : LocalizedError {
case invalidUserInfo( String )
case navigationError( String )
var errorDescription: String ? {
switch self {
case . invalidUserInfo ( let message ) :
return "잘못된 사용자 정보: \(message) "
case . navigationError ( let message ) :
return "네비게이션 오류: \(message) "
}
}
}
extension UIViewController {
func topMostViewController () -> UIViewController {
if let presented = self.presentedViewController {
return presented. topMostViewController ()
}
if let navigation = self as? UINavigationController {
return navigation.visibleViewController ? . topMostViewController () ?? navigation
}
if let tab = self as? UITabBarController {
return tab.selectedViewController ? . topMostViewController () ?? tab
}
return self
}
}
참고
sandbox 환경에서의 푸시는
NChat.setPushToken(token: token, sandbox: true)
sandbox 값이 true 설정이 되어야 정상적으로 수신이 가능합니다.
Connect 이후 푸시 수신 여부 설정을 위해 setPushState 를 호출합니다.
Copy NChat. setPushState ( push : true , ad : true , night : true ) { result in
switch ( result )
{
case . success ( let status ) :
// 성공
break ;
case . failure ( let error ) :
// 실패
break ;
}
}
ID Type Description 푸시 수신 On/ Off (true = On)
iOS (Swift) 푸시 클릭 이벤트
iOS 푸시 클릭 핸들러를 설정 할 수 있습니다.
AppDelegate.swift 내 아래 예시와 같이 추가 정의합니다.
Copy class AppDelegate : UIResponder , UIApplicationDelegate , UNUserNotificationCenterDelegate {
var window: UIWindow ?
// 알림 클릭 처리 함수
private func handleNotificationClick ( userInfo : [ AnyHashable : Any ], actionIdentifier : String ) throws {
if actionIdentifier == UNNotificationDefaultActionIdentifier {
showNotificationPopup ( with : userInfo )
} else {
handleCustomAction ( actionIdentifier, userInfo : userInfo )
}
}
// 사용자 정의 액션 처리 함수
private func handleCustomAction ( _ actionIdentifier : String , userInfo : [ AnyHashable : Any ]) {
switch actionIdentifier {
case "ACTION_1" :
showNotificationPopup ( with : userInfo, title : "ACTION_1" )
case "ACTION_2" :
showNotificationPopup ( with : userInfo, title : "ACTION_2" )
default:
print ( "actionIdentifier: \(actionIdentifier) " )
}
}
// 알림 팝업을 표시하는 함수
private func showNotificationPopup ( with userInfo : [ AnyHashable : Any ], title : String = "알림" ) {
DispatchQueue.main. async {
let alertController = UIAlertController ( title : title, message : "알림 수신됨" , preferredStyle : .alert )
// userInfo의 내용을 메시지에 추가
for ( key, value ) in userInfo {
alertController.message ? . append ( "\n \(key) : \(value) " )
}
let okAction = UIAlertAction ( title : "확인" , style : .default, handler : nil )
alertController. addAction ( okAction )
// 키 윈도우를 찾아 팝업을 표시
if let keyWindow = UIApplication.shared.windows. first ( where : { $0.isKeyWindow } ) {
if let topViewController = keyWindow.rootViewController ? . topMostViewController () {
topViewController. present ( alertController, animated : true , completion : nil )
}
} else {
print ( "키 윈도우를 찾을 수 없음" )
}
}
}
}
iOS 푸시 데이터
iOS 푸시 클릭 핸들러를 통해 전달되는 값에 대한 리스트입니다.
Key Description 채팅방 푸시의 경우 푸시가 발생한 CHANNEL_ID