今天就談論ios開發(fā)中發(fā)送和推送消息的相關(guān)內(nèi)容,接受服務器發(fā)來的推送消息巩踏,首先要生成apple推送的證書奢讨,配置開發(fā)和上傳到app stroe的配置文件读拆,配置移動端項目接收消息的推送篮绰,利用parse rest api和swift發(fā)送推送消息祝懂,最后響應消息推送的交互枫匾。
首先要創(chuàng)建推送證書
創(chuàng)建推送證書部分,需要在apple developer中注冊app id男娄,創(chuàng)建apple push notification service證書震蒋,配置應用程序的app service瞬场,注冊用于調(diào)試的iOS 設備乾巧。
由于推送功能只能運行在真機上句喜,所以需要一個有效的數(shù)字簽名證書。在https://developer.apple.com的頁面中生成這個證書沟于,它需要apple developer身份咳胃,這個身份是需要購買的。
接著要想生成一個推送證書旷太,換需要在自己的mac電腦上生成一個證書簽名請求拙绊。
注意點:在那臺電腦上生成了證書簽名請求(csr文件),那這臺電腦就具備了開發(fā)資格泳秀。只能在這臺電腦上進行真機調(diào)試并上傳到app store上面。
推送證書創(chuàng)建需要一個app id榄攀,所以就在apple developer中注冊一個apple ID:
以圖為例
接下來就是創(chuàng)建推送證書:
仍然用圖說明:
接著把創(chuàng)建好的證書下載下來嗜傅,打開下載好的推送證書。則此時證書就添加到了鑰匙串中了檩赢,可以在我的證書中查看:
接下來需要導出這個證書吕嘀,一邊在parse云端使用它:
接下來就是創(chuàng)建真機調(diào)試允許的手機設備
仍然以圖說明(附上入口,按照要求填寫)
配置app推送開發(fā)的配置文件
接下來可以在自己的cxode中配置創(chuàng)建的證書和文件了
接下來用parse來仿照服務器做推送或者百度云推送贞瞒,把p12證書給到服務器偶房。parse官方網(wǎng)址:https://parse.com。 這個demo是按照pase云端進行的推送军浆,換可以用百度云推送或者蘋果自帶的推送服務
配置移動端接收消息的推送
首先應該配置移動應用程序支持推送的功能
定義一個常量判斷用戶應該接受什么樣的消息,注冊接受遠程消息的推送服務
let settings = UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
application.registerUserNotificationSettings(settings)
application.registerForRemoteNotifications()
注冊成功之后會調(diào)用棕洋,系統(tǒng)會自動調(diào)用didRegisterForRemoteNotificationsWithDeviceToken代理方法,通過這個方法的通知令牌為設備生成一個遠程消息的通知服務乒融。如果注冊失敗掰盘,則調(diào)用didFailToRegisterForRemoteNotificationsWithError代理方法。
核心代碼如下
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
let installation = PFInstallation.currentInstallation()
installation.setDeviceTokenFromData(deviceToken)//令牌存儲到parse云端
installation.saveInBackgroundWithBlock { (success:Bool, error:NSError?) -> Void in
print("Registeration successful? \(success)")
if error != nil {
print("Failed to register \(error?.localizedDescription)")
}
}
}
/*
當app收到遠程推送的消息會調(diào)用這個代理方法赞季,
第一個參數(shù)愧捕,標示的是application對象
第二個參數(shù),包含遠程消息的信息申钩,顯示的icon 聲音次绘,內(nèi)容,通知標示,自定義數(shù)據(jù)等
第三個參數(shù)邮偎,完成之后調(diào)用的閉包
*/
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
PFPush.handlePush(userInfo)//app處理消息的方式
completionHandler(UIBackgroundFetchResult.NewData)//執(zhí)行閉包函數(shù)
}
換需要設置一下應用程序的配置管跺,支持推送
接下來就可以在parse云端發(fā)送消息了,到此就可以利用parse發(fā)送簡單的推送消息了钢猛。
截下來可以利用parse通道發(fā)送推送伙菜,也可以在應用程序中手動推送消息。那怎樣在應用程序中發(fā)送推送
如何將消息手動推送到用戶訂閱的指定通道命迈,即通過通道來發(fā)送到用戶的手機上贩绕。
思路:設置parse云端推送消息的通道和本地發(fā)送推送消息的通道相同
實現(xiàn)一個demo:當點擊界面的button按鈕時,推送一個消息
//在注冊推送成功之后的代理里方法中設置用戶的通道壶愤,即標示parse 云通道淑倾。
installation.addUniqueObject("Swift", forKey: "channels")
點擊button時的操作:
@IBAction func sendButtonTapped(sender: AnyObject) {
if messageTextField.text!.isEmpty {
return
}
let data = ["alert": messageTextField.text!, "badge": "Increment"]
let channels = ["Swift"]
let push = PFPush()
push.setData(data)
push.setChannels(channels)//設置他的通道與云端相同
push.sendPushInBackgroundWithBlock { (success:Bool, error:NSError?) -> Void in
if success {
print("消息發(fā)送成功!")
}else {
print(error?.localizedDescription)
}
}
}
響應消息推送的交互征椒,即點擊推送消息后執(zhí)行的相關(guān)操作
通過一個點擊推送消息打開不同的視圖控制器為例進行說明娇哆,新增加2個視圖控制器:圖片視圖控制器和音頻控制視圖,當點擊的是圖片視圖的推送消息勃救,打開圖片視圖控制器碍讨,反之打開另一個
思路:根據(jù)云端(服務端)發(fā)送的json格式來判斷,讓其格式和客戶端溝通好蒙秒,發(fā)送一個約定好的json格式勃黍,根據(jù)返回的格式進行處理
這里就是返回一個字典格式{“photoid”:”111”,”alert”:””}或者是{“ve di did”:”111”,”alert”:””},根據(jù)返回的是photoid晕讲,還是video ID進行不同的跳轉(zhuǎn)
核心代碼
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
PFPush.handlePush(userInfo)
if let photoId = userInfo["photoId"] as? NSString {
print(photoId)
let mainStoryboard = UIStoryboard(name: "Main", bundle: nil)
let photoViewController = mainStoryboard.instantiateViewControllerWithIdentifier("PhotoViewController") as! PhotoViewController
let viewControllerNav = UINavigationController(rootViewController: photoViewController)
self.window?.rootViewController = viewControllerNav
}else if let videoId = userInfo["videoId"] as? NSString {
print(videoId)
let mainStoryboard = UIStoryboard(name: "Main", bundle: nil)
let videoViewController = mainStoryboard.instantiateViewControllerWithIdentifier("VideoViewController") as! VideoViewController
let viewControllerNav = UINavigationController(rootViewController: videoViewController)
self.window?.rootViewController = viewControllerNav
}else {
PFPush.handlePush(userInfo)
}
completionHandler(UIBackgroundFetchResult.NewData)
}