iOS消息推送

推送的分类

iOS的推送分为2种:

  • 远程服务器推送-RemoteNotification

    服务器端根据Apple分配的SSL证书和每个用户的Device Token,依据一定的格式,将消息发送到APNs(Apple Push Notification Service)服务器,APNs服务器进行权限验证,通过后将消息转发到对于的token(用户)上

  • 本地推送服务-LocalNotification

    本地推送推送依赖于某一时间的触发,当时间达到后, 即发送提醒的信息,适用于todo,闹钟等app;

RemoteNotification

客户端Token获取的原理:

Alt text

  1. 手机开机联网后,系统后台自动连接APNs服务器;
  2. APNs为这台设备分配一个token;
  3. 经过用户的允许后, 你的app可以通过方法application: didRegisterForRemoteNotificationsWithDeviceToken获取到用户的token;
    通知的类型有三种(badge-app图标右上角红色数字,alert常用的锁屏时出现的消息,sound即声音提醒), 可以同时组合这3种通知的类型:
    Alt text
1
2
3
- (void)applicationDidFinishLaunching:(UIApplication *)application{
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
}
  1. app将token上传,服务器保存token,便于后续的推送;

服务器端的推送原理

根据保存的token和ssl证书, 对APNs发送固定二进制格式的包,推送的python脚本大致如下:
Alt text

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import socket, ssl, struct
token = 'a4b8e18bd065c6ea7def614631ee4abaf26dbd56cde307e596fbf838fbb03296'
json = '{"aps": {"alert": {"body": "Hello Frank"}}}'

//对以上信息,pack成二进制的包
byteToken = token.decode('hex')
binary = struct.pack('!BH32sH', 0, 32, byteToken, len(json))
binary += json

// 推送binary包
connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ssl_sock = ssl.wrap_socket(connection, certfile='yourCertificate.pem')
ssl_sock.connect(('gateway.sandbox.push.apple.com', 2195)) // 官网分配的地址和端口
ssl_sock.write(alert)
ssl_sock.close()

用户点击通知消息后,触发的事件

点击消息后, 触发application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
推送包种的json已经被转化为NSDictionary类型,可将消息提取出来, 展示在界面中.

LocalNotification

本地消息的推送依赖时间的触发

1
2
3
4
5
6
  - (void) applicationDidFinishLaunching:(UIApplication *)application{
UILocalNotification * notification = [[UILocalNotification alloc] init];
notification.fireDate = [NSDate dateWithTimeIntervalSinceNow:10];
notification.alertBody = @"HI Frank!!";
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
}
本文如对你有帮助,请鼓励下!