Java APNS 인증키 생성

Java 2011.05.31 13:40
인증키 생성 방법에 대해서 종종 질문을 받아서 정리해 봅니다.
설명은 App ID 등록 및 APNS 관련 설정이 되어 있다는 전제하에 출발합니다.

1. "iOS Provisioning Portal > App IDs" 에서 해당  App ID의 Push SSL Certificate를 다운로드 받아서 더블클릭하여 설치합니다.

2. 키체인 유틸리티에서 해당 인증서를 찾습니다.

 


3. 인증서와 키를 함께 선택 한 후에 마우스 우클릭 하여  "2개 항목 보내기..." 를 선택합니다.



4.  생성할 인증키의 파일명을 입력하고 저장합니다.

 

5.  인증키의 암호를 입력합니다.

 

인증키 잘 사용하세요 ^^ 
저작자 표시
신고

'Java' 카테고리의 다른 글

Java7 Certificates does not conform to algorithm constraints  (0) 2014.03.22
Java APNS 인증키 생성  (0) 2011.05.31
Java로 APNS 및 Feedback  (0) 2011.03.24
Java로 애플 푸시 알림 보내기  (1) 2011.03.23
Posted by 지오아빠^^

Java로 APNS 및 Feedback

Java 2011.03.24 17:04
지난번 포스팅에서 Java로 APNS 요청을 하는 방법을 다뤘었다.
이 포스팅은 지난번 포스팅의 연장선상에 있다.

 만약 APNS 요청을 했는데 사용자가 앱을 지우거나 하여 APNS를 보낼 수 없는 상태라면 어떻게 된까?
APNS 서버는 APNS Feedback 서버에 deviceToken을 등록하여 Service Provider들이 이를 확인할 수 있도록 하고 있다.

지난번 포스팅의 코드에 추가했다.

import javapns.back.PushNotificationManager;

import javapns.back.FeedbackServiceManager;

import javapns.back.SSLConnectionHelper;

import javapns.data.Device;

import javapns.data.PayLoad;


import java.util.*;


public class JavapnsTest {

public static int RUN_MODE_DEVELOPMENT = 1;

public static int RUN_MODE_PRODUCTION = 2;

public static String APNS_DEVELOPMENT_GATEWAY = "gateway.sandbox.push.apple.com";

public static String APNS_PRODUCTION_GATEWAY = "gateway.push.apple.com";

public static String APNS_DEVELOPMENT_FEEDBACK = "feedback.sandbox.push.apple.com";

public static String APNS_PRODUCTION_FEEDBACK = "feedback.push.apple.com";

// Change Here.

public static String APNS_DEVELOPMENT_KEY = "./keystore/your_apns_development_key.p12";

public static String APNS_PRODUCTION_KEY = "./keystore/your_production_key.p12";

public static String APNS_DEVELOPMENT_KEY_PASSWORD = "YOUR DEVELOPMENT PASSWORD";

public static String APNS_PRODUCTION_KEY_PASSWORD = "YOUR DEVELOPMENT PASSWORD";

public void sendApns(int runMode, String deviceToken, String alertMessage, int badgeCount, String soundFile) throws Exception {

try {

PayLoad payLoad = new PayLoad();

payLoad.addAlert(alertMessage);

payLoad.addBadge(badgeCount);

payLoad.addSound(soundFile);


PushNotificationManager pushManager = PushNotificationManager.getInstance();

pushManager.addDevice("iPhone", deviceToken);


int port = 2195;

String host = null;

String certificatePath = null;

String certificatePassword = null;

if (runMode == RUN_MODE_DEVELOPMENT) {

host = APNS_DEVELOPMENT_GATEWAY;

certificatePath = APNS_DEVELOPMENT_KEY;

certificatePassword = APNS_DEVELOPMENT_KEY_PASSWORD;

} else if (runMode == RUN_MODE_PRODUCTION) {

host = APNS_PRODUCTION_GATEWAY;

certificatePath = APNS_PRODUCTION_KEY;

certificatePassword = APNS_PRODUCTION_KEY_PASSWORD;

}

pushManager.initializeConnection(host, port, certificatePath, certificatePassword, SSLConnectionHelper.KEYSTORE_TYPE_PKCS12);


Device client = pushManager.getDevice("iPhone");

pushManager.sendNotification(client, payLoad);

pushManager.stopConnection();


pushManager.removeDevice("iPhone");

} catch (Exception ex) {

ex.printStackTrace(); 

}

}

public ArrayList<String> sendFeedback(int runMode) {

ArrayList<String> deviceTokens = new ArrayList<String> ();

try {

int port = 2196;

String host = null;

String certificatePath = null;

String certificatePassword = null;

if (runMode == RUN_MODE_DEVELOPMENT) {

host = APNS_DEVELOPMENT_FEEDBACK;

certificatePath = APNS_DEVELOPMENT_KEY;

certificatePassword = APNS_DEVELOPMENT_KEY_PASSWORD;

} else if (runMode == RUN_MODE_PRODUCTION) {

host = APNS_PRODUCTION_FEEDBACK;

certificatePath = APNS_PRODUCTION_KEY;

certificatePassword = APNS_PRODUCTION_KEY_PASSWORD;

}

FeedbackServiceManager feedbackManager = FeedbackServiceManager.getInstance();

LinkedList<Device> devices = feedbackManager.getDevices(host, port, certificatePath, certificatePassword, SSLConnectionHelper.KEYSTORE_TYPE_PKCS12);

if (devices.size() > 0) {

ListIterator<Device> itr = devices.listIterator();

while (itr.hasNext()) {

Device device = itr.next();

deviceTokens.add(device.getToken());

}

}

} catch (Exception ex) {

ex.printStackTrace();

}

return deviceTokens;

}

public static void main(String... args) throws Exception{

JavapnsTest apns = new JavapnsTest();

apns.sendApns(

RUN_MODE_DEVELOPMENT,

"deviceToken",

"Test~",

9999,

"default");

ArrayList<String> deviceTokens = apns.sendFeedback(RUN_MODE_DEVELOPMENT);

for (String deviceToken : deviceTokens) {

System.out.println(deviceToken);

}

}

}


 
sendFeedback을 테스트 해보기 위해서는 아래의 절차를 따라야 한다.

1. 앱을 설치한다.
2. 앱에서 APNS 사용하도록 등록한다.
3. 앱을 삭제한다.
4. 앱에 APNS 요청 : 이때 실패가 되면서 APNS서버는 APNS Feedback 서버에 요청했던 deviceToken값을 등록한다.
5. APNS Feedback 서버에서 deviceToken을 조회하여 해당 deviceToken에 더이상 APNS요청을 하지 않도록 설정한다. 

Feedback기능을 특정 APNS요청 전후로 메세지 송신여부를 알아올 수 있는 편리한 기능으로 오해하고 있었다.
인생 장밋빛 라이더스~ 흠냐.. 

Feedback 을 주기적으로 해서 받아온 deviceToken 들을 APNS요청 대상에서 제외시켜주자.
이것도 그린 컴퓨팅인가? 

 
저작자 표시
신고

'Java' 카테고리의 다른 글

Java7 Certificates does not conform to algorithm constraints  (0) 2014.03.22
Java APNS 인증키 생성  (0) 2011.05.31
Java로 APNS 및 Feedback  (0) 2011.03.24
Java로 애플 푸시 알림 보내기  (1) 2011.03.23
Posted by 지오아빠^^
지하 깊숙한곳부터 삽질해서 만들지는 않았다.
언제나 그렇듯 개발을 시작하기 전에는 해결하고자 하는 문제에대한 손쉬운 해결책을 검색하게 된다.
눈앞에있는 문제의 본질이 원리를 깨닫고 더 나아가는 것이 아니라면 나는 언제나 오픈소스를 활용한다.
그렇게 세이브한 시간을 좀더 재미있는 일에 투자한다. 각설하고!

http://code.google.com/p/javapns 에 가면 Java로 APNS를 보낼 수 있는  오픈소스가 있다.
예제 코드가 잘되어 있고 사용도 쉬워서 javapns를 이용하기로 결정했다.
아래는 간단히 Wrapping한 코드이다.

import javapns.back.PushNotificationManager;

import javapns.back.SSLConnectionHelper;

import javapns.data.Device;

import javapns.data.PayLoad;


public class JavapnsTest {

public static int RUN_MODE_DEVELOPMENT = 1;

public static int RUN_MODE_PRODUCTION = 2;

public void sendApns(int runMode, String deviceToken, String alertMessage, int badgeCount, String soundFile) throws Exception {

try {

PayLoad payLoad = new PayLoad();

payLoad.addAlert(alertMessage);

payLoad.addBadge(badgeCount);

payLoad.addSound(soundFile);


PushNotificationManager pushManager = PushNotificationManager.getInstance();

pushManager.addDevice("iPhone", deviceToken);


String host = null;

String certificatePath = null;

if (runMode == RUN_MODE_DEVELOPMENT) {

host = "gateway.sandbox.push.apple.com";

certificatePath = "./keystore/your_apns_development_key.p12";

} else if (runMode == RUN_MODE_PRODUCTION) {

host = "gateway.push.apple.com";

certificatePath = "./keystore/your_apns_production_key.p12";

}

int port = 2195;

String certificatePassword = "Your password";

pushManager.initializeConnection(host, port, certificatePath, certificatePassword, SSLConnectionHelper.KEYSTORE_TYPE_PKCS12);


Device client = pushManager.getDevice("iPhone");

pushManager.sendNotification(client, payLoad);

pushManager.stopConnection();


pushManager.removeDevice("iPhone");

} catch (Exception ex) {

ex.printStackTrace(); 

}

}

public static void main(String... args) throws Exception{

JavapnsTest apns = new JavapnsTest();

apns.sendApns(

RUN_MODE_DEVELOPMENT,

"5c0de8bdc3414816a0eb728751f76be119e9a705e43cdbf0ed16c1772a63218a",

"Test삼~",

9999,

"default");

}

}




정말 간단하다 -ㅅ-; 굳이 설명할 가치도 못느끼겠다.
간단하게 파라미터만 설명 해보자.

1. runMode : APNS는 Development용과 Production용을 구별하고 있다. 그것에 따라서 사용해야하는 키와 게이트웨이가 다르다.

2. deviceToken : 특정 디바이스에 특정 앱에 부여되는 APNS를 위한 고유값 정도로 알아두자. 이값은 유니크하지만 불변의 값은 아니다. 64자리의 문자열 값이다. 앱에서 아래와 같은 방법으로 얻을 수 있다.

[[UIApplication sharedApplication] registerForRemoteNotificationTypes:

(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];

....

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken {

#if !TARGET_IPHONE_SIMULATOR

// ' ', '<', '>' 제거

    NSString *deviceToken = [[[[devToken descriptionstringByReplacingOccurrencesOfString:@"<" withString:@""stringByReplacingOccurrencesOfString:@">" withString:@""stringByReplacingOccurrencesOfString:@" " withString:@""];

NSLog(@"deviceToken : %@", deviceToken);

#endif


3. alertMessage : 노티를 받았을 때 뜨는 알럿창의 메세지다.

4. badgeCount : 스프링보드 아이콘에 붙는 빨콩안의 숫자값이다.

5. soundFile : 노티를 받았을 때 재생되는 사운드 파일명이다. 자세한 내용은 깔끔하게 까먹었다.


APNS에 Custom key-value를 추가 할 수 있지만, 이런 부분까지는 각자의 몫으로 하자!

APNS 자체에대해서 궁금하다면 Apple의 문서를 참고하자. 
p12파일을 만드는 방법이 궁금하다면 여기를 참고하자.




저작자 표시
신고

'Java' 카테고리의 다른 글

Java7 Certificates does not conform to algorithm constraints  (0) 2014.03.22
Java APNS 인증키 생성  (0) 2011.05.31
Java로 APNS 및 Feedback  (0) 2011.03.24
Java로 애플 푸시 알림 보내기  (1) 2011.03.23
Posted by 지오아빠^^
TAG APNS, ios, java
APNS를 추가하기 위해서 registerForRemoteNotificationTypes 를 호출하게 되면 APNS 사용 동의 여부를 묻는 Alert이 뜬다.
개발을 하다보면 앱을 삭제하고 다시 인스톨하기를 무수히 반복하게 되는데 이런 경우 APNS동의 Alert은 최초 registerForRemoteNotificationTypes 호출시에만 Alert을 보여주고 이후에는 앱을 삭제후 재설치했더라도 Alert을 띄우지 않는다.

이런 현상때문에 테스터들로 부터 빈번히 이런 질문을 받게된다. 
"왜 동의 메세지 창이 뜨지않죠?"

대부분은 자신도 명확한 이유를 알지 못하기 때문에 이렇게 답한다.
"동의했던 앱을 캐싱해서 그래요~"

뭐.. 맞는 이야기다. 하지만 좀더 정확히 알고 가고 싶다면 아래 문서를 참고하자.

Resetting the Push Notifications Permissions Alert 부분을 읽어보면 명확한 답이 나와있다.
언제나 그렇듯 Apple의 문서만한 자료는 없는 것 같다.
저작자 표시
신고
Posted by 지오아빠^^
TAG APNS, ios






티스토리 툴바