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
相關文章
相關標籤/搜索