##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包