FLYNNLABAboutMeCodingActivityStudy 2024초등수학
nodejs ios push service
nodejs, ios, apns

참고 : http://blog.saltfactory.net/215

nodejs 로 ios 푸쉬 서버를 구축하면서 실수 했던 부분들을 정리했습니다.

오랬만에 다시 iOS를 개발하게 되었는데 Swift로 바뀐 환경과 iOS8 Beta가 나오고 있어서 제일 최신 방법으로 적용하려고 하니 엄청 삽질했습니다 ㅠㅜ

몇가지 이슈만 정리

iOS에서 인증서는 두 가지 종류가 있습니다. 빌드용 인증서와 Push서버에서 사용하는 인증서입니다. 빌드용 인증서는 Type이 iOS Development / iOS Distribution 입니다. Push 서버용 인증서는 Type이 APNs Development iOS / APNs Production iOS 입니다.

프로비저닝 프로파일(provisioning profile)은 앱을 배포할때 사용합니다. 보통 개발할때에는 프로비저닝 프로파일을 생성하지 않고 Xcode에서 생성해주는 거 사용하면 됩니다. AdHoc이나 앱스토어에 배포할때만 프로비저닝 프로파일을 생성하시면 됩니다.

프로비저닝이 꼬였다 싶으면 Xcode 설정창에서 Accounts > View Details > Refresh Icon 클릭을 하면 해당 계정의 최신 프로비저닝 프로파일을 받아줍니다.

nodejs 서버에서 사용할 파일들 준비

APNs 인증서를 다운 받은 후 키체인에 추가합니다. 추가된 키체인에 내보내기로 p12 파일을 생성합니다.(이때 입력한 암호는 아래 변환할때 사용합니다.) 위 두 파일을 아래 명령어로 key와 cert 파일을 생성합니다.

openssl pkcs12 -in certificates_production.p12 -out dist_key.pem -nodes -clcerts
openssl x509 -in aps_production.cer -inform DER -outform PEM -out dist_cert.pem

nodejs 에서 APNs를 이용할 모듈은 star 가 가장 많은 node-apn을 사용합니다.(https://github.com/argon/node-apn)

var apn = require('apn');
var apnConnection = new apn.Connection({
      gateway: "gateway.push.apple.com",
      cert: './keys/dist_cert.pem',
      key: './keys/dist_key.pem'
    });
  var myDevice = new apn.Device("device token");
  var note = new apn.Notification();
  note.badge = 3;
  note.alert = "테스트";
  note.payload = {'message': "테스트"};
  apnConnection.pushNotification(note, myDevice);

iOS 코드

// objective-c version
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    // 푸시서비스 등록
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:
            UIRemoteNotificationTypeAlert |
                    UIRemoteNotificationTypeBadge |
                    UIRemoteNotificationTypeSound];
    return YES;
 
}
 
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    NSString *tokenString = [[[[deviceToken description]
            stringByReplacingOccurrencesOfString:@"<" withString:@""]
            stringByReplacingOccurrencesOfString:@">" withString:@""]
            stringByReplacingOccurrencesOfString:@" " withString:@""];
 
    NSLog(@"DeviceToken : %@", tokenString);
    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    NSDictionary *parameters = @{@"deviceToken" : tokenString};
    [manager POST:@"http://172.29.17.27:3006/api/pushes/test" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSLog(@"JSON: %@", responseObject);
    }     failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"Error: %@", error);
    }];
}

device token 값을 꼭 확인해야 한다. 배포 인증서마다 device token 값이 바뀌기 때문이다.