
因為最近同事的案子有用到「通知使用者」,這種功能天天都在做。整理一下以前的作法,大概有遠端推播、本地推播、行事曆事件這三種。這三種各有他使用上限制跟優缺點,因為這種需求很頻繁,為了日後不要再說明一次,所以寫了這篇:
遠端推播(push、remote notification)
用push來叫他感覺怪怪的,因為所有跳出一個通知的東西應該都可以叫做push,一般書裡寫的推播指的就是這種,怎麼做不再綴訴:
一般使用流程如下:
1.打開app,在appDelegate裡的didFinishLaunchWithOption或becomeActive裡寫我要用推播
2.會在didRegisterRemoteNotification收到由APNS傳來的deviceToken,把token去頭去尾後,去跟自家的PNS(Push Notification Server)註冊,至少會把deviceToken這個參數傳出去。可以看得出來我在這邊多傳了一個phoneID
3.PNS排好schedule,時間到訊息送出
4.裝置收到推播,點選推播後會自動進入appDelegate的didReceiveNotification裡,進入之後要怎麼處理就是各自app的事了
1.我明明排定某個時間要送出推播,為什麼我收到推播的時間是2個小時甚至更久以後?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//跟APNS說我要用推播 | |
[[UIApplication sharedApplication] registerForRemoteNotificationTypes: | |
(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)]; |
2.會在didRegisterRemoteNotification收到由APNS傳來的deviceToken,把token去頭去尾後,去跟自家的PNS(Push Notification Server)註冊,至少會把deviceToken這個參數傳出去。可以看得出來我在這邊多傳了一個phoneID
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{ | |
NSString *token = [NSString stringWithFormat:@"%@", [deviceToken description]]; | |
token = [token stringByReplacingOccurrencesOfString:@"<" withString:@""];//去左箭號 | |
token = [token stringByReplacingOccurrencesOfString:@">" withString:@""];//去右鍵號 | |
token = [token stringByReplacingOccurrencesOfString:@" " withString:@""];//去空白 | |
//把拿到的deviceToken去頭去尾後 拿去註冊push | |
[self registerPushServer:self.phone_id :token ]; | |
//把BadgeNumber設為0 | |
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:0]; | |
} | |
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { | |
[Flurry logError:@"推播註冊失敗" message:@"APNS無回應" error:error]; | |
} |
3.PNS排好schedule,時間到訊息送出
4.裝置收到推播,點選推播後會自動進入appDelegate的didReceiveNotification裡,進入之後要怎麼處理就是各自app的事了
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { | |
if([[userInfo objectForKey:@"aps"] objectForKey:@"alert"]!=NULL){ | |
NSString *alertbody = [[userInfo objectForKey:@"aps"] objectForKey:@"alert"]; | |
application.applicationIconBadgeNumber = application.applicationIconBadgeNumber+1; | |
} | |
} |
圖片來源:raywenderlich.
需要注意的點如下:
- development會有一組deviceToken、distribution會有一組deviceToken。所以AdHoc跟AppStore的provision拿到的deviceToken會是一樣的
- deviceToken會過期,時間由APNS來決定,過期後APNS會再給device一個deviceToken,所以在第二步註冊的時候應該還要傳UDID或mac address這種唯一且固定的identify
- 如果把development的deviceToken不小心傳到distribution的清單裡面,那distribution群發推播跑到那組development的deviceToken時會halt。
1.我明明排定某個時間要送出推播,為什麼我收到推播的時間是2個小時甚至更久以後?
- 因為送出推播的時候一定是由自己的PNS送出給APNS叫他送出推播,如果今天是一個群發推播,然後註冊的用戶有500萬個,但是自己的PNS一個小時只能處理10萬個request,全部處理完要兩天!那就一定會delay。甚至有些PNS上面要處理的APP不只一個,要處理10幾個APP的排程,那就很不適合放某個時間一定要跳出來的通知。
2.原本可以用的推播,某一天就不能用了?
- 憑證過期,再做一個就好了!
- 從同一個bundle ID做出兩個以上provision,砍到剩一個就好了!
3.推播傳到一半就停止不傳了?
- development的deviceToken不小心混到distribution的清單裡面,找出來,砍掉!(至於怎麼找嘛....)
優點:
- 沒網路GG,APNS會保留一段時間,等裝置可以上網的時候再補推
- 我們拿到使用者註冊推播後,沒有去偵測使用者有沒有刪除APP的話,群發推播的時候會有一堆發送失敗,也會拖慢排程發送的時間。不過這點應該不叫缺點,而是一定會發生又忘記做的事。
1 則留言:
怎麼寫到後面,沒有
本地推播、EKEvent的呢?
張貼留言