preview image
허원철의 개발 블로그

Java에서 iOS Push 삽질기

2019-05-13

직접 APNs를 사용하면서 경험한 삽질기이다.

시작하기 전에…

Push(Android, iOS 등)를 고려한다면 고민말고 FCM(Firebase Cloud Messaging)을 사용하자. Android 뿐만 아니라 다른 플랫폼도 지원한다.

배경

OtherLevels이라는 메시징 플랫폼을 사용 중에 있으며, 여러가지 이유(?)로 이를 사용하지 않고 직접 메시징 시스템을 구축하려고 한다. 인수인계 받은바로는 Android, iOS 각각 플랫폼별로 별도로 처리해야 하는 상황이다.

앞에서 언급했던 것 처럼 APNs만 다룰 예정이다.

APNs 이란?

APNs(Apple Push Notification Service)는 Apple Device에 Push를 보내줄 수 있는 서비스이다. 지원하는 방식으로는 다음과 같다.

Legacy Push

  • TLS(SSL) 소켓 통신
  • Production(gateway.push.apple.com:2195) / Development(gateway.sandbox.push.apple.com:2195)

Push

  • HTTP/2 통신
  • Production(api.push.apple.com:443) / Development(api.sandbox.push.apple.com:443)

HTTP/1.1 통신을 지원하지 않는다.

Legacy Push 이용하기

fernandospr/javapns-jdk16 테스트 진행. 하지만 마지막 커밋이 2017-05-17으로 현재 기준(2019-05-14)으로 만 2년이 넘은 상태이다. 이와 같이 Legacy Push에 대한 오픈소스 관리는 거의 안되는 상태이다. 또한, Thread Pool 관리가 안되기 때문에 코드의 복잡성이 늘어나거나 리소스 관리가 안될 수 있으니 조심해서 사용하자.

1
2
3
4
5
6
7
/* fernandospr/javapns-jdk16 샘플 */
PushNotificationBigPayload payload = PushNotificationBigPayload.complex();
payload.addAlert("Message received from Bob");

/* ... */

Push.payload(payload, p12File, password, isProduction, deviceTokens);

Push 이용하기

CleverTap/apns-http2relayrides/pushy, RestTemplate 테스트 진행. 하지만 지금 서버가 Java 8이기 때문에 HTTP/2을 지원하지 않아 별도의 작업이 필요하다. (사실 relayrides/pushy는 없어도 된다.)


※ 참고) ALPN 지원

1
2
3
4
5
6
7
8
9
10
11
12
13
/* CleverTap/apns-http2 샘플 */
FileInputStream cert = new FileInputStream("/path/to/certificate.p12");
final ApnsClient client = new ApnsClientBuilder()
.withProductionGateway()
.inSynchronousMode()
.withCertificate(cert)
.withPassword("<password>")
.build();

Notification n = new Notification.Builder("<the device token>")
.alertBody("Hello").build();

NotificationResponse result = client.push(n);

그리고… 방법 중에 하나로 alpn-boot-{version}.jar 다운받고, 실행시에 다음 옵션을 추가해야한다.