iOS Remote消息推送学习文档一篇足以

##APNs原理 原理见得多了,我放一张图你们本身体会。😁 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,须要注册消息类型,以后就不须要注册了。数据结构

  • iOS10以后
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

  • iOS8
UIUserNotificationType types = UIUserNotificationTypeBadge+UIUserNotificationTypeSound+UIUserNotificationTypeAlert;
UIUserNotificationSettings *mySettings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:mySettings];
  • iOS8以前
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];

###启动消息推送eclipse

  • iOS10以后 使用的userNotifications.framework,须要设置代理
id<UNUserNotificationCenterDelegate> delegate;
[UNUserNotificationCenter currentNotificationCenter].delegate = delegate;
[[UIApplication sharedApplication] registerForRemoteNotifications];

这里的delegate 能够是AppDelegate,也能够是任意指定的对象。须要知足生命周期和app同样长,以及时的收到推送消息。iphone

  • iOS8
[[UIApplication sharedApplication] registerForRemoteNotifications];
  • iOS8之前 注册消息类型的同事就启动了消息推送
  • (void)registerForRemoteNotificationTypes:(UIRemoteNotificationType)types

###设备注册 在开启消息推送后,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收到推送消息,会有如下触发场景

  • app未启动
  • app已启动,在前台显示
  • app已启动,在后台 ####app未启动 app未启动,消息会在iOS系统的通知中心展现,用户点击消息后,会启动app,并传入消息数据。 触发- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions; 消息数据保存在launchOptions
- (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包

  • fastjson-1.2.7.jar
  • JavaPNS_2.2.jar
相关文章
相关标签/搜索