天天看點

ios 本地通知與消息推送 iOS開發中的兩種消息通知機制詳解

iOS開發中的兩種消息通知機制詳解

iOS中通知機制又叫消息機制,其包括兩類:一類是本地通知;另一類是推送通知,也叫遠端通知。兩種通知在iOS中的表現一緻,可以通過橫幅或者彈出提醒兩種形式告訴使用者,并且點選通知可以會打開應用程式,但是實作原理卻完全不同。

本地通知

1.建立UILocalNotification。

2.設定處理通知的時間fireDate。

3.配置通知的内容:通知主體、通知聲音、圖示數字等。

4.配置通知傳遞的自定義資料參數userInfo(這一步可選)。

5.調用通知,可以使用scheduleLocalNotification:按計劃排程一個通知,也可以使用presentLocalNotificationNow立即調用通知。

下面就以一個程式更新後使用者長期沒有使用的提醒為例對本地通知做一個簡單的了解。在這個過程中并沒有牽扯太多的界面操作,所有的邏輯都在AppDelegate中:進入應用後如果沒有注冊通知,需要首先注冊通知請求使用者允許通知;一旦調用完注冊方法,無論使用者是否選擇允許通知此刻都會調用應用程式的- (void)application:(UIApplication )application didRegisterUserNotificationSettings:(UIUserNotificationSettings )notificationSettings代理方法,在這個方法中根據使用者的選擇:如果是允許通知則會按照前面的步驟建立通知并在一定時間後執行。

<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#import <span class="hljs-title" style="box-sizing: border-box;">"AppDelegate.h"</span></span>
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#import <span class="hljs-title" style="box-sizing: border-box;">"KCMainViewController.h"</span></span>
<span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">@interface</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">AppDelegate</span> ()</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">@end</span>
<span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">@implementation</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">AppDelegate</span></span>
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#pragma mark - 應用代理方法</span>
- (<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">BOOL</span>)application:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIApplication</span> *)application didFinishLaunchingWithOptions:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSDictionary</span> *)launchOptions {

    _window=[[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIWindow</span> alloc]initWithFrame:[UIScreen mainScreen]<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.bounds</span>];

    _window<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.backgroundColor</span> =[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIColor</span> colorWithRed:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">249</span>/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">255.0</span> green:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">249</span>/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">255.0</span> blue:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">249</span>/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">255.0</span> alpha:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>];

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//設定全局導覽列風格和顔色</span>
    [[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UINavigationBar</span> appearance] setBarTintColor:[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIColor</span> colorWithRed:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">23</span>/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">255.0</span> green:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">180</span>/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">255.0</span> blue:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">237</span>/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">255.0</span> alpha:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>]];
    [[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UINavigationBar</span> appearance] setBarStyle:UIBarStyleBlack];

    KCMainViewController *mainController=[[KCMainViewController alloc]init];
    _window<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.rootViewController</span>=mainController;

    [_window makeKeyAndVisible];
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//如果已經獲得發送通知的授權則建立本地通知,否則請求授權(注意:如果不請求授權在設定中是沒有對應的通知設定項的,也就是說如果從來沒有發送過請求,即使通過設定也打不開消息允許設定)</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> ([[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIApplication</span> sharedApplication]currentUserNotificationSettings]<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.types</span>!=UIUserNotificationTypeNone) {
        [<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span> addLocalNotification];
    }<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span>{
        [[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIApplication</span> sharedApplication]registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound  categories:<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">nil</span>]];
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">YES</span>;
}
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#pragma mark 調用過使用者注冊通知方法之後執行(也就是調用完registerUserNotificationSettings:方法之後執行)</span>
-(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>)application:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIApplication</span> *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings{
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (notificationSettings<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.types</span>!=UIUserNotificationTypeNone) {
        [<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span> addLocalNotification];
    }
}
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#pragma mark 進入前台後設定消息資訊</span>
-(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>)applicationWillEnterForeground:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIApplication</span> *)application{
    [[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIApplication</span> sharedApplication]setApplicationIconBadgeNumber:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>];<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//進入前台取消應用消息圖示</span>
}
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#pragma mark - 私有方法</span>
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#pragma mark 添加本地通知</span>
-(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>)addLocalNotification{

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//定義本地通知對象</span>
    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UILocalNotification</span> *notification=[[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UILocalNotification</span> alloc]init];
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//設定調用時間</span>
    notification<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.fireDate</span>=[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSDate</span> dateWithTimeIntervalSinceNow:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10.0</span>];<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//通知觸發的時間,10s以後</span>
    notification<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.repeatInterval</span>=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>;<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//通知重複次數</span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//notification.repeatCalendar=[NSCalendar currentCalendar];//目前月曆,使用前最好設定時區等資訊以便能夠自動同步時間</span>

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//設定通知屬性</span>
    notification<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.alertBody</span>[email protected]<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"最近添加了諸多有趣的特性,是否立即體驗?"</span>; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//通知主體</span>
    notification<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.applicationIconBadgeNumber</span>=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//應用程式圖示右上角顯示的消息數</span>
    notification<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.alertAction</span>[email protected]<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"打開應用"</span>; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//待機界面的滑動動作提示</span>
    notification<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.alertLaunchImage</span>[email protected]<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Default"</span>;<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//通過點選通知打開應用時的啟動圖檔,這裡使用程式啟動圖檔</span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//notification.soundName=UILocalNotificationDefaultSoundName;//收到通知時播放的聲音,預設消息聲音</span>
    notification<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.soundName</span>[email protected]<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"msg.caf"</span>;<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//通知聲音(需要真機才能聽到聲音)</span>

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//設定使用者資訊</span>
    notification<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.userInfo</span>[email protected]{@<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"id"</span>:@<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>,@<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"user"</span>:@<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Kenshin Cui"</span>};<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//綁定到通知上的其他附加資訊</span>

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//調用通知</span>
    [[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIApplication</span> sharedApplication] scheduleLocalNotification:notification];
}
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#pragma mark 移除本地通知,在不需要此通知時記得移除</span>
-(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>)removeNotification{
    [[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIApplication</span> sharedApplication] cancelAllLocalNotifications];
}
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">@end</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li></ul>      
ios 本地通知與消息推送 iOS開發中的兩種消息通知機制詳解

1.請求獲得使用者允許通知的效果。

2.應用退出到後彈出通知的效果。

3.鎖屏狀态下的通知效果(從這個界面可以看到alertAction配置為“打開應用”)。

注意:

  • 在使用通知之前必須注冊通知類型,如果使用者不允許應用程式發送通知,則以後就無法發送通知,除非使用者手動到iOS設定中打開通知。
  • 本地通知是有作業系統統一排程的,隻有在應用退出到背景或者關閉才能收到通知。(注意:這一點對于後面的推送通知也是完全适用的。 )
  • 通知的聲音是由iOS系統播放的,格式必須是Linear PCM、MA4(IMA/ADPCM)、µLaw、aLaw中的一種,并且播放時間必須在30s内,否則将被系統聲音替換,同時自定義聲音檔案必須放到main boundle中。
  • 本地通知的數量是有限制的,最近的本地通知最多隻能有64個,超過這個數量将被系統忽略。
  • 如果想要移除本地通知可以調用UIApplication的cancelLocalNotification:或cancelAllLocalNotifications移除指定通知或所有通知。

從上面的程式可以看到userInfo這個屬性我們設定了參數,那麼這個參數如何接收呢?

在iOS中如果點選一個彈出通知(或者鎖屏界面滑動檢視通知),預設會自動打開目前應用。由于通知由系統排程那麼此時進入應用有兩種情況:如果應用程式已經完全退出那麼此時會調用- (BOOL)application:(UIApplication )application didFinishLaunchingWithOptions:(NSDictionary )launchOptions方法;如果此時應用程式還在運作(無論是在前台還是在背景)則會調用-(void)application:(UIApplication )application didReceiveLocalNotification:(UILocalNotification )notification方法接收消息參數。當然如果是後者自然不必多說,因為參數中已經可以拿到notification對象,隻要讀取userInfo屬性即可。如果是前者的話則可以通路launchOptions中鍵為UIApplicationLaunchOptionsLocalNotificationKey的對象,這個對象就是發送的通知,由此對象再去通路userInfo。為了示範這個過程在下面的程式中将userInfo的内容寫入檔案以便模拟關閉程式後再通過點選通知打開應用擷取userInfo的過程。

<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#import <span class="hljs-title" style="box-sizing: border-box;">"AppDelegate.h"</span></span>
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#import <span class="hljs-title" style="box-sizing: border-box;">"KCMainViewController.h"</span></span>
<span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">@interface</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">AppDelegate</span> ()</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">@end</span>
<span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">@implementation</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">AppDelegate</span></span>
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#pragma mark - 應用代理方法</span>
- (<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">BOOL</span>)application:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIApplication</span> *)application didFinishLaunchingWithOptions:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSDictionary</span> *)launchOptions {

    _window=[[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIWindow</span> alloc]initWithFrame:[UIScreen mainScreen]<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.bounds</span>];

    _window<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.backgroundColor</span> =[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIColor</span> colorWithRed:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">249</span>/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">255.0</span> green:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">249</span>/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">255.0</span> blue:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">249</span>/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">255.0</span> alpha:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>];

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//設定全局導覽列風格和顔色</span>
    [[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UINavigationBar</span> appearance] setBarTintColor:[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIColor</span> colorWithRed:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">23</span>/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">255.0</span> green:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">180</span>/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">255.0</span> blue:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">237</span>/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">255.0</span> alpha:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>]];
    [[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UINavigationBar</span> appearance] setBarStyle:UIBarStyleBlack];

    KCMainViewController *mainController=[[KCMainViewController alloc]init];
    _window<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.rootViewController</span>=mainController;

    [_window makeKeyAndVisible];
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//添加通知</span>
    [<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span> addLocalNotification];
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//接收通知參數</span>
    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UILocalNotification</span> *notification=[launchOptions valueForKey:UIApplicationLaunchOptionsLocalNotificationKey];
    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSDictionary</span> *userInfo= notification<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.userInfo</span>;

    [userInfo writeToFile:@<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"/Users/kenshincui/Desktop/didFinishLaunchingWithOptions.txt"</span> atomically:<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">YES</span>];
    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSLog</span>(@<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"didFinishLaunchingWithOptions:The userInfo is %@."</span>,userInfo);

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">YES</span>;
}
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#pragma mark 接收本地通知時觸發</span>
-(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>)application:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIApplication</span> *)application didReceiveLocalNotification:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UILocalNotification</span> *)notification{
    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSDictionary</span> *userInfo=notification<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.userInfo</span>;
    [userInfo writeToFile:@<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"/Users/kenshincui/Desktop/didReceiveLocalNotification.txt"</span> atomically:<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">YES</span>];
    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSLog</span>(@<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"didReceiveLocalNotification:The userInfo is %@"</span>,userInfo);
}
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#pragma mark 調用過使用者注冊通知方法之後執行(也就是調用完registerUserNotificationSettings:方法之後執行)</span>
-(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>)application:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIApplication</span> *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings{
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (notificationSettings<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.types</span>!=UIUserNotificationTypeNone) {
        [<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span> addLocalNotification];
    }
}
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#pragma mark 進入前台後設定消息資訊</span>
-(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>)applicationWillEnterForeground:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIApplication</span> *)application{
    [[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIApplication</span> sharedApplication]setApplicationIconBadgeNumber:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>];<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//進入前台取消應用消息圖示</span>
}
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#pragma mark - 私有方法</span>
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#pragma mark 添加本地通知</span>
-(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>)addLocalNotification{

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//定義本地通知對象</span>
    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UILocalNotification</span> *notification=[[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UILocalNotification</span> alloc]init];
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//設定調用時間</span>
    notification<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.fireDate</span>=[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSDate</span> dateWithTimeIntervalSinceNow:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10.0</span>];<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//通知觸發的時間,10s以後</span>
    notification<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.repeatInterval</span>=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>;<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//通知重複次數</span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//notification.repeatCalendar=[NSCalendar currentCalendar];//目前月曆,使用前最好設定時區等資訊以便能夠自動同步時間</span>

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//設定通知屬性</span>
    notification<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.alertBody</span>[email protected]<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"最近添加了諸多有趣的特性,是否立即體驗?"</span>; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//通知主體</span>
    notification<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.applicationIconBadgeNumber</span>=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//應用程式圖示右上角顯示的消息數</span>
    notification<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.alertAction</span>[email protected]<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"打開應用"</span>; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//待機界面的滑動動作提示</span>
    notification<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.alertLaunchImage</span>[email protected]<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Default"</span>;<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//通過點選通知打開應用時的啟動圖檔</span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//notification.soundName=UILocalNotificationDefaultSoundName;//收到通知時播放的聲音,預設消息聲音</span>
    notification<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.soundName</span>[email protected]<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"msg.caf"</span>;<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//通知聲音(需要真機)</span>

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//設定使用者資訊</span>
    notification<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.userInfo</span>[email protected]{@<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"id"</span>:@<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>,@<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"user"</span>:@<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Kenshin Cui"</span>};<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//綁定到通知上的其他額外資訊</span>

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//調用通知</span>
    [[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIApplication</span> sharedApplication] scheduleLocalNotification:notification];
}
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">@end</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li></ul>      

上面的程式可以分為兩種情況去運作:一種是啟動程式關閉程式,等到接收到通知之後點選通知重新進入程式;另一種是啟動程式後,進入背景(其實在前台也可以,但是為了明顯的體驗這個過程建議進入背景),接收到通知後點選通知進入應用。另種情況會分别按照前面說的情況調用不同的方法接收到userInfo寫入本地檔案系統。有了userInfo一般來說就可以根據這個資訊進行一些處理,例如可以根據不同的參數資訊導航到不同的界面,假設是更新的通知則可以導航到更新内容界面等。

推送通知

和本地通知不同,推送通知是由應用服務提供商發起的,通過蘋果的APNs(Apple Push Notification Server)發送到應用用戶端。下面是蘋果官方關于推送通知的過程示意圖: 

ios 本地通知與消息推送 iOS開發中的兩種消息通知機制詳解

推送通知的過程可以分為以下幾步:

1.應用服務提供商從伺服器端把要發送的消息和裝置令牌(device token)發送給蘋果的消息推送伺服器APNs。

2.APNs根據裝置令牌在已注冊的裝置(iPhone、iPad、iTouch、mac等)查找對應的裝置,将消息發送給相應的裝置。

3.用戶端裝置接将接收到的消息傳遞給相應的應用程式,應用程式根據使用者設定彈出通知消息。

當然,這隻是一個簡單的流程,有了這個流程我們還無從下手編寫程式,将上面的流程細化可以得到如下流程圖(圖檔來自網際網路),在這個過程中會也會提到如何在程式中完成這些步驟: 

ios 本地通知與消息推送 iOS開發中的兩種消息通知機制詳解

1.應用程式注冊APNs推送消息。

說明:

a.隻有注冊過的應用才有可能接收到消息,程式中通常通過UIApplication的registerUserNotificationSettings:方法注冊,iOS8中通知注冊的方法發生了改變,如果是iOS7及之前版本的iOS請參考其他代碼。

b.注冊之前有兩個前提條件必須準備好:開發配置檔案(provisioning profile,也就是.mobileprovision字尾的檔案)的App ID不能使用通配ID必須使用指定APP ID并且生成配置檔案中選擇Push Notifications服務,一般的開發配置檔案無法完成注冊;應用程式的Bundle Identifier必須和生成配置檔案使用的APP ID完全一緻。

2.iOS從APNs接收device token,在應用程式擷取device token。

說明:

a.在UIApplication的-(void)application:(UIApplication )application didRegisterForRemoteNotificationsWithDeviceToken:(NSData)deviceToken代理方法中擷取令牌,此方法發生在注冊之後。

b.如果無法正确獲得device token可以在UIApplication的-(void)application:(UIApplication )application didFailToRegisterForRemoteNotificationsWithError:(NSError )error代理方法中檢視詳細錯誤資訊,此方法發生在擷取device token失敗之後。

c.必須真機調試,模拟器無法擷取device token。

3.iOS應用将device token發送給應用程式提供商,告訴伺服器端目前裝置允許接收消息。

說明:

a.device token的生成算法隻有Apple掌握,為了確定算法發生變化後仍然能夠正常接收伺服器端發送的通知,每次應用程式啟動都重新獲得device token(注意:device token的擷取不會造成性能問題,蘋果官方已經做過優化)。

b.通常可以建立一個網絡連接配接發送給應用程式提供商的伺服器端, 在這個過程中最好将上一次獲得的device token存儲起來,避免重複發送,一旦發現device token發生了變化最好将原有的device token一塊發送給伺服器端,伺服器端删除原有令牌存儲新令牌避免伺服器端發送無效消息。

4.應用程式提供商在伺服器端根據前面發送過來的device token組織資訊發送給APNs。

說明:

a.發送時指定device token和消息内容,并且完全按照蘋果官方的消息格式組織消息内容,通常情況下可以借助其他第三方消息推送架構來完成。

5.APNs根據消息中的device token查找已注冊的裝置推送消息。

說明:

a.正常情況下可以根據device token将消息成功推送到用戶端裝置中,但是也不排除使用者解除安裝程式的情況,此時推送消息失敗,APNs會将這個錯誤消息通知伺服器端以避免資源浪費(伺服器端此時可以根據錯誤删除已經存儲的device token,下次不再發送)。

下面将簡單示範一下推送通知的簡單流程:

首先,看一下iOS用戶端代碼:

<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#import <span class="hljs-title" style="box-sizing: border-box;">"AppDelegate.h"</span></span>
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#import <span class="hljs-title" style="box-sizing: border-box;">"KCMainViewController.h"</span></span>
<span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">@interface</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">AppDelegate</span> ()</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">@end</span>
<span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">@implementation</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">AppDelegate</span></span>
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#pragma mark - 應用程式代理方法</span>
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#pragma mark 應用程式啟動之後</span>
- (<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">BOOL</span>)application:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIApplication</span> *)application didFinishLaunchingWithOptions:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSDictionary</span> *)launchOptions {

    _window=[[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIWindow</span> alloc]initWithFrame:[UIScreen mainScreen]<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.bounds</span>];

    _window<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.backgroundColor</span> =[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIColor</span> colorWithRed:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">249</span>/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">255.0</span> green:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">249</span>/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">255.0</span> blue:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">249</span>/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">255.0</span> alpha:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>];

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//設定全局導覽列風格和顔色</span>
    [[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UINavigationBar</span> appearance] setBarTintColor:[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIColor</span> colorWithRed:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">23</span>/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">255.0</span> green:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">180</span>/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">255.0</span> blue:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">237</span>/<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">255.0</span> alpha:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>]];
    [[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UINavigationBar</span> appearance] setBarStyle:UIBarStyleBlack];

    KCMainViewController *mainController=[[KCMainViewController alloc]init];
    _window<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.rootViewController</span>=mainController;

    [_window makeKeyAndVisible];

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//注冊推送通知(注意iOS8注冊方法發生了變化)</span>
    [application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound categories:<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">nil</span>]];
    [application registerForRemoteNotifications];

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">YES</span>;
}
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#pragma mark 注冊推送通知之後</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//在此接收裝置令牌</span>
-(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>)application:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIApplication</span> *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{
    [<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span> addDeviceToken:deviceToken];
    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSLog</span>(@<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"device token:%@"</span>,deviceToken);
}
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#pragma mark 擷取device token失敗後</span>
-(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>)application:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIApplication</span> *)application didFailToRegisterForRemoteNotificationsWithError:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSError</span> *)error{
    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSLog</span>(@<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"didFailToRegisterForRemoteNotificationsWithError:%@"</span>,error<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.localizedDescription</span>);
    [<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span> addDeviceToken:<span class="hljs-literal" style="color: rgb(0, 102, 102); box-sizing: border-box;">nil</span>];
}
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#pragma mark 接收到推送通知之後</span>
-(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>)application:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">UIApplication</span> *)application didReceiveRemoteNotification:(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSDictionary</span> *)userInfo{
    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSLog</span>(@<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"receiveRemoteNotification,userInfo is %@"</span>,userInfo);
}
<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#pragma mark - 私有方法</span>
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
 *  添加裝置令牌到伺服器端
 *
 *  @param deviceToken 裝置令牌
 */</span>
-(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>)addDeviceToken:(NSData *)deviceToken{
    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSString</span> *[email protected]<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"DeviceToken"</span>;
    NSData *oldToken= [[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSUserDefaults</span> standardUserDefaults]objectForKey:key];
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//如果偏好設定中的已儲存設備令牌和新擷取的令牌不同則存儲新令牌并且發送給伺服器端</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (![oldToken isEqualToData:deviceToken]) {
        [[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSUserDefaults</span> standardUserDefaults] setObject:deviceToken forKey:key];
        [<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span> sendDeviceTokenWidthOldDeviceToken:oldToken newDeviceToken:deviceToken];
    }
}
-(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>)sendDeviceTokenWidthOldDeviceToken:(NSData *)oldToken newDeviceToken:(NSData *)newToken{
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//注意一定確定真機可以正常通路下面的位址</span>
    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSString</span> *[email protected]<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http://192.168.1.101/RegisterDeviceToken.aspx"</span>;
    urlStr=[urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSURL</span> *url=[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSURL</span> URLWithString:urlStr];
    NSMutableURLRequest *requestM=[NSMutableURLRequest requestWithURL:url cachePolicy:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span> timeoutInterval:<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">10.0</span>];
    [requestM setHTTPMethod:@<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"POST"</span>];
    <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSString</span> *bodyStr=[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSString</span> stringWithFormat:@<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"oldToken=%@&newToken=%@"</span>,oldToken,newToken];
    NSData *body=[bodyStr dataUsingEncoding:NSUTF8StringEncoding];
    [requestM setHTTPBody:body];
    NSURLSession *session=[NSURLSession sharedSession];
    NSURLSessionDataTask *dataTask= [session dataTaskWithRequest:requestM completionHandler:^(NSData *data, NSURLResponse *response, <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSError</span> *error) {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (error) {
            <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSLog</span>(@<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Send failure,error is :%@"</span>,error<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">.localizedDescription</span>);
        }<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span>{
            <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">NSLog</span>(@<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"Send Success!"</span>);
        }

    }];
    [dataTask resume];
}
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">@end</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li><li style="box-sizing: border-box; padding: 0px 5px;">74</li><li style="box-sizing: border-box; padding: 0px 5px;">75</li><li style="box-sizing: border-box; padding: 0px 5px;">76</li><li style="box-sizing: border-box; padding: 0px 5px;">77</li><li style="box-sizing: border-box; padding: 0px 5px;">78</li><li style="box-sizing: border-box; padding: 0px 5px;">79</li><li style="box-sizing: border-box; padding: 0px 5px;">80</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li><li style="box-sizing: border-box; padding: 0px 5px;">74</li><li style="box-sizing: border-box; padding: 0px 5px;">75</li><li style="box-sizing: border-box; padding: 0px 5px;">76</li><li style="box-sizing: border-box; padding: 0px 5px;">77</li><li style="box-sizing: border-box; padding: 0px 5px;">78</li><li style="box-sizing: border-box; padding: 0px 5px;">79</li><li style="box-sizing: border-box; padding: 0px 5px;">80</li></ul>      

iOS用戶端代碼的代碼比較簡單,注冊推送通知,擷取device token存儲到偏好設定中,并且如果新擷取的device token不同于偏好設定中存儲的資料則發送給伺服器端,更新伺服器端device token清單。

其次,由于device token需要發送給伺服器端,這裡使用一個Web應用作為伺服器端接收device token,這裡使用了ASP.NET程式來處理令牌接收注冊工作,當然你使用其他技術同樣沒有問題。下面是對應的背景代碼:

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> System;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> System.Collections.Generic;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> System.Web;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> System.Web.UI;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> System.Web.UI.WebControls;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> CMJ.Framework.Data;
namespace WebServer
{
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">partial</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> RegisterDeviceToken : System.Web.UI.Page
    {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span> _appID = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">@"com.cmjstudio.pushnotification"</span>;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> SqlHelper _helper = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> SqlHelper();
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">Page_Load</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span> sender, EventArgs e)
        {
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span>
            {
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span> oldToken = Request[<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"oldToken"</span>] + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">""</span>;
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span> newToken = Request[<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"newToken"</span>] + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">""</span>;
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span> sql = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">""</span>;
                <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//如果傳遞舊的裝置令牌則删除舊令牌添加新令牌</span>
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (oldToken != <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">""</span>)
                {
                    sql = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span>.Format(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"DELETE FROM dbo.Device WHERE AppID='{0}' AND DeviceToken='{1}';"</span>, _appID, oldToken);
                }
                sql += <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span>.Format(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">@"IF NOT EXISTS (SELECT ID FROM dbo.Device WHERE AppID='{0}' AND DeviceToken='{1}')
                                        INSERT INTO dbo.Device ( AppID, DeviceToken ) VALUES ( N'{0}', N'{1}');"</span>, _appID, newToken);
                _helper.ExecuteNonQuery(sql);
                Response.Write(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"注冊成功!"</span>);
            }
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span>(Exception ex)
            {
                Response.Write(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"注冊失敗,錯誤詳情:"</span>+ex.ToString());
            }
        }
    }
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li></ul>      

這個過程主要就是儲存device token到資料庫中,當然如果同時傳遞舊的裝置令牌還需要先删除就的裝置令牌,這裡簡單的在資料庫中建立了一張Device表來儲存裝置令牌,其中記錄了應用程式Id和裝置令牌。 

第三步就是伺服器端發送消息,如果要給APNs發送消息就必須按照Apple的标準消息格式組織消息内容。但是好在目前已經有很多開源的第三方類庫供我們使用,具體消息如何包裝完全不用自己組織,這裡使用一個開源的類庫Push Sharp來給APNs發送消息 ,除了可以給Apple裝置推送消息,Push Sharp還支援Android、Windows Phone等多種裝置,更多詳細内容大家可以參照官方說明。前面說過如果要開發消息推送應用不能使用一般的開發配置檔案,這裡還需要注意:如果伺服器端要給APNs發送消息其秘鑰也必須是通過APNs Development iOS類型的證書來導出的,一般的iOS Development 類型的證書導出的秘鑰無法用作伺服器端發送秘鑰。下面通過在一個簡單的WinForm程式中調用Push Sharp給APNs發送消息,這裡讀取之前Device表中的所有裝置令牌循環發送消息:

<code class="hljs cs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> System;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> System.IO;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> System.Collections.Generic;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> System.ComponentModel;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> System.Data;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> System.Drawing;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> System.Text;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> System.Windows.Forms;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> PushSharp;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> PushSharp.Apple;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> CMJ.Framework.Data;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> CMJ.Framework.Logging;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> CMJ.Framework.Windows.Forms;
namespace PushNotificationServer
{
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">partial</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> frmMain : PersonalizeForm
    {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span> _appID = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">@"com.cmjstudio.pushnotification"</span>;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> SqlHelper _helper = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> SqlHelper();
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-title" style="box-sizing: border-box;">frmMain</span>()
        {
            InitializeComponent();
        }
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">btnClose_Click</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span> sender, EventArgs e)
        {
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>.Close();
        }
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">btnSend_Click</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span> sender, EventArgs e)
        {
            List<<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span>> deviceTokens = GetDeviceToken();
            SendMessage(deviceTokens, tbMessage.Text);
        }
        <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#<span class="hljs-keyword" style="box-sizing: border-box;">region</span> 發送消息</span>
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><summary></span></span>
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> 取得所有裝置令牌</span>
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"></summary></span></span>
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><returns></span>裝置令牌<span class="hljs-xmlDocTag" style="box-sizing: border-box;"></returns></span></span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> List<<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span>> <span class="hljs-title" style="box-sizing: border-box;">GetDeviceToken</span>()
        {
            List<<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span>> deviceTokens = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> List<<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span>>();
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span> sql = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span>.Format(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"SELECT DeviceToken FROM dbo.Device WHERE AppID='{0}'"</span>,_appID);
            DataTable dt = _helper.GetDataTable(sql);
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(dt.Rows.Count><span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>)
            {
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">foreach</span>(DataRow dr <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span> dt.Rows)
                {
                    deviceTokens.Add((dr[<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"DeviceToken"</span>]+<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">""</span>).TrimStart(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'<'</span>).TrimEnd(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'>'</span>).Replace(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">" "</span>,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">""</span>));
                }
            }
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> deviceTokens;
        }

        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><summary></span></span>
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> 發送消息</span>
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"></summary></span></span>
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><param name="deviceToken"></span>裝置令牌<span class="hljs-xmlDocTag" style="box-sizing: border-box;"></param></span></span>
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><param name="message"></span>消息内容<span class="hljs-xmlDocTag" style="box-sizing: border-box;"></param></span></span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">SendMessage</span>(List<<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span>> deviceToken, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span> message)
        {
            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//建立推送對象</span>
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">var</span> pusher = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> PushBroker();
            pusher.OnNotificationSent += pusher_OnNotificationSent;<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//發送成功事件</span>
            pusher.OnNotificationFailed += pusher_OnNotificationFailed;<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//發送失敗事件</span>
            pusher.OnChannelCreated += pusher_OnChannelCreated;
            pusher.OnChannelDestroyed += pusher_OnChannelDestroyed;
            pusher.OnChannelException += pusher_OnChannelException;
            pusher.OnDeviceSubscriptionChanged += pusher_OnDeviceSubscriptionChanged;
            pusher.OnDeviceSubscriptionExpired += pusher_OnDeviceSubscriptionExpired;
            pusher.OnNotificationRequeue += pusher_OnNotificationRequeue;
            pusher.OnServiceException += pusher_OnServiceException;
            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//注冊推送服務</span>
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">byte</span>[] certificateData = File.ReadAllBytes(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">@"E:\KenshinCui_Push.p12"</span>);
            pusher.RegisterAppleService(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> ApplePushChannelSettings(certificateData, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"123"</span>));
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">foreach</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span> token <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span> deviceToken)
            {
                <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//給指定裝置發送消息</span>
                pusher.QueueNotification(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> AppleNotification()
                    .ForDeviceToken(token)
                    .WithAlert(message) 
                    .WithBadge(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>)
                    .WithSound(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"default"</span>));
            }
        }
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> pusher_OnServiceException(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span> sender, Exception error)
        {
            Console.WriteLine(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"消息發送失敗,錯誤詳情:"</span> + error.ToString());
            PersonalizeMessageBox.Show(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"消息發送失敗,錯誤詳情:"</span> + error.ToString(), <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"系統提示"</span>);
        }
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> pusher_OnNotificationRequeue(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span> sender, PushSharp.Core.NotificationRequeueEventArgs e)
        {
            Console.WriteLine(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"pusher_OnNotificationRequeue"</span>);
        }
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> pusher_OnDeviceSubscriptionExpired(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span> sender, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span> expiredSubscriptionId, DateTime expirationDateUtc, PushSharp.Core.INotification notification)
        {
            Console.WriteLine(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"pusher_OnDeviceSubscriptionChanged"</span>);
        }
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> pusher_OnDeviceSubscriptionChanged(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span> sender, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span> oldSubscriptionId, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span> newSubscriptionId, PushSharp.Core.INotification notification)
        {
            Console.WriteLine(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"pusher_OnDeviceSubscriptionChanged"</span>);
        }
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> pusher_OnChannelException(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span> sender, PushSharp.Core.IPushChannel pushChannel, Exception error)
        {
            Console.WriteLine(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"消息發送失敗,錯誤詳情:"</span> + error.ToString());
            PersonalizeMessageBox.Show(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"消息發送失敗,錯誤詳情:"</span> + error.ToString(), <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"系統提示"</span>);
        }
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> pusher_OnChannelDestroyed(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span> sender)
        {
            Console.WriteLine(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"pusher_OnChannelDestroyed"</span>);
        }
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> pusher_OnChannelCreated(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span> sender, PushSharp.Core.IPushChannel pushChannel)
        {
            Console.WriteLine(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"pusher_OnChannelCreated"</span>);
        }
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> pusher_OnNotificationFailed(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span> sender, PushSharp.Core.INotification notification, Exception error)
        {
            Console.WriteLine(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"消息發送失敗,錯誤詳情:"</span> + error.ToString());
            PersonalizeMessageBox.Show(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"消息發送失敗,錯誤詳情:"</span>+error.ToString(), <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"系統提示"</span>);
        }
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> pusher_OnNotificationSent(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span> sender, PushSharp.Core.INotification notification)
        {
            Console.WriteLine(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"消息發送成功!"</span>);
            PersonalizeMessageBox.Show(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">this</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"消息發送成功!"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"系統提示"</span>);
        }
        <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#<span class="hljs-keyword" style="box-sizing: border-box;">endregion</span></span>
    }
}
</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li><li style="box-sizing: border-box; padding: 0px 5px;">74</li><li style="box-sizing: border-box; padding: 0px 5px;">75</li><li style="box-sizing: border-box; padding: 0px 5px;">76</li><li style="box-sizing: border-box; padding: 0px 5px;">77</li><li style="box-sizing: border-box; padding: 0px 5px;">78</li><li style="box-sizing: border-box; padding: 0px 5px;">79</li><li style="box-sizing: border-box; padding: 0px 5px;">80</li><li style="box-sizing: border-box; padding: 0px 5px;">81</li><li style="box-sizing: border-box; padding: 0px 5px;">82</li><li style="box-sizing: border-box; padding: 0px 5px;">83</li><li style="box-sizing: border-box; padding: 0px 5px;">84</li><li style="box-sizing: border-box; padding: 0px 5px;">85</li><li style="box-sizing: border-box; padding: 0px 5px;">86</li><li style="box-sizing: border-box; padding: 0px 5px;">87</li><li style="box-sizing: border-box; padding: 0px 5px;">88</li><li style="box-sizing: border-box; padding: 0px 5px;">89</li><li style="box-sizing: border-box; padding: 0px 5px;">90</li><li style="box-sizing: border-box; padding: 0px 5px;">91</li><li style="box-sizing: border-box; padding: 0px 5px;">92</li><li style="box-sizing: border-box; padding: 0px 5px;">93</li><li style="box-sizing: border-box; padding: 0px 5px;">94</li><li style="box-sizing: border-box; padding: 0px 5px;">95</li><li style="box-sizing: border-box; padding: 0px 5px;">96</li><li style="box-sizing: border-box; padding: 0px 5px;">97</li><li style="box-sizing: border-box; padding: 0px 5px;">98</li><li style="box-sizing: border-box; padding: 0px 5px;">99</li><li style="box-sizing: border-box; padding: 0px 5px;">100</li><li style="box-sizing: border-box; padding: 0px 5px;">101</li><li style="box-sizing: border-box; padding: 0px 5px;">102</li><li style="box-sizing: border-box; padding: 0px 5px;">103</li><li style="box-sizing: border-box; padding: 0px 5px;">104</li><li style="box-sizing: border-box; padding: 0px 5px;">105</li><li style="box-sizing: border-box; padding: 0px 5px;">106</li><li style="box-sizing: border-box; padding: 0px 5px;">107</li><li style="box-sizing: border-box; padding: 0px 5px;">108</li><li style="box-sizing: border-box; padding: 0px 5px;">109</li><li style="box-sizing: border-box; padding: 0px 5px;">110</li><li style="box-sizing: border-box; padding: 0px 5px;">111</li><li style="box-sizing: border-box; padding: 0px 5px;">112</li><li style="box-sizing: border-box; padding: 0px 5px;">113</li><li style="box-sizing: border-box; padding: 0px 5px;">114</li><li style="box-sizing: border-box; padding: 0px 5px;">115</li><li style="box-sizing: border-box; padding: 0px 5px;">116</li><li style="box-sizing: border-box; padding: 0px 5px;">117</li><li style="box-sizing: border-box; padding: 0px 5px;">118</li><li style="box-sizing: border-box; padding: 0px 5px;">119</li><li style="box-sizing: border-box; padding: 0px 5px;">120</li><li style="box-sizing: border-box; padding: 0px 5px;">121</li><li style="box-sizing: border-box; padding: 0px 5px;">122</li><li style="box-sizing: border-box; padding: 0px 5px;">123</li><li style="box-sizing: border-box; padding: 0px 5px;">124</li><li style="box-sizing: border-box; padding: 0px 5px;">125</li><li style="box-sizing: border-box; padding: 0px 5px;">126</li><li style="box-sizing: border-box; padding: 0px 5px;">127</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li><li style="box-sizing: border-box; padding: 0px 5px;">74</li><li style="box-sizing: border-box; padding: 0px 5px;">75</li><li style="box-sizing: border-box; padding: 0px 5px;">76</li><li style="box-sizing: border-box; padding: 0px 5px;">77</li><li style="box-sizing: border-box; padding: 0px 5px;">78</li><li style="box-sizing: border-box; padding: 0px 5px;">79</li><li style="box-sizing: border-box; padding: 0px 5px;">80</li><li style="box-sizing: border-box; padding: 0px 5px;">81</li><li style="box-sizing: border-box; padding: 0px 5px;">82</li><li style="box-sizing: border-box; padding: 0px 5px;">83</li><li style="box-sizing: border-box; padding: 0px 5px;">84</li><li style="box-sizing: border-box; padding: 0px 5px;">85</li><li style="box-sizing: border-box; padding: 0px 5px;">86</li><li style="box-sizing: border-box; padding: 0px 5px;">87</li><li style="box-sizing: border-box; padding: 0px 5px;">88</li><li style="box-sizing: border-box; padding: 0px 5px;">89</li><li style="box-sizing: border-box; padding: 0px 5px;">90</li><li style="box-sizing: border-box; padding: 0px 5px;">91</li><li style="box-sizing: border-box; padding: 0px 5px;">92</li><li style="box-sizing: border-box; padding: 0px 5px;">93</li><li style="box-sizing: border-box; padding: 0px 5px;">94</li><li style="box-sizing: border-box; padding: 0px 5px;">95</li><li style="box-sizing: border-box; padding: 0px 5px;">96</li><li style="box-sizing: border-box; padding: 0px 5px;">97</li><li style="box-sizing: border-box; padding: 0px 5px;">98</li><li style="box-sizing: border-box; padding: 0px 5px;">99</li><li style="box-sizing: border-box; padding: 0px 5px;">100</li><li style="box-sizing: border-box; padding: 0px 5px;">101</li><li style="box-sizing: border-box; padding: 0px 5px;">102</li><li style="box-sizing: border-box; padding: 0px 5px;">103</li><li style="box-sizing: border-box; padding: 0px 5px;">104</li><li style="box-sizing: border-box; padding: 0px 5px;">105</li><li style="box-sizing: border-box; padding: 0px 5px;">106</li><li style="box-sizing: border-box; padding: 0px 5px;">107</li><li style="box-sizing: border-box; padding: 0px 5px;">108</li><li style="box-sizing: border-box; padding: 0px 5px;">109</li><li style="box-sizing: border-box; padding: 0px 5px;">110</li><li style="box-sizing: border-box; padding: 0px 5px;">111</li><li style="box-sizing: border-box; padding: 0px 5px;">112</li><li style="box-sizing: border-box; padding: 0px 5px;">113</li><li style="box-sizing: border-box; padding: 0px 5px;">114</li><li style="box-sizing: border-box; padding: 0px 5px;">115</li><li style="box-sizing: border-box; padding: 0px 5px;">116</li><li style="box-sizing: border-box; padding: 0px 5px;">117</li><li style="box-sizing: border-box; padding: 0px 5px;">118</li><li style="box-sizing: border-box; padding: 0px 5px;">119</li><li style="box-sizing: border-box; padding: 0px 5px;">120</li><li style="box-sizing: border-box; padding: 0px 5px;">121</li><li style="box-sizing: border-box; padding: 0px 5px;">122</li><li style="box-sizing: border-box; padding: 0px 5px;">123</li><li style="box-sizing: border-box; padding: 0px 5px;">124</li><li style="box-sizing: border-box; padding: 0px 5px;">125</li><li style="box-sizing: border-box; padding: 0px 5px;">126</li><li style="box-sizing: border-box; padding: 0px 5px;">127</li></ul>      

伺服器端消息發送應用運作效果: 

ios 本地通知與消息推送 iOS開發中的兩種消息通知機制詳解

iOS用戶端接收的消息的效果: 

ios 本地通知與消息推送 iOS開發中的兩種消息通知機制詳解

到目前為止通過伺服器端應用可以順利發送消息給APNs并且iOS應用已經成功接收推送消息。

補充–iOS開發證書、秘鑰

iOS開發過程中如果需要進行真機調試、釋出需要注冊申請很多證書,對于初學者往往迷惑不解,再加上今天的文章中會牽扯到一些特殊配置,這裡就簡單的對iOS開發的常用證書和秘鑰等做一說明。

證書

iOS常用的證書包括開發證書和釋出證書,無論是真機調試還是最終釋出應用到App Store這兩個證書都是必須的,它是iOS開發的基本證書。

a.開發證書:開發證書又分為普通開發證書和推送證書,如果僅僅是一般的應用則前者即可滿足,但是如果開發推送應用則必須使用推送證書。

b.釋出證書:釋出證書又可以分為普通釋出證書、推送證書、Pass Type ID證書、站點釋出證書、VoIP服務證書、蘋果支付證書。同樣的,對于需要使用特殊服務的應用則必須選擇對應的證書。

應用辨別

App ID,應用程式的唯一辨別,對應iOS應用的Bundle Identifier,App ID在蘋果開發者中心中分為通配應用ID和明确的應用ID,前者一般用于普通應用開發,一個ID可以适用于多個不同辨別的應用;但是對于使用消息推送、Passbook、站點釋出、iCloud等服務的應用必須配置明确的應用ID。

裝置辨別

UDID,用于辨別每一台硬體裝置的标示符。注意它不是device token,device token是根據UDID使用一個隻有Apple自己才知道的算法生成的一組标示符。

配置簡介

Provisioning Profiles,平時又稱為PP檔案。将UDID、App ID、開發證書打包在一起的配置檔案,同樣分為開發和釋出兩類配置檔案。

秘鑰

在申請開發證書時必須要首先送出一個秘鑰請求檔案,對于生成秘鑰請求檔案的mac,如果要做開發則隻需要下載下傳證書和配置簡介即可開發。但是如果要想在其他機器上做開發則必須将證書中的秘鑰導出(導出之後是一個.p12檔案),然後導入其他機器。同時對于類似于推送伺服器端應用如果要給APNs發送消息,同樣需要使用.p12秘鑰檔案,并且這個秘鑰檔案需要是推送證書導出的對應秘鑰。