부가 기능
알림 그룹 만들기¶
알림 센터에서 알림을 그룹으로 표시할 수 있습니다. 동일한 이벤트에 해당하는 알림들은 그룹화하여 축소해 표시할 수 있습니다. 축소한 알림 그룹은 유저가 다시 확장할 수 있으며, 하위 알림(그룹에 속한 각 알림)은 개별적으로 실행할 수 있습니다.
알림 그룹은 콘솔 > 노티피케이션 > 푸시 v4 > 푸시 캠페인 등록 > 캠페인 등록 > 옵션 > 그룹 키에서 그룹 키를 사용으로 변경하고 키 값을 추가하여 만들 수 있습니다. 콘솔에서 그룹을 만든 후, 로컬 푸시 및 리모트 푸시를 발송할 때 groupId
로 알림 그룹을 적용할 수 있습니다. 그룹을 적용하면 아래와 같이 알림들이 그룹별로 축소되어 보이게 됩니다.
| |
![]() | ![]() |
iOS 미디어 노티피케이션¶
Apple의 UserNotifications 프레임워크를 활용하면 Notification에 이미지, 동영상 등의 미디어 파일을 추가할 수 있습니다.
![]() | ![]() | ![]() |
동작 과정¶
미디어 노티피케이션 기능은 iOS의 Notification Service Extension(이하 Extension)을 활용하여 동작합니다. Notification Service Extension 이란 사용자에게 Remote Notification이 전달되기 전, Payload를 수정할 수 있는 App Extension의 하나로Context의 전환 없이 다른 앱의 프로세스 (UI 또는 기능)를 사용할 수 있는 기술입니다. 자세한 내용은 다음을 참고하세요. 자세히
파일 용량 및 타입 제한¶
미디어 파일 첨부 시 용량 제한이 있으며 상세 내용은 UNNotificationAttachment에서 확인할 수 있습니다.
Warning
Youtube나 각종 모바일 게임(예. 서머너즈 워, 별이되어라, 체인스트라이크) 등 AVAudioSession을 사용하는 앱이 실행 중일 때, 푸시로 전달 받은 오디오를 전송할 경우 메인 화면(Springboard)이 재부팅되는 현상을 발견했습니다. 이는 iOS 버전이나 기기 종류에 관계 없이 발생하며, Hive와 별개로 Apple 시스템 내에서 충돌이 발생하는 것으로 확인했습니다.
2018년 12월 20일 Apple 측에 해당 현상을 문의한 상태로 대응이 마련될 때까지 미디어 푸시를 이용한 오디오 전송 기능 사용을 중단하세요.
분류 | 타입 | 제한 용량 |
---|---|---|
이미지 | JPG, JPEG, PNG, GIF | 10MB |
동영상 | MP4, AVI | 50MB |
- 네트워크가 원활하지 않아 타임아웃이 발생했을 경우, 사용자는 미디어가 포함되지 않은 일반 Notification을 전달받게 됩니다.
- 매우 느린 속도의 네트워크에서는 최대 10분간 다운로드를 진행하기도 하므로 해당 지역의 네트워크 상태를 고려하여 적당한 용량을 가진 미디어를 사용해야합니다.
구현 및 활용¶
미디어를 다운로드하고 Notification 객체를 재구성하여, 사용자에게 전달하는 작업을 수행하기 위해서는 몇 가지 설정 및 소스 코드 추가가 필요합니다.
Note
Notification Service Extension은 라이브러리 또는 프레임워크에 포함하여 배포가 불가능함으로 Extension을 사용하기 위해서는 Hive가 제공하는 가이드를 바탕으로 설정을 진행해야 합니다.
Extension 추가¶
미디어 노티피케이션 기능을 사용하려면, 프로젝트에 Notification Service Extension을 추가해야 합니다. 클래스를 직접 추가하거나 오버라이드 하지 않고, 프로젝트에 새로운 타겟을 추가하는 방식을 사용합니다.
프로젝트에 타겟을 추가하면 자동으로 Template이 생성됩니다.
Unity 프로젝트에서 타겟 추가하기
Unity Editor에서는 Hive SDK가 PostProcess 기능으로 타겟 추가 및 Info.plist 작성 등 일련의 과정을 자동으로 수행합니다. 미디어 푸시의 사용 여부만 체크하면 되며, 다른 작업은 필요하지 않습니다.
- Unity Editor 상단의 메뉴바에서 Hive > Build project post process settings > iOS 메뉴로 진입
- Push Media Contents 를 활성화
Unity 외 환경에서 타겟 추가하기
HIVEExtensions.framework 추가¶
Hive에서 제공되는 HIVEExtensions.framework 를 활용하여, 미디어를 손쉽게 다운로드할 수 있습니다.
HIVEExtensions.framework 를 추가하는 방법은 아래와 같습니다.
-
Hive SDK는 CocoaPods를 지원합니다. 프로젝트 경로에 Podfile 이 없다면
pod init
을 수행하세요.Podfile 이 있다면 파일을 열어 target 'NotificationServiceExtension(예시 타겟명)' do-end 구문을 작성하세요.
-
NotificationSample(예시 프로젝트명).xcworkspace 를 열면 아래와 같이 Pods 프로젝트가 추가된 것을 확일할 수 있습니다. 이제 NotificationSample 과 NotificationServiceExtension 타겟에서 HIVEExtensions 를 임포트할 수 있습니다.
Framework 적용¶
NotificationService.swift 파일에 예시와 같이 Framework를 임포트합니다. 템플릿에서 제공하는 메서드에서 HIVEExtensions.framework가 제공하는 메서드를 호출하도록 구현하고 메서드 내부에 있던 최초 템플릿 코드는 삭제하세요.
import HIVEExtensions
func didReceiveNotificationRequest(request: UNNotificationRequest, with contentHandler: (UNNotificationContent) -> Void) {
HIVENotificationService.didReceive(request) { content in
guard let content else { return }
contentHandler(content)
}
}
func serviceExtensionTimeWillExpire() {
HIVENotificationService.serviceExtensionTimeWillExpire()
}
#import <HIVEExtensions/HIVEExtensions.h>
- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
[HIVENotificationService didReceiveNotificationRequest:request withContentHandler:contentHandler];
}
- (void)serviceExtensionTimeWillExpire {
[HIVENotificationService serviceExtensionTimeWillExpire];
}
적용 시 주의 사항¶
발송, 수신 시점의 차이¶
Extension에서 모든 작업이 종료된 이후에, 사용자에게 Notification을 전달하게 됨에 따라 발송 시간과 수신 시간에 차이가 발생할 수 있으며 클라이언트에서는 서버에서 발송한 시간 기준으로 표시됩니다.
예를 들어, 15:00에 Notification을 발송하고, 다운로드가 완료 된 시간이 15:05분일 경우, Notification은 15:00에 도착한 것으로 표시됩니다.
디바이스 용량¶
푸시를 통해 전달받은 미디어는 유저의 기기 내부에 저장된 후에 푸시를 통해 노출되며 전달받은 미디어는 기기 내부 Cache 데이터 공간에 저장되어 유저 기기 내부 용량을 차지하게 됩니다. Cache데이터 공간은 유저 디바이스 내부 저장용량이 부족한 경우 OS에서 자체적으로 데이터를 삭제합니다.
유저의 모바일 데이터 사용¶
푸시를 통해 전달받은 미디어를 다운로드 받는데 유저의 모바일 데이터를 사용하게 되며 유저의 동의 없이 다운로드가 진행되어 다운로드시 데이터 이용 비용이 발생 할 수 있습니다.
푸시를 통해 오디오 / 영상 파일을 전달받는 경우 다운로드 전 유저의 네트워크 연결 상태를 확인하고 유저가 Wifi 연결 상태가 아니라면 다운로드를 진행하지 않고 미디어가 없는 푸시를 노출하도록 합니다.
이때 푸시를 통해 전달받은 미디어의 타입은 미디어 URL 제일 끝에 명시된 확장자로 확인하며 [파일 용량 및 타입 제한] 항목에 명시된 확장자만 정상적으로 노출됩니다.
전달받은 URL | wifi | LTE / 3G |
http://xxx/notimovie.mp4 | 항상 다운로드 후 푸시에 미디어 노출 | 영상파일에 해당하는 확장자 (mp4)를 가졌으므로 미디어 다운로드 없이 푸시 노출 |
http://xxx/notimovie | 항상 다운로드 후 푸시에 미디어 노출 | 음성파일/미디어 파일이 아니므로 다운로드 후 푸시에 미디어 노출 |
http://xxx/notisound.wav | 항상 다운로드 후 푸시에 미디어 노출 | 음성파일에 해당하는 확장자 (wav)를 가졌으므로 미디어 다운로드 없이 푸시 노출 |
http://xxx/notiimage.jpg | 항상 다운로드 후 푸시에 미디어 노출 | 음성파일/미디어 파일이 아니므로 다운로드 후 푸시에 미디어 노출 |
App Transport Security 설정¶
Apple의 기본 정책은 모든 앱에서 수행하는 서버 통신은 https를 허용하도록 되어있으며 Notification을 통해 전달받는 URL도 해당 정책에 영향을 받습니다. Http 도메인을 사용하여 통신하고자 하는 경우 App Transport Security(이하 ATS) 예외 설정이 필요합니다.
이때, Application에서 ATS 예외 처리가 되어있더라도, 푸시를 통해 전송받는 url에 http도메인을 이용하기 위해서는 Extension에서 ATS 예외 설정을 하세요.
Unity에서 미디어가 전달되지 않는 경우¶
Hub connection error Error Domain=NSCocoaErrorDomain Code=4097 "connection to service named com.com2us.hivesdk.normal.freefull.apple.global.ios.universal.NotificationServiceExtension" UserInfo={NSDebugDescription=connection to service named com.com2us.hivesdk.normal.freefull.apple.global.ios.universal.NotificationServiceExtension}
유니티에서 위와 같은 에러 로그가 노출되면서 미디어가 전달되지 않는 경우가 있습니다. 이 경우 생성된 Extension Target의 Architectures에 armv7, arm64 값이 둘 다 포함되어 있는지 확인하세요.
푸시 액션 버튼¶
푸시 액션 버튼이란 아래와 같이 푸시 알림을 길게 누르면 표시되는 시스템 버튼입니다. 푸시 알림에 이러한 추가 버튼을 노출시킴으로써 사용자 반응을 유도할 수 있습니다.
Hive SDK에서는 간단한 설정을 통해 푸시 액션 버튼을 선택적으로 구현할 수 있습니다.
Android | iOS |
---|---|
![]() | ![]() |
Note
Android용 SDK에서는 푸시 액션 버튼을 위한 별도의 설정 작업이 필요하지 않으며 콘솔 가이드 > 노티피케이션 내용을 참고하여 액션 버튼 기능을 사용할 수 있습니다. iOS용 SDK에서는 '기본 구현 방법'과 '심화 구현 방법' 두 가지 방식을 참고하여 푸시 액션 버튼을 구현할 수 있습니다.
Warning
iOS용 SDK에서 푸시 액션 버튼을 위의 iOS 미디어 노티피케이션과 함께 적용할 시 iOS 미디어 노티피케이션 기능이 불완전하게 동작할 수 있습니다. 푸시 발송 시 '미디어 주소'와 '액션 푸시' 중 한 번에 하나의 기능만 사용하세요. 한 번에 두 기능을 동시에 사용할 경우 미디어가 푸시 수신 시의 썸네일로만 노출되고 길게 눌렀을 때 확장된 뷰어는 노출되지 않습니다.
기본 구현 방법 (iOS)¶
Hive SDK에서는 자주 쓰이는 문답을 패턴화한 디폴트 푸시 액션 버튼 세트를 제공합니다. ‘확인’, ‘거절’ 등 자주 사용되는 버튼 조합이 내장되어 있어 빠르게 적용할 수 있으며, 필요에 따라 커스텀 액션 버튼 세트를 정의하고 확장할 수 있는 유연한 구조를 제공합니다. 기본적으로 제공하는 푸시 액션 버튼 세트 내 목록은 아래와 같습니다.
- 확인
- 닫기
- 확인, 닫기
- 실행, 취소
- 일괄 수락, 닫기
- 지금 받기, 닫기
- 구매하기, 거절하기
- 판매하기, 거절하기
- 수락, 거절, 보류
카테고리(카테고리식별자) | 버튼명(액션식별자) |
---|---|
확인하기(INFO_CATEGORY) | 확인(CONFIRM_ID) |
종료하기(CLOSE_CATEGORY) | 닫기(CLOSE_ID) |
선택 확인(CONFIRM_CATEGORY) | 확인(CONFIRM_ID), 닫기(CLOSE_ID) |
실행 여부(EXECUTE_CATEGORY) | 실행(EXECUTE_ID), 취소(CANCEL_ID) |
일괄 처리(ACCEPT_ALL_CATEGORY) | 일괄 수락(ACCEPT_ALL_ID), 닫기(CLOSE_ID) |
즉시 수령(ACCEPT_NOW_CATEGORY) | 지금 받기(ACCEPT_NOW_ID), 닫기(CLOSE_ID) |
구매 결정(PURCHASE_CATEGORY) | 구매하기(PURCHASE_ID), 거절하기(DECLINE_ID) |
판매 요청(SALE_CATEGORY) | 판매하기(SALE_ID), 거절하기(DECLINE_ID) |
의사 결정(ACCEPT_DECISION_CATEGORY) | 수락(ACCEPT_ID), 거절(REJECT_ID), 보류(HOLDING_ID) |
위 푸시 액션 버튼 세트를 적용하기 위해서는 별도의 코드 구현이 필요하지 않으나, 프로젝트에 Notification Content Extension
타겟을 추가해야 합니다. 아래의 개발 환경에 따른 '푸시 액션 버튼 세트 적용 가이드'를 참고하여 타겟을 추가하고 푸시 액션 버튼을 활성화하세요.
Unity에서 푸시 액션 버튼 세트 적용하기
Unity Editor에서는 Hive SDK의 PostProcess 기능으로 타겟 추가 및 Info.plist 작성 등의 일련의 과정을 자동으로 수행합니다. 푸시 액션 버튼의 사용 여부만 체크하면 되며, 다른 작업은 필요하지 않습니다.
- Unity Editor 상단의 메뉴바에서 Hive > Build project post process settings > iOS 메뉴로 진입합니다.
- Push Action Buttons 를 활성화 합니다.
버튼 활성화시 나타는 목록은 아래 심화 구현 방법에서 사용하는 hive_push_actions.json 파일 내categories
필드 목록의 미리보기입니다. 해당 파일 없이 기본 구현으로 진행할 경우 'none'으로 표기됩니다.
Unity 외 환경에서 푸시 액션 버튼 세트 적용하기
Xcode 프로젝트(.xcodeproj)를 산출한 후 아래 순서대로 진행하세요.
각 개발 환경에서 푸시 액션 버튼 세트를 적용하였다면, 콘솔에서 푸시 발송 시 액션을 함께 지정하세요
액션 지정 시, 위 푸시 액션 버튼 세트 목록(자세히)의 카테고리 및 액션의 각 식별자(identifier)를 활용하세요.
콘솔 설정 관련하여 자세한 내용은 콘솔 가이드를 참고하세요.
심화 구현 방법 (iOS)¶
hive_push_actions.json 파일에 actions
와 categories
에 해당하는 값을 정의하세요. 정의 후 hive_push_actions.json 파일을 타겟에 포함하여 앱을 빌드하면, 앱 실행시 Hive SDK에서 자동으로 본문을 분석하여 액션과 카테고리를 알림 센터에 등록합니다.
hive_push_actions.json 파일의 본문 예시는 아래와 같습니다.
hive_push_actions.json 예시
{
"actions": {
"ACCEPT_ALL_ID": {
"ar": "قبول الكل",
"de": "Alle akzeptieren",
"en": "Accept All",
"es": "Aceptar todo",
"fr": "Tout accepter",
"id": "Terima Semua",
"it": "Accetta tutto",
"ja": "一括承諾",
"ko": "일괄 수락",
"pt": "Aceitar tudo",
"ru": "Принять все",
"th": "ยอมรับทั้งหมด",
"tr": "Hepsini Kabul Et",
"vi": "Chấp Nhận Tất Cả",
"zh-Hans": "批量接受",
"zh-Hant": "一鍵接受"
},
"ACCEPT_ID": {
"ar": "قبول",
"de": "Akzeptieren",
"en": "Accept",
"es": "Aceptar",
"fr": "Accepter",
"id": "Terima",
"it": "Accetta",
"ja": "承諾",
"ko": "수락",
"pt": "Aceitar",
"ru": "Принять",
"th": "ยอมรับ",
"tr": "İzin Ver",
"vi": "Chấp Nhận",
"zh-Hans": "接受",
"zh-Hant": "接受"
},
"ACCEPT_NOW_ID": {
"ar": "استلام الآن",
"de": "Jetzt erhalten",
"en": "Claim Now",
"es": "Recibir ahora",
"fr": "Recevoir maintenant",
"id": "Klaim Sekarang",
"it": "Prendi ora",
"ja": "今すぐ受け取る",
"ko": "지금 받기",
"pt": "Obter agora",
"ru": "Получить сейчас",
"th": "รับเลย",
"tr": "Şimdi Al",
"vi": "Nhận Ngay",
"zh-Hans": "立即领取",
"zh-Hant": "立即領取"
},
"CANCEL_ID": {
"ar": "تنفيذ",
"de": "Abbrechen",
"en": "Cancel",
"es": "Cancelar",
"fr": "Annuler",
"id": "Batal",
"it": "Annulla",
"ja": "キャンセル",
"ko": "취소",
"pt": "Cancelar",
"ru": "Отменить",
"th": "ยกเลิก",
"tr": "İptal",
"vi": "Hủy",
"zh-Hans": "取消",
"zh-Hant": "取消"
},
"CLOSE_ID": {
"ar": "إغلاق",
"de": "Schließen",
"en": "Close",
"es": "Cerrar",
"fr": "Fermer",
"id": "Tutup",
"it": "Chiudi",
"ja": "閉じる",
"ko": "닫기",
"pt": "Fechar",
"ru": "Закрыть",
"th": "ปิด",
"tr": "Kapat",
"vi": "Đóng",
"zh-Hans": "关闭",
"zh-Hant": "關閉"
},
"CONFIRM_ID": {
"ar": "موافق",
"de": "OK",
"en": "OK",
"es": "Confirmar",
"fr": "Voir",
"id": "OK",
"it": "Ok",
"ja": "OK",
"ko": "확인",
"pt": "Confirmar",
"ru": "OK",
"th": "ตกลง",
"tr": "TAMAM",
"vi": "OK",
"zh-Hans": "确认",
"zh-Hant": "確認"
},
"DECLINE_ID": {
"ar": "رفض",
"de": "Ablehnen",
"en": "Decline",
"es": "Rechazar",
"fr": "Refuser",
"id": "Tolak",
"it": "Rifiuta",
"ja": "拒否する",
"ko": "거절하기",
"pt": "Recusar",
"ru": "Отклонить",
"th": "ปฏิเสธ",
"tr": "Reddet",
"vi": "Từ Chối",
"zh-Hans": "拒绝",
"zh-Hant": "拒絕"
},
"EXECUTE_ID": {
"ar": "إلغاء",
"de": "Ausführen",
"en": "Run",
"es": "Ejecutar",
"fr": "Exécuter",
"id": "Jalankan",
"it": "Avvia",
"ja": "実行",
"ko": "실행",
"pt": "Executar",
"ru": "Запустить",
"th": "ดำเนินการ",
"tr": "Devam Et",
"vi": "Kích Hoạt",
"zh-Hans": "执行",
"zh-Hant": "執行"
},
"HOLDING_ID": {
"ar": "الاختيار لاحقًا",
"de": "Halten",
"en": "Hold",
"es": "Pendiente",
"fr": "En attente",
"id": "Tahan",
"it": "Rimanda",
"ja": "保留",
"ko": "보류",
"pt": "Manter",
"ru": "Отложить",
"th": "พักไว้",
"tr": "Tut",
"vi": "Tạm Hoãn",
"zh-Hans": "暂缓",
"zh-Hant": "保留"
},
"PURCHASE_ID": {
"ar": "شراء",
"de": "Kaufen",
"en": "Purchase",
"es": "Comprar",
"fr": "Acheter",
"id": "Beli",
"it": "Compra",
"ja": "購入する",
"ko": "구매하기",
"pt": "Comprar",
"ru": "Купить",
"th": "ซื้อ",
"tr": "Satın Al",
"vi": "Mua",
"zh-Hans": "购买",
"zh-Hant": "購買"
},
"REJECT_ID": {
"ar": " رفض",
"de": "Ablehnen",
"en": "Decline",
"es": "Rechazar",
"fr": "Refuser",
"id": "Tolak",
"it": "Rifiuta",
"ja": "拒否",
"ko": "거절",
"pt": "Recusar",
"ru": "Отклонить",
"th": "ปฏิเสธ",
"tr": "Reddet",
"vi": "Từ Chối",
"zh-Hans": "拒绝",
"zh-Hant": "拒絕"
},
"SALE_ID": {
"ar": "بيع",
"de": "Verkaufen",
"en": "Sell",
"es": "Vender",
"fr": "Vendre",
"id": "Jual",
"it": "Vendi",
"ja": "販売する",
"ko": "판매하기",
"pt": "Vender",
"ru": "Продать",
"th": "ขาย",
"tr": "Sat",
"vi": "Bán",
"zh-Hans": "出售",
"zh-Hant": "販售"
}
},
"categories": {
"INFO_CATEGORY": [
"CONFIRM_ID"
],
"CLOSE_CATEGORY": [
"CLOSE_ID"
],
"CONFIRM_CATEGORY": [
"CONFIRM_ID",
"CLOSE_ID"
],
"EXECUTE_CATEGORY": [
"EXECUTE_ID",
"CANCEL_ID"
],
"ACCEPT_ALL_CATEGORY": [
"ACCEPT_ALL_ID",
"CLOSE_ID"
],
"ACCEPT_NOW_CATEGORY": [
"ACCEPT_NOW_ID",
"CLOSE_ID"
],
"PURCHASE_CATEGORY": [
"PURCHASE_ID",
"DECLINE_ID"
],
"SALE_CATEGORY": [
"SALE_ID",
"DECLINE_ID"
]
}
}
본문 작성 시, 유의 사항은 아래와 같습니다.
- 한 카테고리(세트)별 버튼 개수의 상한은 3개입니다.
- 위 예시는 기본 제공 버튼 세트에 대한 정의입니다. 커스텀 액션 버튼에 동일한 identifier를 사용하면 인식되지 않으므로, 중복이 아닌 식별 가능한 문자열을 사용하세요.
- 다국어는 '게임 언어'를 따라가며, Hive SDK에서 지원하는 16개 언어를 입력할 수 있습니다. 영문(
"en"
)은 다국어 문자열에 대해 기본값으로 사용되므로 반드시 추가하세요.
Note
Unity PostProcess를 지원합니다. Unity 프로젝트 내 hive_config.xml 파일이 존재하는 경로에 hive_push_actions.json 파일을 추가하면 Xcode 프로젝트 빌드시 자동으로 앱타겟에 hive_push_actions.json 파일을 추가합니다.
Warning
본문 작성 후, Notification Content Extension의 Info.plist 내 UNNotificationExtensionCategory
에 본문 "categories" 필드의 key들을 추가하세요.
Unity 환경의 경우 자동으로 파일 본문을 분석하여 추가합니다.