##APNs原理 原理見得多了,我放一張圖你們本身體會。😁 php
##iOS客戶端 ###消息類型UNAuthorizationOptionsjava
typedef NS_OPTIONS(NSUInteger, UNAuthorizationOptions) { UNAuthorizationOptionBadge = (1 << 0), //角標 UNAuthorizationOptionSound = (1 << 1), //消息音效 UNAuthorizationOptionAlert = (1 << 2), //彈窗 UNAuthorizationOptionCarPlay = (1 << 3), //車載 } __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0);
###消息的數據結構apache
{ "aps":{ "sound":"default", "alert":"這是一條測試消息" }, "url":"http://www.10086.cn" }
aps是系統字段 ,除此以外還能夠自定義字段,如url。 但apple對推送消息的大小是有限制的,這點要注意。json
###註冊通知消息類型 消息類型只有在註冊後,才能使用對應的類型。消息類型是多選的。 當第一次打開APP,須要註冊消息類型,以後就不須要註冊了。數據結構
object-c UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter]; [center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert + UNAuthorizationOptionSound) completionHandler:^(BOOL granted, NSError * _Nullable error) { // Enable or disable features based on authorization. }]; SWIFT let center = UNUserNotificationCenter.current() center.requestAuthorization(options: [.alert, .sound]) { (granted, error) in // Enable or disable features based on authorization. }
這裏給本身挖個坑,(UNAuthorizationOptionAlert + UNAuthorizationOptionSound) 和(UNAuthorizationOptionAlert | UNAuthorizationOptionSound)的區別,有知道的大牛指點一下。app
UIUserNotificationType types = UIUserNotificationTypeBadge+UIUserNotificationTypeSound+UIUserNotificationTypeAlert; UIUserNotificationSettings *mySettings = [UIUserNotificationSettings settingsForTypes:types categories:nil]; [[UIApplication sharedApplication] registerUserNotificationSettings:mySettings];
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];
###啓動消息推送eclipse
id<UNUserNotificationCenterDelegate> delegate; [UNUserNotificationCenter currentNotificationCenter].delegate = delegate; [[UIApplication sharedApplication] registerForRemoteNotifications];
這裏的delegate 能夠是AppDelegate,也能夠是任意指定的對象。須要知足生命週期和app同樣長,以及時的收到推送消息。iphone
[[UIApplication sharedApplication] registerForRemoteNotifications];
###設備註冊 在開啓消息推送後,app啓動後,系統就會返回devicetoken,將devicetoken上傳給消息推送sever,以備推送消息的時候用測試
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { //打印獲取的deviceToken的字符串 [self pushTokenToSever:deviceToken]; } //若是deviceToken獲取不到,會進入此事件 - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)err { NSString *str = [NSString stringWithFormat: @"Error: %@",err]; NSLog(@"註冊推送失敗%@",str); }
模擬器是獲取不到deviceToken的。url
###接收消息處理 app收到推送消息,會有如下觸發場景
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { if ([launchOptions isKindOfClass:[NSDictionary class]]) { NSDictionary *userInfo = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]; if ([userInfo isKindOfClass:[NSDictionary class]]) { //處理userInfo裏面的消息數據 } } }
####app已啓動,在前臺顯示
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler { if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) { if ([SchemeHelper sharedInstance].delegate) { NSDictionary *userInfo = notification.request.content.userInfo; //此處省略一萬行需求代碼。。。。。。 }else { // 判斷爲本地通知 } }
####app已啓動,在後臺
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler { DLog(@"++++++++++++++++++++++++++++++++++++++++++%s",__func__); // iOS10 app關閉啓動、後臺啓動 都會觸發此方法. if ([SchemeHelper sharedInstance].delegate) { NSDictionary *userInfo = response.notification.request.content. content.userInfo; } }
在iOS10以前,app已經啓動了後,統一由一個方法處理
- (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo { //推送反饋(app運行時) NSLog(@"推送反饋(app運行時) %@",userInfo); }
##消息推送Sever的搭建 客戶端的代碼有了,做爲一個iOS開發,仍是須要掌握點服務端知識,來自測你的推送配置。
下面是用java在myeclipse上面搭建的簡單環境,你也能夠用php等等。
import java.util.ArrayList; import java.util.List; import javapns.devices.Device; import javapns.devices.implementations.basic.BasicDevice; import javapns.notification.AppleNotificationServerBasicImpl; import javapns.notification.PushNotificationManager; import javapns.notification.PushNotificationPayload; import javapns.notification.PushedNotification; import org.apache.commons.lang.StringUtils; import com.alibaba.fastjson.JSONArray; public class PushDemo { public static void main(String[] args) throws Exception { String tokenJson = "[\"cfa9120938bfb24276e1db189fe40a18210ffbd15ccc75f5754c9ddb1d0d40c3\"]"; List<String> token = (List<String>) JSONArray.parse(tokenJson); String alert = "my notification message";//push的內容 String sound = "default";//鈴音 List<String> tokens = new ArrayList<String>(); tokens.addAll(token); String certificatePath = "src/apns_development.p12"; String certificatePassword = "123456";//此處注意導出的證書密碼不能爲空由於空密碼會報錯 boolean flag = false; // String certificatePath = "src/aps_distribution.p12"; // String certificatePassword = "ALSKDJFH!G";//此處注意導出的證書密碼不能爲空由於空密碼會報錯 // boolean flag = true; //true:表示的是產品發佈推送服務 false:表示的是產品測試推送服務 boolean sendCount = false; try { PushNotificationPayload payLoad = new PushNotificationPayload(); payLoad.addAlert(alert); // 消息內容 payLoad.addBadge(0); // iphone應用圖標上小紅圈上的數值 payLoad.addCustomDictionary("url", "http://www.10086.cn"); payLoad.addCustomDictionary("type", ""); payLoad.addCustomDictionary("msgid", "192"); payLoad.addCustomDictionary("login", "0"); if (!StringUtils.isBlank(sound)) { payLoad.addSound(sound);//鈴音 } PushNotificationManager pushManager = new PushNotificationManager(); pushManager.initializeConnection(new AppleNotificationServerBasicImpl(certificatePath, certificatePassword, flag)); List<PushedNotification> notifications = new ArrayList<PushedNotification>(); // 發送push消息 if (sendCount) { Device device = new BasicDevice(); device.setToken(tokens.get(0)); PushedNotification notification = pushManager.sendNotification(device, payLoad, true); notifications.add(notification); } else { List<Device> device = new ArrayList<Device>(); for (String atoken : tokens) { device.add(new BasicDevice(atoken)); } notifications = pushManager.sendNotifications(payLoad, device); } List<PushedNotification> failedNotifications = PushedNotification.findFailedNotifications(notifications); List<PushedNotification> successfulNotifications = PushedNotification.findSuccessfulNotifications(notifications); int failed = failedNotifications.size(); int successful = successfulNotifications.size(); pushManager.stopConnection(); System.out.println("failedNotifications:"+failedNotifications); System.out.println("successfulNotifications:"+successfulNotifications); } catch (Exception e) { e.printStackTrace(); } } }
這裏用到了2個jar包