블로그 이미지
안녕하세요~ iolate(isho) 의 블로그 입니다~! iolate

카테고리

분류 전체보기 (156)
끄적끄적 (9)
Server, AWS (6)
Linux, Ubuntu (22)
개발질 (44)
Mac (18)
iOS (23)
IoT (6)
Web (5)
ROS (1)
Network (3)
Review (10)
마인크래프트 (1)
WF IT봉사 (0)
기타 (8)
비공개글 (0)
Total559,730
Today38
Yesterday230

Apple 개발자 페이지에서 App ID 등록 및 Push 인증서 발급까지 끝낸 이 후.


0. 개발용 인증서 등록

잘 까먹는 과정 중 하나라서..

Push 서비스를 이용하려면 개발용 인증서 새로 발급해야 한다. 와일드카드 ㄴㄴ

발급 후 다운받을 수 있는 .mobileprovision 파일을 실행 후

프로젝트 Build Settings -> Code Signing Identity 에서 해당 인증서 선택


==========


1. .cer 파일을 실행해서 키체인에 등록

2. 키체인 - 인증서 카테고리 에서 인증서 찾아서 (앱아이디로 검색)


3. 왼쪽 접힌걸 열어서 인증서와 개인키를 같이 선택, 우클릭 -> 2개 항목 보내기

ㄴ 정확한건 아니지만, sandbox 용은 개인키와 함께, production 용은 인증서만 선택해서 추출해야 작동을 하는 것 같다.

원래 잘 되던게 언제부턴가 이러던데, 정확한 원인이나 이유는 잘 모르겠음.


4. .p12 포맷으로 적당한 곳에 저장. 비밀번호는 설정안해도 된다.

5. $ openssl pkcs12 -in cert.p12 -out cert.pem -nodes

6. 위에서 비밀번호를 지정했다면 해당 비밀번호를, 아니라면 그냥 엔터

7. 완성

저작자 표시 비영리 변경 금지
신고
Posted by iolate
TAG APNS, ios, p12, pem, Push

iOS 만 서비스 할때는 그냥 대충 php + cron 으로 push 를 돌렸었는데,

이게 백명 단위만 되어도 delay 문제가 생겨서... async 방식으로 언젠가 도입을 해야지.. 생각만 했었다.


이번에 안드로이드때문에 하게 되었으니.. 겸사겸사...

GCM 으로 iOS 도 사용할 수 있는 방법이 있다는건 봤지만,, 클라를 수정해야 했고..

이미 있는 앱도 같이 적용 + 클라 더 손대기가 귀찮아서 서버쪽을 잘 만들어보기로 했다.



APNS

우선 APNS 는 pyapns 라는 녀석으로 쉽게 asynchronous 한 push 를 구현가능하다.


pyapns 설치하기


pyapns 서버를 구축한 후 python 에서


import pyapns

pem_path = 'path_to_push_pem'

pyapns.configure({'HOST': 'http://localhost:7077/'})

pyapns.provision('com.example.appid', pem_path, 'production') #sandbox

push = {'aps': {'alert':'푸시 테스트', 'sound':'default'}}

pyapns.notify('com.example.appid', '### push token ###', push, async=True)


이렇게 사용하면 된다.



GCM

GCM 은 주로 node.js 로 했던 듯 하나... 난 시스템을 통일시키고 싶었다.

찾아보니, 위 pyapns 처럼 로컬에 서버를 열어두고 request를 보내면 되는 방식의 GoCM 이라는 라이브러리가 있었다.

Golang 으로 짜져 있음.


GoCM 설치하기


GCM 은 인증서가 필요없고 sandbox / production 구분이 없어서 더 간편하다.

간단히 POST request 만 구현하면 어떻게든 가능하지만, 난 requests 라이브러리 사용을 선호함.


import requests, json

GCM_SEND_ENDPOINT = 'http://localhost:5601/gcm/send'

token = '### token ###'

msg = {'title': '[title]', 'message': 'message'}

requests.post(GCM_SEND_ENDPOINT, data={'tokens': [token], 'payload': json.dumps(msg)})



Daemonize

위 방법대로 하면 이제 APNS / GCM 을 둘다 이용할 수 있게 되지만, 각각 웹서버를 하나 돌려야 해서 귀찮다.

당장은 그냥 쓴다고 해도 재부팅을 한다거나.. 프로세스 유지해주기가 귀찮으니까 데몬으로 만들어버리자.


pyapns 는 python-twistd :: daemon 으로 만들기

GoCM 은 GoCM :: daemon 으로 만들기


글을 각각 참고하면 된다.



Feedback / Report

APNS / GCM 각각 삭제되었거나 더이상 사용되지 않는 token 에 대한 feedback 을 제공해준다.


APNS

pyapns.feedback('com.example.appid') 를 호출하면 

[(timestamp, token), ] 

형태로 반환해준다.


token 으로 uninstalled 처리를 해주면 됨.


GCM

canonicals / notregistered 두가지 feedback 이 존재한다.

전자는 token 이 변경되었을 경우(인 것 같다. 사실 레퍼런스를 안봐서..), 후자는 앱이 삭제된 경우.


이건 그냥 GoCM README 를 보자.



Fin

드디어 Python 만을 사용하여(Go 는 컴파일 한번 하고 끝이니 논외), 하나의 시스템만으로 Asynchronous APNS / GCM 둘다 사용할 수 있게 되었다.


여기선 다루지 않았지만, 동일한 DB에 os 구분하여 token 을 저장하고, os 를 알아서 구분해서 메세지를 보내도록 하면 좀 더 관리가 쉽다.


분명히 두 OS를 같이 서비스하는 사람/업체가 많은데 내가 못찾는건지 다른 방법이 있는건지...

생각처럼 깔끔하고 쉬운 방법이 눈에 안보이네.. 흑

저작자 표시 비영리 변경 금지
신고
Posted by iolate
TAG APNS, GCM, GoCM, Push, pyapns

뭐.. 다들 한번씩 겪는 것 같은데, 리모트 푸시의 Token 을 제대로 못 받아오는 문제..


Target Provisioning Profile 에서 push 용으로 받은거 잘 골라주고,

iOS8 에서 변경된 푸시 등록 방법을 사용하면 잘되야 정상이다. (각각 방법은 알아서 찾아보기.)


Push 세팅을 리셋해주고 다시 하니까 잘 되던데,

Apple 에선

1. 앱을 지우고

2. 재부팅을 하고

3. 날짜를 하루 당겼다가 돌아오고

4. 재부팅


이라고 안내하는데, 난 이게 귀찮아서,,, 탈옥폰의 장점은 이게 아니겠는가!


/var/mobile/Library/BackBoard/applicationState.plist

에서 해당 앱과 관련된 키를 지워버리고 BackBoard 를 재시작 한다.


$ killall backboardd


그리고 다시 앱을 시작하면 푸시 권한을 다시 물어보고, 허용해주면 잘 됨!

저작자 표시 비영리 변경 금지
신고
Posted by iolate

최근에 달린 댓글

최근에 받은 트랙백

글 보관함