Swift JPush極光推送通知和自定義消息

在開始之前窘问,首先了解下自定義消息和通知的幾點區(qū)別。

自定義消息和通知的區(qū)別

  • 收到推送自定義消息時推送通知欄不顯示
  • 自定義消息推送不經(jīng)過APNS宜咒,所以說跟推送證書沒有關(guān)系
  • 只有app在前臺時才能收到自定義消息惠赫,未啟動或者啟動但處于后臺時接收不到(解決了不想在app未啟動時收到推送消息的問題)

SDK初始化

Appdelegate文件

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        
        // 極光推送
        if (UIDevice.current.systemVersion as NSString).floatValue >= 10.0  {
            
            if #available(iOS 10.0, *) {
                let entity = JPUSHRegisterEntity()
                entity.types = NSInteger(UNAuthorizationOptions.alert.rawValue | UNAuthorizationOptions.badge.rawValue | UNAuthorizationOptions.sound.rawValue)
                _ = JPUSHService.register(forRemoteNotificationConfig: entity, delegate: self)
            } else {
                // Fallback on earlier versions
            }
            
        } else if  (UIDevice.current.systemVersion as NSString).floatValue >= 8.0 {
            //可以添加自定義categories
            JPUSHService.register(forRemoteNotificationTypes: UIUserNotificationType.badge.rawValue | UIUserNotificationType.sound.rawValue | UIUserNotificationType.alert.rawValue, categories: nil)
        } else {
            //categories 必須為nil
            JPUSHService.register(forRemoteNotificationTypes: UIUserNotificationType.badge.rawValue | UIUserNotificationType.sound.rawValue | UIUserNotificationType.alert.rawValue, categories: nil)
        }
        
        var isJpushProduction: Bool
        #if DEBUG
            isJpushProduction = false
        #else
            isJpushProduction = true
        #endif
        
        JPUSHService.setup(withOption: launchOptions, appKey: JPUSHService_appKey, channel: "Publish channel", apsForProduction: isJpushProduction, advertisingIdentifier: nil)
        
        return true
    }

通知(極光遠程推送)

調(diào)用此 API 來取得應用程序?qū)?RegistrationID。 只有當應用程序成功注冊到 JPush 的服務器時才返回對應的值故黑,否則返回空字符串儿咱。

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        
        JPUSHService.registerDeviceToken(deviceToken)
        
        /**
         completionHandler用于處理設(shè)置返回結(jié)果
         resCode返回的結(jié)果狀態(tài)碼
         registrationID返回registrationID
         */
        JPUSHService.registrationIDCompletionHandler { (resCode, registrationID) in
            print("resCode--", resCode, "    registrationID---", registrationID ?? "沒有")
        }
    }

注冊失敗回調(diào)方法

func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
        
        print("didFailToRegisterForRemoteNotificationsWithError----", error)
    }

iOS10以下的系統(tǒng)版本庭砍,收到本地通知(LocalNotification)時調(diào)用

func application(_ application: UIApplication, didReceive notification: UILocalNotification) {
        
        let userInfo = notification.userInfo;
        print("userInfo-------", userInfo ?? ["":""])
    }

基于iOS10以下iOS 7 及以上的系統(tǒng)版本,收到遠程通知(RemoteNotification)時調(diào)用

private func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        
        JPUSHService.handleRemoteNotification(userInfo)
        // 收到遠程通知后的處理
        handleTheRemoteNotification(userInfo: userInfo as NSDictionary)
        completionHandler(UIBackgroundFetchResult.newData)
    }

在iOS 10出來后吏颖,極光推出了下面的兩個新方法來替代了以上的兩個方法。

iOS10及以上系統(tǒng)版本,app在后臺(1咆槽、app在后臺運行 2、鎖屏狀態(tài) 3、app關(guān)閉時)收到通知并且當用戶點擊通知欄上的消息時調(diào)用

@available(iOS 10.0, *)
    func jpushNotificationCenter(_ center: UNUserNotificationCenter!, didReceive response: UNNotificationResponse!, withCompletionHandler completionHandler: (() -> Void)!) {
        
        let userInfo = response.notification.request.content.userInfo
        if response.notification.request.trigger?.isKind(of: UNPushNotificationTrigger.classForCoder()) == true {
            
            JPUSHService.handleRemoteNotification(userInfo)
            print("iOS10后臺收到通知(當用戶點擊通知欄的時候)...")
            // 收到遠程通知后的處理
            handleTheRemoteNotification(userInfo: userInfo as NSDictionary)
            
        } else {
            print("----本地通知")
        }
        
        completionHandler() // 系統(tǒng)要求執(zhí)行這個方法
    }

iOS10及以上系統(tǒng)版本,app處于前臺時接收到通知時調(diào)用

@available(iOS 10.0, *)
    func jpushNotificationCenter(_ center: UNUserNotificationCenter!, willPresent notification: UNNotification!, withCompletionHandler completionHandler: ((Int) -> Void)!) {
        
        let userInfo = notification.request.content.userInfo
        
        if notification.request.trigger?.isKind(of: UNPushNotificationTrigger.classForCoder()) == true {
            JPUSHService.handleRemoteNotification(userInfo)
            print("iOS10 前臺收到遠程通知...")
            // 收到遠程通知后的處理
            handleTheRemoteNotification(userInfo: userInfo as NSDictionary)
            
        } else {
            print("本地通知...")
        }
        
        let tempPresentationOptions = UNNotificationPresentationOptions.alert.rawValue |  UNNotificationPresentationOptions.sound.rawValue | UNNotificationPresentationOptions.badge.rawValue
        completionHandler(Int(tempPresentationOptions)) // 需要執(zhí)行這個方法方面,選擇是否提醒用戶,有Badge、Sound扬蕊、Alert三種類型可以選擇設(shè)置
    }

自定義方法再愈,用于收到遠程通知后的一些處理操作,比如取值以及頁面的跳轉(zhuǎn)等等

func handleTheRemoteNotification(userInfo: NSDictionary) {
        
        let aps = userInfo["aps"] as? NSDictionary // 取得 APNs 標準信息內(nèi)容
        let content = aps?["alert"] as? String ?? "" // 推送顯示的內(nèi)容
        let customizeField = aps?["customizeExtras"] as? String ?? "" // 服務端中Extras字段缴渊,key是自己定義的
        
        let ctrlAlert = UIAlertController(title: "提醒", message: content, preferredStyle: UIAlertControllerStyle.alert)
        
        let confirmAction = UIAlertAction(title: "確定", style: .default){ (action) in
            UIApplication.shared.applicationIconBadgeNumber -= 1
            // 所需業(yè)務邏輯處理菩佑。劣光。雄可。
        }
        let cancelAction =  UIAlertAction(title: "取消", style: .default) { (action) in
            UIApplication.shared.applicationIconBadgeNumber -= 1
            // 不作處理
        }
        
        ctrlAlert.addAction(cancelAction)
        ctrlAlert.addAction(confirmAction)
        
        let rootVC = UIApplication.shared.keyWindow?.rootViewController
}

通知(本地推送)

對于一些業(yè)務需求箱残,比如鬧鈴或者日歷的一些提醒事件等,自己推送消息俄删,實現(xiàn)推送通知的效果妨猩。

func pushLocalNotification() {
        
        let notification = UILocalNotification()
        if #available(iOS 8.2, *) {
            notification.alertTitle = "小蝸牛"
        } else {
            // Fallback on earlier versions
        }
        notification.alertBody = "快來玩啊~"
        notification.userInfo = ["name": "Tony", "gender": "man"]
        UIApplication.shared.presentLocalNotificationNow(notification)
    }

自定義消息

功能說明:只有在前端運行的時候才能收到自定義消息的推送。
從jpush服務器獲取用戶推送的自定義消息內(nèi)容和標題以及附加字段等迈勋。
這些內(nèi)容是和后臺的同學們協(xié)商好的较鼓,并且由他們來寫好向極光推送的相應服務谆级。

獲取iOS的推送內(nèi)容需要在appDelegate類中注冊通知并實現(xiàn)回調(diào)方法吕朵。

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        
        // 極光推送哮塞,接收自定義消息
        let defaultCenter = NotificationCenter.default
        defaultCenter.addObserver(self, selector: #selector(networkDidReceiveMessage(notification:)), name: NSNotification.Name.jpfNetworkDidReceiveMessage, object: nil)
        
        return true
    }

回調(diào)方法

// 接收自定義消息
    func networkDidReceiveMessage(notification:NSNotification) {

        let userInfo: NSDictionary = notification.userInfo! as NSDictionary
        print("自定義消息---",userInfo)
        
        // 業(yè)務邏輯處理。板惑。喷好。
    }

標簽與別名

別名 alias

為安裝了應用程序的用戶订雾,取個別名來標識识补。以后給該用戶 Push 消息時孕荠,就可以用此別名來指定。
每個用戶只能指定一個別名骚灸。
同一個應用程序內(nèi)雏赦,對不同的用戶靴寂,建議取不同的別名榨汤。這樣蜜宪,盡可能根據(jù)別名來唯一確定用戶缝呕。
系統(tǒng)不限定一個別名只能指定一個用戶。如果一個別名被指定到了多個用戶煎源,當給指定這個別名發(fā)消息時,服務器端API會同時給這多個用戶發(fā)送消息耙册。
舉例:在一個用戶要登錄的游戲中毫捣,可能設(shè)置別名為 userid详拙。游戲運營時,發(fā)現(xiàn)該用戶 3 天沒有玩游戲了蔓同,則根據(jù) userid 調(diào)用服務器端API發(fā)通知到客戶端提醒用戶饶辙。

標簽 tag

為安裝了應用程序的用戶,打上標簽斑粱。其目的主要是方便開發(fā)者根據(jù)標簽弃揽,來批量下發(fā) Push 消息。
可為每個用戶打多個標簽则北。
舉例: game, old_page, women

別名與標簽的設(shè)置
因為別名和標簽可以重復設(shè)置矿微,所以我把它放在了登錄方法中。

func login() {
  //極光推送 注冊別名
  let alias = String(format: "%d", userId)
  JPUSHService.setTags(["lowbeer","doubeer"], aliasInbackground: alias)
}

然后在退出登錄時注銷別名和標簽尚揣,避免在多個設(shè)備上登錄后涌矢,通過別名發(fā)送通知時,多個設(shè)備都會收到的情況惑艇。

// 退出登錄
func logout() {
  // 注銷推送別名和標簽
  JPUSHService.setTags([], aliasInbackground: "")
}

參數(shù)說明

alias
  • nil 此次調(diào)用不設(shè)置此值蒿辙。
  • 空字符串 ("")表示取消之前的設(shè)置拇泛。
  • 每次調(diào)用設(shè)置有效的別名滨巴,覆蓋之前的設(shè)置。
  • 有效的別名組成:字母(區(qū)分大小寫)俺叭、數(shù)字恭取、下劃線、漢字熄守,特殊- 字符(v2.1.9支持)@!#$&*+=.|蜈垮。
  • 限制:alias 命名長度限制為 40 字節(jié)耗跛。(判斷長度需采用UTF-8編碼)
tags
  • nil 此次調(diào)用不設(shè)置此值。
  • 空集合([NSSet set])表示取消之前的設(shè)置攒发。
  • 集合成員類型要求為String類型
  • 每次調(diào)用至少設(shè)置一個 tag调塌,覆蓋之前的設(shè)置,不是新增惠猿。
  • 有效的標簽組成:字母(區(qū)分大小寫)羔砾、數(shù)字、下劃線偶妖、漢字姜凄,特殊字符(v2.1.9支持)@!#$&*+=.|。
  • 限制:每個 tag 命名長度限制為 40 字節(jié)趾访,最多支持設(shè)置 1000 個 tag态秧,但總長度不得超過7K字節(jié)。(判斷長度需采用UTF-8編碼)
    單個設(shè)備最多支持設(shè)置 1000 個 tag扼鞋。App 全局 tag 數(shù)量無限制申鱼。

小結(jié)

在推送測試時如果接收不到通知,不要著急藏鹊,不要悲傷润讥,深呼吸,淡定~~~

  • 要檢查好項目的開發(fā)和生產(chǎn)證書是否配置正確盘寡,并上傳到了極光應用后臺楚殿,并保證證書沒有過期。參考SDK集成指南證書設(shè)置指南
  • 項目Target的Push Notifications開關(guān)是否打開竿痰。
  • 卸載應用重新安裝脆粥。我有次第一次收到了,但是后邊卻無論如何都接收不到了影涉,然后拿著RegId和MsgId問了下極光的技術(shù)变隔,他們告訴我:
    1、apple認為token失效了
    2蟹倾、蘋果建議程序每次啟動的時候從 apns 獲取 devicetoken
    重新獲取一次新的token匣缘,測試時,簡單的操作就是卸載重裝
    ---該問題可以看下這個蘋果APNs’ device token特性和過期更新鲜棠。
  • 在極光官網(wǎng)最下方有技術(shù)交流群肌厨,可以加群找技術(shù)咨詢解決。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末豁陆,一起剝皮案震驚了整個濱河市柑爸,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌盒音,老刑警劉巖表鳍,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件馅而,死亡現(xiàn)場離奇詭異,居然都是意外死亡譬圣,警方通過查閱死者的電腦和手機瓮恭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來厘熟,“玉大人偎血,你說我怎么就攤上這事《⑵” “怎么了颇玷?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長就缆。 經(jīng)常有香客問我帖渠,道長,這世上最難降的妖魔是什么竭宰? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任空郊,我火速辦了婚禮,結(jié)果婚禮上切揭,老公的妹妹穿的比我還像新娘狞甚。我一直安慰自己,他們只是感情好廓旬,可當我...
    茶點故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布哼审。 她就那樣靜靜地躺著,像睡著了一般孕豹。 火紅的嫁衣襯著肌膚如雪涩盾。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天励背,我揣著相機與錄音春霍,去河邊找鬼。 笑死叶眉,一個胖子當著我的面吹牛址儒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播衅疙,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼莲趣,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了炼蛤?” 一聲冷哼從身側(cè)響起妖爷,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤蝶涩,失蹤者是張志新(化名)和其女友劉穎理朋,沒想到半個月后絮识,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡嗽上,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年次舌,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片兽愤。...
    茶點故事閱讀 38,577評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡彼念,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出浅萧,到底是詐尸還是另有隱情逐沙,我是刑警寧澤,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布洼畅,位于F島的核電站吩案,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏帝簇。R本人自食惡果不足惜徘郭,卻給世界環(huán)境...
    茶點故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望丧肴。 院中可真熱鬧残揉,春花似錦、人聲如沸芋浮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽纸巷。三九已至江醇,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間何暇,已是汗流浹背陶夜。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留裆站,地道東北人条辟。 一個月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像宏胯,于是被迫代替她去往敵國和親羽嫡。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,452評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 版本記錄 前言 前一篇已經(jīng)對ios新特性進行了介紹肩袍,這一篇則對ios的SDK進行說明杭棵。1. 極光推送集成(一)2....
    刀客傳奇閱讀 1,282評論 0 1
  • 版本記錄 前言 ??現(xiàn)在很多APP都有推送功能,其中極光推送就是很多APP的首選。我們最近的幾個APP也是用的極光...
    刀客傳奇閱讀 8,367評論 0 8
  • 點擊查看原文 Web SDK 開發(fā)手冊 SDK 概述 網(wǎng)易云信 SDK 為 Web 應用提供一個完善的 IM 系統(tǒng)...
    layjoy閱讀 13,692評論 0 15
  • 推送技術(shù)產(chǎn)生場景: --服務器端主動性: 客戶端與服務器交互都是客戶端主動的, 服務器一般不能主動與客戶端進行數(shù)據(jù)...
    原軍鋒閱讀 34,532評論 4 60
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理魂爪,服務發(fā)現(xiàn)先舷,斷路器,智...
    卡卡羅2017閱讀 134,628評論 18 139