iOS推送(兼容iOS10及以上)

系统自带

1. 注册推送

iOS10及以上版本需要导入以下头文件

// iOS10注册APNs所需头文件
#ifdef NSFoundationVersionNumber_iOS_9_x_Max
#import 
#endif
// 在该方法中注册通知
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    if ([[UIDevice currentDevice].systemVersion doubleValue] >= 10.0) {
        // iOS10及以上版本
        UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
        center.delegate = self;
        [center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert | UNAuthorizationOptionBadge | UNAuthorizationOptionSound) completionHandler:^(BOOL granted, NSError * _Nullable error) {
            if (granted) {
                // 点击允许
                NSLog(@"注册成功");
                [center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
                    NSLog(@"%@", settings);
                }];
            } else {
                // 点击不允许
                NSLog(@"注册失败")
            }
        }];
    } else if ([[UIDevice currentDevice].systemVersion doubleValue] >= 8.0) {
        // iOS8及以上 iOS10以下
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
        [application registerUserNotificationSettings:settings];
    } if ([[UIDevice currentDevice].systemVersion floatValue] < 8.0) {
        //iOS8系统以下
        [application registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound)];
    }
    
    
   // 2.注册远程通知
   [application registerForRemoteNotifications];
    
    return YES;
}

2.通知注册回调获取token

// 获取token成功
- (void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    NSLog(@"%@", [NSString stringWithFormat:@"Device Token: %@", deviceToken]);
}

// 获取token失败
- (void)application:(UIApplication *)application
didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
    NSLog(@"did Fail To Register For Remote Notifications With Error: %@", error);
}

报错:"OBJC_CLASS$_UNUserNotificationCenter", referenced from"
解决办法:link binary With中导入UserNotifications.framework

3. 收到系统推送

前台收到推送

iOS10及以上可以在前台收到推送后提醒

- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
    
    completionHandler(UNNotificationPresentationOptionBadge | UNNotificationPresentationOptionAlert | UNAuthorizationOptionBadge);
}

点击推送

// iOS10级以上
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler {

    NSDictionary * userInfo = response.notification.request.content.userInfo;
    UNNotificationRequest *request = response.notification.request; // 收到推送的请求
    UNNotificationContent *content = request.content; // 收到推送的消息内容
    NSNumber *badge = content.badge;  // 推送消息的角标
    NSString *body = content.body;    // 推送消息体
    UNNotificationSound *sound = content.sound;  // 推送消息的声音
    NSString *subtitle = content.subtitle;  // 推送消息的副标题
    NSString *title = content.title;  // 推送消息的标题
    
    // 系统要求执行该方法
    completionHandler();
}

// iOS7及以上
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
    completionHandler(UIBackgroundFetchResultNewData);
}

// iOS6及以下
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
}

PHP推送测试

制作iOS推送证书pem

1. 从钥匙串中导出certificate和private key的.p12

2. 使用.p12制作.pem

// certificate
openssl pkcs12 -clcerts -nokeys -out <导出certificate证书文件地址>.pem -in .12

// private key
openssl pkcs12 -nocerts -out <导出key文件地址>.pem -in .p12

unable to load client certificate private key file
140735895778184:error:0906D06C:PEM routines:PEM_read_bio:no start line:/BuildRoot/Library/Caches/com.apple.xbs/Sources/libressl/libressl-22/libressl/crypto/pem/pem_lib.c:704:Expecting: ANY PRIVATE KEY
注意:private key 制作必须输入密码 如果为空会报错以上错误

3. 移除private key.pem文件密码

openssl rsa -in .pem -out .pem

4. 将certificate.pem和private key.pem文件合成

cat .pem .pem > <合成文件名>.pem

5. 测试合成文件

// 开发地址服务器:gateway.sandbox.push.apple.com:2195
// 正是地址地址服务器:gateway.push.apple.com:2195
openssl s_client -connect <上述地址服务器> -cert <合成的.pem文件/certificate.pem文件> -key 

// 如果合成文件可用输出类似如下
Enter pass phrase for apns-dis-key.pem:
CONNECTED(00000006)
depth=1 C = US, O = "Entrust, Inc.", OU = See www.entrust.net/legal-terms, OU = "(c) 2012 Entrust, Inc. - for authorized use only", CN = Entrust Certification Authority - L1K
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
 0 s:/C=US/ST=California/L=Cupertino/O=Apple Inc./CN=gateway.sandbox.push.apple.com
   i:/C=US/O=Entrust, Inc./OU=See www.entrust.net/legal-terms/OU=(c) 2012 Entrust, Inc. - for authorized use only/CN=Entrust Certification Authority - L1K
 1 s:/C=US/O=Entrust, Inc./OU=See www.entrust.net/legal-terms/OU=(c) 2012 Entrust, Inc. - for authorized use only/CN=Entrust Certification Authority - L1K
   i:/O=Entrust.net/OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/OU=(c) 1999 Entrust.net Limited/CN=Entrust.net Certification Authority (2048)
---
Server certificate
-----BEGIN CERTIFICATE-----
······
-----END CERTIFICATE-----
subject=/C=US/ST=California/L=Cupertino/O=Apple Inc./CN=gateway.sandbox.push.apple.com
issuer=/C=US/O=Entrust, Inc./OU=See www.entrust.net/legal-terms/OU=(c) 2012 Entrust, Inc. - for authorized use only/CN=Entrust Certification Authority - L1K
---
Acceptable client certificate CA names
/C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Apple Root CA
/C=US/O=Apple Inc./OU=Apple Worldwide Developer Relations/CN=Apple Worldwide Developer Relations Certification Authority
/CN=Apple Application Integration 2 Certification Authority/OU=Apple Certification Authority/O=Apple Inc./C=US
/C=US/ST=CA/L=Cupertino/O=Apple Inc./OU=Internet Software and Services/CN=iCloud Test/[email protected]
/C=US/ST=California/L=Cupertino/O=Apple Inc./CN=gateway.sandbox.push.apple.com
/C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Apple Application Integration Certification Authority
---
SSL handshake has read 3662 bytes and written 2522 bytes
---
New, TLSv1/SSLv3, Cipher is DES-CBC3-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : DES-CBC3-SHA
    Session-ID:
    Session-ID-ctx:
    Master-Key: D3D1D69B9410949E89DDF7C21C3CCE332321274CEB07B20916E6D982237953917049D99FD64B76DFAA5FD6962463A88E
    Start Time: 1512554054
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---

使用php推送信息

 array("alert" => 'message',"badge" => 2,"sound"=>'default'));  //推送方式,包含内容和声音
    $ctx = stream_context_create();
    //如果在Windows的服务器上,寻找pem路径会有问题,路径修改成这样的方法:
    //$pem = dirname(__FILE__) . '/' . 'apns-dev.pem';
    //linux 的服务器直接写pem的路径即可
    stream_context_set_option($ctx,"ssl","local_cert","apns-dis.pem");
    $pass = "xxxxxx";
    stream_context_set_option($ctx, 'ssl', 'passphrase', $pass);
    //此处有两个服务器需要选择,如果是开发测试用,选择第二名sandbox的服务器并使用Dev的pem证书,如果是正是发布,使用Product的pem并选用正式的服务器
    // $fp = stream_socket_client("ssl://gateway.push.apple.com:2195", $err, $errstr, 60, STREAM_CLIENT_CONNECT, $ctx);
    $fp = stream_socket_client("ssl://gateway.sandbox.push.apple.com:2195", $err, $errstr, 60, STREAM_CLIENT_CONNECT, $ctx);
    if (!$fp) {
    echo "Failed to connect $err $errstrn";
    return;
    }
    print "Connection OK\n";
    $payload = json_encode($body);
    $msg = chr(0) . pack("n",32) . pack("H*", str_replace(' ', '', $deviceToken)) . pack("n",strlen($payload)) . $payload;
    echo "sending message :" . $payload ."\n";
    fwrite($fp, $msg);
    fclose($fp);
?>

PushMeBaby测试推送

PushMeBayGit传送门

1. 导入推送证书

2. 填写注册推送获取到的Token

3. 运行

运行报错:注释掉报错头文件

极光推送

极光推送传送门

你可能感兴趣的:(iOS推送(兼容iOS10及以上))