공부

Sending push notifications using command-line tools (feat. Token / .p8)

Zedd0202 2023. 2. 28. 20:02
반응형

 

오늘 의식의 흐름

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이면 정상적으로 보내진건데, 

위 처럼 에러케이스들이 몇개 있음 

https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CommunicatingwithAPNs.html

Status Code랑 Reason이 나오니깐 참고하기! 


전체 코드는 gist에 올려두었으니 

변수 부분들만 수정해서 사용하시면 됩니다~!

저는 개인적으로 간단히 푸시 테스트 해보고싶을때 요거 완전 유용하게 잘 쓸 것 같아요..!?

일단 Firebase 관련 세팅을 안해도 된다는게 굿

이걸 이제야 알다니 

틀린 부분있으면 댓글 남겨주세요! 

 

반응형