iOS

1. 개요

Morpheus Cloud Push 를 사용하기 위해, Client와 UPMC 서버간 통신을 원활하게 할 수 있도록 제공하는 라이브러리의 API 명세서 이다.

2. Push APIs

Initialize with delegate

[[PushManager defaultManager] initializeWithDelegate:delegate]
  • Push Manager 를 시작하면서 delegate(대리자) 을 등록

  • 등록된 delegate 을 통해 message 수신 등 push 와 관련된 business logic controller 역활을 대행

  • delegate 이 등록되지 않으면 앱이 시작되면서 전달받은 push message 들은 자동으로 지연 전달됨

Parameters
  • delegate (id<PushManagerDelegate>) – delegate 값, NotNull

Register Service and User

[[PushManager defaultManager] registerServiceAndUser:activity, clientUID:@"CUID" clientName:@"CNAME" completionHandler:^(BOOL success) {}];
Parameters
  • activity (UIViewController) – 호출하는 화면 전달, NotNull

  • clientUID (NSString) – Client ID 값, NotNull

  • clientName (NSString) – Client Name 값, NotNull

  • completionHandler (BlockHandler) – User 등록 완료 후 호출, Nullable

Unregister User

[[PushManager defaultManager] unregisterUser:activity completionHandler:^(BOOL success) {}];
  • 사용자를 등록해제

Parameters
  • activity (UIViewController) – 호출하는 화면 전달, NotNull

  • completionHandler (BlockHandler) – Service 해제 완료 후 호출, Nullable

Unregister Service

[[PushManager defaultManager] unregisterService:activity completionHandler:^(BOOL success) {}];
  • 서비스 해제

Parameters
  • activity (UIViewController) – 호출하는 화면 전달, NotNull

  • completionHandler (BlockHandler) – Service 해제 완료 후 호출, Nullable

Register Group

[[PushManager defaultManager] registerGroup:activity groupSequenceNumber:@"GROUP-NUMBER" completionHandler:^(BOOL success) {}];
  • 현재 등록된 User 를 Group 에 등록

  • 서버에 등록된 Group Sequence Number 값을 알고 있어야 등록 가능

Parameters
  • activity (UIViewController) – 호출하는 화면 전달, NotNull

  • groupSequenceNumber (NSString) – Group Sequence Number 값, NotNull

  • completionHandler (BlockHandler) – Group 등록 완료 후 호출, Nullable

Unregister Group

[[PushManager defaultManager] unregisterGroup:activity groupSequenceNumber:@"GROUP-NUMBER" completionHandler:^(BOOL success) {}];
  • 현재 등록된 User 를 Group 에서 해제

  • 서버에 등록된 Group Sequence Number 값을 알고 있어야 해제 가능

Parameters
  • activity (UIViewController) – 호출하는 화면 전달, NotNull

  • groupSequenceNumber (NSString) – Group Sequence Number 값, NotNull

  • completionHandler (BlockHandler) – Group 해제 완료 후 호출, Nullable

Read Message

PushManagerBadgeOption

Constant

Description

PushManagerBadgeOptionKeep

서버에서 관리되는 counting 하나 줄여 count 를 유지시킴

PushManagerBadgeOptionReset

서버에서 관리되는 counting 을 0으로 reset

PushManagerBadgeOptionUpdate

서버에서 관리되는 counting 을 특정 count 로 업데이트

PushManagerBadgeOptionForce

서버에서 관리되는 counting 을 Update API 를 통해 특정 count 로 업데이트

[[PushManager defaultManager] read:activity notification:userInfo completionHandler:^(BOOL success) {}];
  • 읽음 확인 발송

  • didReceiveRemoteNotification: 로 전달된 userInfo 를 그대로 전달

Parameters
  • activity (UIViewController) – 호출하는 화면 전달, NotNull

  • userInfo (NSDictionary) – 수신된 Notification 데이타, NotNull

  • completionHandler (BlockHandler) – 읽음 확인 발송 완료 후 호출, Nullable

[[PushManager defaultManager] read:activity notification:userInfo badgeOption:PushManagerBadgeOption completionHandler:^(BOOL success) {}];
  • 읽음 확인 발송

  • badge 정책을 badge option 으로 전달

Parameters
  • activity (UIViewController) – 호출하는 화면 전달, NotNull

  • userInfo (NSDictionary) – 수신된 Notification 데이타, NotNull

  • badgeOption (PushManagerBadgeOption) – 수신된 Notification 데이타, NotNull

  • completionHandler (BlockHandler) – 읽음 확인 발송 완료 후 호출, Nullable

Example:

[[PushManager defaultManager]
        read:activity notification:userInfo
        badgeOption:PushManagerBadgeOptionKeep
        completionHandler:^(BOOL success) {

}];

or

[[PushManager defaultManager]
        read:activity notification:userInfo
        badgeOption:PushManagerBadgeOptionReset
        completionHandler:^(BOOL success) {

}];
[[PushManager defaultManager] read:activity notification:userInfo badgeOption:badgeOption badge:badge completionHandler:^(BOOL success) {}];
  • 읽음 확인 발송

  • 읽음 확인에 대한 counting 을 특정 badge 값으로 업데이트

  • 최소 1이상, 최대 1000 값

Parameters
  • activity (UIViewController) – 호출하는 화면 전달, NotNull

  • userInfo (NSDictionary) – 수신된 Notification 데이타, NotNull

  • badgeOption (PushManagerBadgeOption) – 수신된 Notification 데이타, NotNull

  • badge (NSNumber) – 업데이트할 counting 값, 1-1000

  • completionHandler (BlockHandler) – 읽음 확인 발송 완료 후 호출, Nullable

Example:

[[PushManager defaultManager]
        read:activity
        notification:userInfo
        badgeOption:PushManagerBadgeOptionUpdate
        badge:@(10)
        completionHandler:^(BOOL success) {

}];
- (void)update:(UIViewController *)activity badge:(NSNumber *)badge completionHandler:(PushManagerNetworkCompletionHandler)handler
  • 읽음 확인에 대한 counting 을 강제로 특정 badge 값으로 업데이트

  • 최소 1이상, 최대 1000 값

Parameters
  • activity (UIViewController) – 호출하는 화면 전달, NotNull

  • badge (NSNumber) – 업데이트할 counting 값, 1-1000

  • completionHandler (BlockHandler) – 읽음 확인 발송 완료 후 호출, Nullable

Example:

[[PushManager defaultManager]
        update:self
        badge:@(3)
        completionHandler:^(BOOL success) {

}];

3. PushManager Delegate

PushStatus

Push Message 가 발송된 상태값

Constant

Description

START

Push Message 로 앱을 시작한 경우

ACTIVE

Application Forground Status 에서 Push Message 를 받은 경우

BACKGROUND

Application Background Status 에서 Push Message 가 전달된 경우

Delegate 설정

Push Message 수신을 대행하는 대리자를 등록

- (void)initilaizeWithDelegate:(id <PushManagerDelegate>)delegate {}
Parameters
  • delegate (PushManagerDelegate) – PushManager 의 역활을 대행할 대리자 등록

Example:

[[PushManager defaultManager] initializeWithDelegate:self];

Push Message 수신 처리

- (void)manager:(PushManager *)manager didReceiveUserNotification:(NSDictionary *)userInfo
status:(NSString *)status messageUID:(NSString *)messageUID {}
Parameters
  • manager (PushManager) – PushManager Instance, NotNull

  • userInfo (NSDictionary) – 수신된 Notification 데이타, NotNull

  • status (PushStatus) – 수신된 Notification 의 상태, NotNull

  • messageUUID (NSString) – 앱에서 부여한 수신된 메세지의 고유 ID, NotNull

Example:

- (void)manager:(PushManager *)manager didReceiveUserNotification:(NSDictionary *)userInfo status:(NSString *)status messageUID:(NSString *)messageUID {

        PushManager *manager = [PushManager defaultManager];

        NSDictionary *apsInfo = [userInfo objectForKey:@"aps"];

        if ( [apsInfo objectForKey:@"badge"] ) {
                NSNumber *badge = [apsInfo objectForKey:@"badge"];

                // 뱃지 숫자 변경
                manager.notificationCenter.badgeNumber = badge;

                // 뱃지 숫자 초기화
                manager.notificationCenter.badgeNumber = [NSNumber numberWithInteger:0];
        }

        // 읽음 확인
        [manager read:self notification:notification.userInfo completionHandler:^(BOOL success) {
                NSString *message = ( ! success ) ? @"Confirming Read-Message is FAIL !!" : @"Confirming Read-Message is SUCCESS !!";
                NSLog( @"%@", message );
        }];

        // 알림 메세지
        NSString *title = [NSString stringWithFormat:@"PUSH (%@)", status];
        NSString *message = [apsInfo objectForKey:@"alert"];

        if ( NSClassFromString(@"UIAlertController") ) {
                UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];

                [alert addAction:[UIAlertAction actionWithTitle:@"취소" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {

                }]];

                [alert addAction:[UIAlertAction actionWithTitle:@"확인" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {

                }]];

                UIViewController *viewController = [[UIApplication sharedApplication] keyWindow].rootViewController;

                if ( viewController.presentedViewController ) {
                        viewController = viewController.presentedViewController;
                }

                [viewController presentViewController:alert animated:YES completion:^{

                }];
        }
        else {
                UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:message delegate:nil cancelButtonTitle:@"취소" otherButtonTitles:@"확인", nil];

                [alert show];
        }
}

4. APNS Push Payload

UPMC 에서 APNS 로 발송되는 Payload JSON 형태

APNS Payload Keys (APN)

APNS 로 보내지는 JSON dictionary object 에 기본적으로 정의되는 aps 대한 키값 정의

Key

Value Type

Description

alert

Object, String

Push Message 내용

badge

Number

앱 아이콘에 Badge 표시, 값이 정의되지 않으면 변경되지 않음

sound

String

Library/Sounds 폴더에 있는 파일명을 정의하면 알림시 Sound 와 함께 알림. 값이 정의되지 않으면 default 로 처리

alert.title

String

alert이 Object일 경우에 제목

alert.body

String

alert이 Object일 경우에 내용

UPMC Payload Keys (MPS)

APNS 로 보내지는 JSON dictionary object 에 UPMC에서 추가정의되는 mps 대한 키값 정의

Key

Value Type

Description

appid

String

발송 타겟의 Application ID

sender

String

발송 주체 ( admin, device-android, device-ios )

seqno

Number

DB 처리되고 있는

ext

String

확장 데이타, 보통 JSON String 형태로 전달. 만약 데이타가 대용량(Rich)인 경우 서버에서 데이타를 HTML형태로 생성하여 해당 URL을 전달

senddate

String

발송된 시간

db_in

String

DB Insert 여부 (“Y” or “N”)

pushkey

String

발송 대상에 대한 고유 키

Example:

  • Simple Data Push

{
        "aps": {
                "alert": {
                        "body": "내용"
                },
                "mutable-content": 1
                "badge": 1,
                "sound": "alert.aif"
        },
        "mps": {
                "appid": "com.uracle.push.test",
                "seqno": "104",
                "sender": "UMSUI",
                "senddate": "2020081214",
                "db_in": "Y",
                "sms": "Y",
                "pushkey": "2a4dc34b21e6f075f9de2d1403bea7ff8144f810"
        }
}
  • Rich Data Push

{
        "aps": {
                "alert": {
                        "title": "제목",
                        "body": "내용"
                },
                "mutable-content": 1
                "badge": 1,
                "sound": "alert.aif"
        },
        "mps": {
                "appid": "com.uracle.push.test",
                "seqno": "104",
                "sender": "UMSUI",
                "senddate": "2020081214",
                "db_in": "Y",
                "sms": "Y",
                "ext": "6|부가정보|https://www.morpheus.kr",
                "pushkey": "2a4dc34b21e6f075f9de2d1403bea7ff8144f810"
        }
}

5. MUTABLE-CONTENT 수신확인 (iOS10 이상)

  • 앱이 Background 또는 종료 상태일 경우에 Push Message가 mutable-content:1 타입으로 올 경우 Notification Service Extention에서 메시지를 우선 처리할수 있다.

  • iOS10 미만 단말기에서는 기존과 동일하게 처리.

Notification Service Extention

  1. File -> New -> Target 선택
    ../../_images/Notification-service_1.png
  2. Notification Service Extention 선택
    ../../_images/Notification-service_2.png
  3. Product Name을 자유롭게 설정
    ../../_images/Notification-service_3.png
  4. Activate를 선택하면 Notification Service Extention Target 항목이 추가
    ../../_images/Notification-service_4.png
  5. 추가된 NotificationService.m 파일에 Push 관련 처리
    ../../_images/Notification-service_5.png

NotificationService.m 파일에서의 수신확인

  1. Push 관련 라이브러리 파일들 Target Membership에 NotificationService 타켓 추가

  2. #import <MPushLibrary/MPushLibrary.h> 추가

  3. didReceiveNotificationRequest 메서드 내에 feedback 메서드 추가

Example:

// NotificationService 쪽에서 메시지 수신시 들어오는 이벤트
- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
    self.contentHandler = contentHandler;
    self.bestAttemptContent = [request.content mutableCopy];

    //PushManager 초기화
    PushManager *manager = [PushManager defaultManager];

    //Keychain Sharing을 통해 feedback시 필요한 정보를 획득
    //키체인 공유 외에도 앱그룹등을 통한 방법으로도 공유가 가능 (app과 extension 사이에 데이터 공유)
    NSString *app_identifier = [NSString stringWithFormat:@"%@.pushDic", @"com.uracle.push.demo.NotificationService"];
    NSDictionary *pushDic = [KeychainController loadValueForKey:app_identifier forAccessGroup:@"com.uracle.push.demo.NotificationService"];

    //관련정보가 없을 경우에는 feedback처리 없이 완료
    if(pushDic == nil)
    {
        self.contentHandler(self.bestAttemptContent);
        return;
    }
    else
    {
        //데이터 공유시의 값의 정보 출처 샘플
        //[pushDic setObject:[PushManager defaultManager].info.clientUID forKey:@"cuid"];
        //[pushDic setObject:[PushManager defaultManager].info.pushServiceID forKey:@"psid"];
        //[pushDic setObject:[PushManager defaultManager].info.host forKey:@"host"];

        NSString *cuid = [pushDic objectForKey:@"cuid"];
        NSString *psid = [pushDic objectForKey:@"psid"];
        NSString *host = [pushDic objectForKey:@"host"];

        if(host)
        {
            //서버 호스트 정보를 셋팅
            [manager.info changeHost:host];
        }
        if(cuid && psid)
        {
            //feedback API 호출
            //push메시지 객체와 cuid, psid값이 필요
            [manager feedback:self notification:self.bestAttemptContent.userInfo clientUID:cuid psID:psid completionHandler:^(BOOL success) {
                //앱에서 중복으로 feedback처리를 하지 않도록 메시지 객체에 feedback 정보에 대한 값을 셋팅후 전달
                NSMutableDictionary *userInfo = [self.bestAttemptContent.userInfo mutableCopy];
                [userInfo setObject:@"true" forKey:@"feedback"];
                self.bestAttemptContent.userInfo = userInfo;

                self.contentHandler(self.bestAttemptContent);
            }];
        }
        else
        {
            self.contentHandler(self.bestAttemptContent);
        }
    }
}

6. 용어

APNS

  • Apple Push Notification Service 의 줄임말.

  • Apple 에서 직접 제공하는 영구적인 보안 채널에 공급자를 연결하여 대상 장치에 알림을 보낼 수 있는 서비스.

UPMC

  • Uracle Push Message Center 의 줄임말.

  • Apple APNS 서버와 TLS 인증으로 연결된 APNS Provider 서버를 Server 대 Server 로 연계하여 구동하는 WAS(Web Application Server) 이다.

  • Receiver 라고도 불림

Service 등록

  • APNS 로 부터 Token 을 할당 받고 UPMC 로 Push 서비스를 사용하겠다고 등록하는 절차

Service 해제

  • UPMC 로 Push 서비스를 사용하지 않겠다고 등록을 삭제하는 절차

User 등록

  • UPMC 로 Push 서비스에 대한 사용자를 등록 또는 변경하는 절차

ServiceAndUser 등록

  • UPMC 로 Push 서비스 등록 및 사용자를 등록을 동시에 진행하는 절차

수신 확인

  • 메세지를 제대로 받았을 때 UPMC 로 Ack를 주는 절차

읽음 확인

  • App에서 메세지를 읽었을때 UPMC 로 Ack를 주는 절차

Application ID

  • Apple에서 App을 구분하는 구분값으로 Bundle Identifier값을 지칭

Client ID

  • 사용자로 등록할 Client 의 고유한 ID (CUID 라고도 함)

  • Email, UserID, Phone Number 또는 Device-UUID 등을 CUID 로 사용

Client Name

  • 사용자로 등록할 Client 의 이름 (CNAME 라고도 함)

  • 사용자의 이름이나 Nickname 또는 Device Name 을 CNAME 으로 사용

GROUPSEQ

– Group Sequence Number 의 준말로 User Group의 고유한 Sequence Number

PSID

– Push Service ID 의 줄임말 - Push 서비스에 대한 고유 ID - APNS에서 할당 받은 Device Token을 사용