Sending push notifications using command-line tools (feat. Token / .p8)
오늘 의식의 흐름
1. Remote Notification을 테스트 해보고싶음
2. 개인적으로 Remote Notification은 Firebase를 통해서만 써봤음.. (FCM)
3. Firebase 프로젝트 세팅하고 뭐 프로젝트에 SDK 추가할 생각하니까 갑자기 아득해짐..ㄹㅇ;;
4. 진심 이게 최선임..? 에반데 하다가 Sending push notifications using command-line tools 이런게 있길래 도전
참고로 위 링크에 2가지 방법(Certiticate, Token)이 있는데 나는 Token을 이용해서 해볼거
Certificate와 Token 방식에 대한 차이점은
[Remote Notification 한판 정리] APNs / Token Based / Certificate Based / .p8과 .p12
글을 참고
당연히 애플 개발자 프로그램 가입이 되어있어야합니다?
1. 프로젝트 만들기
나는 대충 ZeddPushTest로 만들어줬따..
2. Capabilities > Push Notification 추가
3. AppDelegate.swift 수정
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let token = deviceToken.reduce("") {
$0 + String(format: "%02X", $1)
}
print(token)
}
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
print(error.localizedDescription)
}
DeviceToken 얻어오는 부분 추가해주기
4. 알림 권한 요청
UNUserNotificationCenter.current().requestAuthorization(options: [.alert,.sound,.badge], completionHandler: {
didAllow,Error in
DispatchQueue.main.async {
UIApplication.shared.registerForRemoteNotifications()
}
})
5. DeviceToken 복사해두기
6. Certificates, Identifiers & Profiles 사이트로 이동
7. 왼쪽에 Keys 선택 후 + 버튼 누르기
8. KeyName 입력, APNs 체크 후 Continue
9. Register 클릭
10. 한번 다운받으면 다시 다운로드 할 수 없으니 주의. 다운 고고
여기서 Key ID가 중요한데, 다시 들어가서 볼 수 있으니 걱정 ㄴㄴ
아무튼 .p8 파일이 다운받아졌을거임
11. TeamID 가져오기
https://developer.apple.com/account 여기 들어가서
팀 ID 부분 써야하니 이 창 켜두고 있기
이제 조합할 일만 남았는데...
Send a Push Notification Using a Token 이쪽 보면
사실 이거 보고 살짝 아득해짐
해봅시다.
12. 터미널 열고 쉘 스크립트 파일 만들어주기
이번 스텝은 전부 다 개인취향임
1. 나는 Desktop에서 보는게 편해서 Desktop에 만들려고 이동했고
2. 나는 나노충이라 nano로 만듬
3. 파일명 암거나 ㄱㄱ .sh 만 잘 붙혀주면됨
13. 첫 줄에 #!/bin/bash 추가
#!/bin/bash
14. Send a Push Notification Using a Token 로 가서 스크립트 복사해주기
빨간색 네모 친거 쉘 스크립트 파일에 복붙
⚠️ 주의사항 ⚠️ 마지막 curl 앞에있는 %는 빼주기!!!!
#!/bin/bash
TEAM_ID=Team ID
TOKEN_KEY_FILE_NAME=path to the private key file
AUTH_KEY_ID=your key identifier
TOPIC=App ID
DEVICE_TOKEN=device token for your app
APNS_HOST_NAME=api.sandbox.push.apple.com
JWT_ISSUE_TIME=$(date +%s)
JWT_HEADER=$(printf '{ "alg": "ES256", "kid": "%s" }' "${AUTH_KEY_ID}" |
openssl base64 -e -A | tr -- '+/' '-_' | tr -d =)
JWT_CLAIMS=$(printf '{ "iss": "%s", "iat": %d }' "${TEAM_ID}"
"${JWT_ISSUE_TIME}" | openssl base64 -e -A | tr -- '+/' '-_' | tr -d =)
JWT_HEADER_CLAIMS="${JWT_HEADER}.${JWT_CLAIMS}"
JWT_SIGNED_HEADER_CLAIMS=$(printf "${JWT_HEADER_CLAIMS}" | openssl dgst
-binary -sha256 -sign "${TOKEN_KEY_FILE_NAME}" | openssl base64 -e -A | tr
-- '+/' '-_' | tr -d =)
AUTHENTICATION_TOKEN="${JWT_HEADER}.${JWT_CLAIMS}.${JWT_SIGNED_HEADER_CLAIMS}"
curl -v --header "apns-topic: $TOPIC" --header "apns-push-type: alert"
--header "authorization: bearer $AUTHENTICATION_TOKEN" --data
'{"aps":{"alert":"test"}}' --http2
https://${APNS_HOST_NAME}/3/device/${DEVICE_TOKEN}
파일 상태가 지금 이럴텐데,
TEAM_ID=Team ID
TOKEN_KEY_FILE_NAME=path to the private key file
AUTH_KEY_ID=your key identifier
TOPIC=App ID
DEVICE_TOKEN=device token for your app
APNS_HOST_NAME=api.sandbox.push.apple.com
우리는 👆 이 부분만 수정하면 됩니다.
✔️ Team_ID → 11번으로 이동. 팀 ID 부분 복붙
✔️ TOKEN_KEY_FILE_NAME → 10번으로 이동. 아까 다운로드 받은 .p8의 Path를 입력해주면됨. (ex. /Users/zedd/Downloads/AuthKey_어쩌구.p8)
✔️ AUTH_KEY_ID → 10번으로 이동. 아까 만든 Key에 들어가서 Key ID 복붙
✔️ TOPIC → 처음에 만든 프로젝트의 Bundle ID 복붙 (ex. com.zedd.ZeddPushTest)
✔️ DEVICE_TOKEN → 5번으로 이동. 아까 만들어둔 토큰 복붙
✔️ APNS_HOST_NAME → 수정안해도 됨
15. 스크립트 실행
./send_notification.sh
만약 zsh: permission denied: ./send_notification.sh 이런식으로 권한 거부 메시지가 나오면..
실행권한이 없는거여서 실행권한을 부여해줘야함.
chmod 755 send_notification.sh
권한 부여하고 다시 스크립트 실행 ㄱㄱ
전부 제대로 입력했다면
뭐 이런거 쫘라락 나오고
야호 ㅠㅠㅠ!!!!! 한번에 되가지고 행복..
# 개선해보기
지금 curl 쪽 명령어 보면 data 부분이
'{"aps":{"alert":"test"}}'
이렇게 되어있어서 가독성이 떨어지는데, 이것도 변수로 빼보자.
APNS_HOST_NAME 밑에
read -r -d '' PAYLOAD <<'EOF'
{
"aps": {
"badge": 1,
"alert": {
"title": "불꽃남자",
"subtitle": "정대만",
"body": "❤️"
}
}
}
EOF
대충 이런식으로 정의해두고, curl 부분을 아래와같이 수정해주기!
curl -v --header "apns-topic: $TOPIC" --header "apns-push-type: alert" --header "authorization: bearer $AUTHENTICATION_TOKEN" --data "${PAYLOAD}" --http2 https://${APNS_HOST_NAME}/3/device/${DEVICE_TOKEN}
그냥 "${PAYLOAD}"로 바꾼거밖에 없음
다시 스크립트 실행하면
야호
# APNs 에러
보내고나면 이게 성공적으로 보내졌는지, 에러가 났는지 나온다.
200이면 정상적으로 보내진건데,
위 처럼 에러케이스들이 몇개 있음
Status Code랑 Reason이 나오니깐 참고하기!
전체 코드는 gist에 올려두었으니
변수 부분들만 수정해서 사용하시면 됩니다~!
저는 개인적으로 간단히 푸시 테스트 해보고싶을때 요거 완전 유용하게 잘 쓸 것 같아요..!?
일단 Firebase 관련 세팅을 안해도 된다는게 굿
이걸 이제야 알다니
틀린 부분있으면 댓글 남겨주세요!