iOS10中PushNotification大改革(未完待續(xù)...)

PushNotification發(fā)展歷史

iOS 10 中,把以前雜亂的和通知相關(guān)的 API 都統(tǒng)一了,現(xiàn)在開(kāi)發(fā)者可以使用獨(dú)立的UserNotifications.framework來(lái)集中管理和使用 iOS 系統(tǒng)中通知的功能护盈。在此基礎(chǔ)上勇皇,Apple 還增加了撤回單條通知,更新已展示通知化漆,中途修改通知內(nèi)容抖誉,在通知中展示圖片視頻殊轴,自定義通知 UI 等一系列新功能衰倦,非常強(qiáng)大袒炉。

對(duì)于開(kāi)發(fā)者來(lái)說(shuō),相較于之前版本樊零,iOS 10 提供了一套非常易用的通知處理接口我磁,是 SDK 的一次重大重構(gòu)。而之前的絕大部分通知相關(guān) API 都已經(jīng)被標(biāo)為棄用 (deprecated)驻襟。下面我們來(lái)回顧一下PushNotification的發(fā)展歷程夺艰。

iOS 3 - 引入推送通知:ApplicationregisterForRemoteNotificationTypesUIApplicationDelegateapplication(_:didRegisterForRemoteNotificationsWithDeviceToken:),application(_:didReceiveRemoteNotification:)

iOS 4 - 引入本地通知scheduleLocalNotification沉衣,presentLocalNotificationNow:郁副,application(_:didReceive:)

iOS 5 - 加入通知中心頁(yè)面
iOS 6 - 通知中心頁(yè)面與 iCloud 同步

iOS 7 - 后臺(tái)靜默推送application(_:didReceiveRemoteNotification:fetchCompletionHandle:)

iOS 8 - 重新設(shè)計(jì) Notification權(quán)限請(qǐng)求,Actionable 通知registerUserNotificationSettings(_:)豌习,UIUserNotificationActionUIUserNotificationCategory存谎,application(_:handleActionWithIdentifier:forRemoteNotification:completionHandler:)

iOS 9 - Text Input action,基于 HTTP/2 的推送請(qǐng)求UIUserNotificationActionBehavior肥隆,全新的 Provider API 等

現(xiàn)狀分析

有點(diǎn)暈既荚,不是么?一個(gè)開(kāi)發(fā)者很難在不借助于文檔的幫助下區(qū)分 application(_:didReceiveRemoteNotification:)application(_:didReceiveRemoteNotification:fetchCompletionHandle:)栋艳,新入行的開(kāi)發(fā)者也不可能明白 registerForRemoteNotificationTypesregisterUserNotificationSettings(_:)之間是不是有什么關(guān)系恰聘,Remote 和 Local Notification 除了在初始化方式之外那些細(xì)微的區(qū)別也讓人抓狂,而很多 API 都被隨意地放在了 UIApplication 或者 UIApplicationDelegate 中吸占。除此之外晴叨,應(yīng)用已經(jīng)在前臺(tái)時(shí),遠(yuǎn)程推送是無(wú)法直接顯示的矾屯,要先捕獲到遠(yuǎn)程來(lái)的通知篙螟,然后再發(fā)起一個(gè)本地通知才能完成顯示。更讓人郁悶的是问拘,應(yīng)用在運(yùn)行時(shí)和非運(yùn)行時(shí)捕獲通知的路徑還不一致遍略。雖然這些種種問(wèn)題都是由一定歷史原因造成的惧所,但不可否認(rèn),正是混亂的組織方式和之前版本的考慮不周绪杏,使得 iOS 通知方面的開(kāi)發(fā)一直稱不上“讓人愉悅”下愈,甚至有不少“壞代碼”的味道。

另一方面蕾久,現(xiàn)在的通知功能相對(duì)還是簡(jiǎn)單势似,我們能做的只是本地或者遠(yuǎn)程發(fā)起通知,然后顯示給用戶僧著。雖然 iOS 8 和 9 中添加了按鈕和文本來(lái)進(jìn)行交互履因,但是已發(fā)出的通知不能更新,通知的內(nèi)容也只是在發(fā)起時(shí)唯一確定盹愚,而這些內(nèi)容也只能是簡(jiǎn)單的文本栅迄。 想要在現(xiàn)有基礎(chǔ)上擴(kuò)展通知的功能,勢(shì)必會(huì)讓原本就盤(pán)根錯(cuò)節(jié)的 API 更加難以理解皆怕。

在 iOS 10 中新加入 UserNotifications 框架毅舆,可以說(shuō)是 iOS SDK 發(fā)展到現(xiàn)在的最大規(guī)模的一次重構(gòu)。新版本里通知的相關(guān)功能被提取到了單獨(dú)的框架愈腾,通知也不再區(qū)分類型憋活,而有了更統(tǒng)一的行為。我們接下來(lái)就將由淺入深地解析這個(gè)重構(gòu)后的框架的使用方式虱黄。

UserNotifications 框架解析

基本流程

iOS 10 中通知相關(guān)的操作遵循下面的流程:


首先你需要向用戶請(qǐng)求推送權(quán)限悦即,然后發(fā)送通知。對(duì)于發(fā)送出的通知橱乱,如果你的應(yīng)用位于后臺(tái)或者沒(méi)有運(yùn)行的話辜梳,系統(tǒng)將通過(guò)用戶允許的方式 (彈窗,橫幅仅醇,或者是在通知中心) 進(jìn)行顯示冗美。如果你的應(yīng)用已經(jīng)位于前臺(tái)正在運(yùn)行,你可以自行決定要不要顯示這個(gè)通知析二。最后粉洼,如果你希望用戶點(diǎn)擊通知能有打開(kāi)應(yīng)用以外的額外功能的話,你也需要進(jìn)行處理叶摄。

權(quán)限申請(qǐng)

iOS 8 之前属韧,本地推送 UILocalNotification 和遠(yuǎn)程推送 Remote Notification 是區(qū)分對(duì)待的,應(yīng)用只需要在進(jìn)行遠(yuǎn)程推送時(shí)獲取用戶同意蛤吓。iOS 8 對(duì)這一行為進(jìn)行了規(guī)范宵喂,因?yàn)闊o(wú)論是本地推送還是遠(yuǎn)程推送,其實(shí)在用戶看來(lái)表現(xiàn)是一致的会傲,都是打斷用戶的行為锅棕。因此從 iOS 8 開(kāi)始拙泽,這兩種通知都需要申請(qǐng)權(quán)限。iOS 10 里進(jìn)一步消除了本地通知和推送通知的區(qū)別裸燎。向用戶申請(qǐng)通知權(quán)限非常簡(jiǎn)單:

UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) {
    granted, error in
    if granted {
        // 用戶允許進(jìn)行通知
    }
}

當(dāng)然顾瞻,在使用 UN 開(kāi)頭的 API 的時(shí)候,不要忘記導(dǎo)入 UserNotifications 框架:
import UserNotifications
第一次調(diào)用這個(gè)方法時(shí)德绿,會(huì)彈出一個(gè)系統(tǒng)彈窗荷荤。


要注意的是,一旦用戶拒絕了這個(gè)請(qǐng)求移稳,再次調(diào)用該方法也不會(huì)再進(jìn)行彈窗蕴纳,想要應(yīng)用有機(jī)會(huì)接收到通知的話,用戶必須自行前往系統(tǒng)的設(shè)置中為你的應(yīng)用打開(kāi)通知个粱,如果不是殺手級(jí)應(yīng)用古毛,想讓用戶主動(dòng)去在茫茫多 app 中找到你的那個(gè)并專門為你開(kāi)啟通知,往往是不可能的几蜻。因此喇潘,在合適的時(shí)候彈出請(qǐng)求窗体斩,在請(qǐng)求權(quán)限前預(yù)先進(jìn)行說(shuō)明梭稚,以此增加通過(guò)的概率應(yīng)該是開(kāi)發(fā)者和策劃人員的必修課。相比與直接簡(jiǎn)單粗暴地在啟動(dòng)的時(shí)候就進(jìn)行彈窗絮吵,耐心誘導(dǎo)會(huì)是更明智的選擇弧烤。

一旦用戶同意后,你就可以在應(yīng)用中發(fā)送本地通知了蹬敲。不過(guò)如果你通過(guò)服務(wù)器發(fā)送遠(yuǎn)程通知的話暇昂,還需要多一個(gè)獲取用戶 token 的操作。你的服務(wù)器可以使用這個(gè) token 將用向 Apple Push Notification 的服務(wù)器提交請(qǐng)求伴嗡,然后 APNs 通過(guò) token 識(shí)別設(shè)備和應(yīng)用急波,將通知推給用戶。
提交 token 請(qǐng)求和獲得 token 的回調(diào)是現(xiàn)在“唯二”不在新框架中的 API瘪校。我們使用 UIApplicationregisterForRemoteNotifications 來(lái)注冊(cè)遠(yuǎn)程通知澄暮,在 AppDelegateapplication(_:didRegisterForRemoteNotificationsWithDeviceToken)中獲取用戶 token:

// 向 APNS 請(qǐng)求 token:
UIApplication.shared.registerForRemoteNotifications()

// AppDelegate.swift
 func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    let tokenString = deviceToken.hexString
    print("Get Push token: \(tokenString)")
}

獲取得到的deviceToken 是一個(gè) Data 類型,為了方便使用和傳遞阱扬,我們一般會(huì)選擇將它轉(zhuǎn)換為一個(gè)字符串泣懊。Swift 3 中可以使用下面的 Data 擴(kuò)展來(lái)構(gòu)造出適合傳遞給 Apple 的字符串:

extension Data {
    var hexString: String {
        return withUnsafeBytes {(bytes: UnsafePointer<UInt8>) -> String in
            let buffer = UnsafeBufferPointer(start: bytes, count: count)
            return buffer.map {String(format: "%02hhx", $0)}.reduce("", { $0 + $1 })
        }
    }
}
權(quán)限設(shè)置

用戶可以在系統(tǒng)設(shè)置中修改你的應(yīng)用的通知權(quán)限,除了打開(kāi)和關(guān)閉全部通知權(quán)限外麻惶,用戶也可以限制你的應(yīng)用只能進(jìn)行某種形式的通知顯示馍刮,比如只允許橫幅而不允許彈窗及通知中心顯示等。一般來(lái)說(shuō)你不應(yīng)該對(duì)用戶的選擇進(jìn)行干涉窃蹋,但是如果你的應(yīng)用確實(shí)需要某種特定場(chǎng)景的推送的話卡啰,你可以對(duì)當(dāng)前用戶進(jìn)行的設(shè)置進(jìn)行檢查:

UNUserNotificationCenter.current().getNotificationSettings {
    settings in 
    print(settings.authorizationStatus) // .authorized | .denied | .notDetermined
    print(settings.badgeSetting) // .enabled | .disabled | .notSupported
    // etc...
}
發(fā)送通知

UserNotifications中對(duì)通知進(jìn)行了統(tǒng)一静稻。我們通過(guò)通知的內(nèi)容 (UNNotificationContent),發(fā)送的時(shí)機(jī)(UNNotificationTrigger) 以及一個(gè)發(fā)送通知的 String 類型的標(biāo)識(shí)符匈辱,來(lái)生成一個(gè) UNNotificationRequest 類型的發(fā)送請(qǐng)求姊扔。最后,我們將這個(gè)請(qǐng)求添加到 UNUserNotificationCenter.current()中梅誓,就可以等待通知到達(dá)了:

// 1. 創(chuàng)建通知內(nèi)容
let content = UNMutableNotificationContent()
content.title = "Time Interval Notification"
content.body = "My first notification"

// 2. 創(chuàng)建發(fā)送觸發(fā)
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false)

// 3. 發(fā)送請(qǐng)求標(biāo)識(shí)符
let requestIdentifier = "com.onevcat.usernotification.myFirstNotification"

// 4. 創(chuàng)建一個(gè)發(fā)送請(qǐng)求
let request = UNNotificationRequest(identifier: requestIdentifier, content: content, trigger: trigger)

// 將請(qǐng)求添加到發(fā)送中心
UNUserNotificationCenter.current().add(request) { error in
    if error == nil {
        print("Time Interval Notification scheduled: \(requestIdentifier)")
    }
}

iOS 10 中通知不僅支持簡(jiǎn)單的一行文字恰梢,你還可以添加 titlesubtitle,來(lái)用粗體字的形式強(qiáng)調(diào)通知的目的梗掰。對(duì)于遠(yuǎn)程推送嵌言,iOS 10 之前一般只含有消息的推送 payload 是這樣的:

 {
   "aps":{
     "alert":"Test",
     "sound":"default",
     "badge":1
   }
 }

如果我們想要加入titlesubtitle 的話,則需要將 alert從字符串換為字典及穗,新的 payload 是:

 {
   "aps":{
     "alert":{
       "title":"I am title",
       "subtitle":"I am subtitle",
       "body":"I am body"
     },
     "sound":"default",
     "badge":1
   }
 }

好消息是摧茴,后一種字典的方法其實(shí)在 iOS 8.2 的時(shí)候就已經(jīng)存在了。雖然當(dāng)時(shí)title 只是用在 Apple Watch 上的埂陆,但是設(shè)置好body 的話在 iOS 上還是可以顯示的苛白,所以針對(duì) iOS 10 添加標(biāo)題時(shí)是可以保證前向兼容的。
另外焚虱,如果要進(jìn)行本地化對(duì)應(yīng)购裙,在設(shè)置這些內(nèi)容文本時(shí),本地可以使用String.localizedUserNotificationString(forKey: "your_key", arguments: [])
的方式來(lái)從 Localizable.strings 文件中取出本地化字符串鹃栽,而遠(yuǎn)程推送的話躏率,也可以在payloadalert中使用loc-key
或者title-loc-key
來(lái)進(jìn)行指定。關(guān)于 payload 中的 key民鼓,可以參考這篇文檔薇芝。

2.觸發(fā)器是只對(duì)本地通知而言的,遠(yuǎn)程推送的通知的話默認(rèn)會(huì)在收到后立即顯示》峒危現(xiàn)在UserNotifications 框架中提供了三種觸發(fā)器夯到,分別是:在一定時(shí)間后觸發(fā) UNTimeIntervalNotificationTrigger,在某月某日某時(shí)觸發(fā)UNCalendarNotificationTrigger以及在用戶進(jìn)入或是離開(kāi)某個(gè)區(qū)域時(shí)觸發(fā)UNLocationNotificationTrigger饮亏。

3.請(qǐng)求標(biāo)識(shí)符可以用來(lái)區(qū)分不同的通知請(qǐng)求耍贾,在將一個(gè)通知請(qǐng)求提交后,通過(guò)特定 API 我們能夠使用這個(gè)標(biāo)識(shí)符來(lái)取消或者更新這個(gè)通知克滴。我們將在稍后再提到具體用法逼争。

4.在新版本的通知框架中,Apple 借用了一部分網(wǎng)絡(luò)請(qǐng)求的概念劝赔。我們組織并發(fā)送一個(gè)通知請(qǐng)求誓焦,然后將這個(gè)請(qǐng)求提交給 UNUserNotificationCenter 進(jìn)行處理。我們會(huì)在 delegate 中接收到這個(gè)通知請(qǐng)求對(duì)應(yīng)的 response,另外我們也有機(jī)會(huì)在應(yīng)用的 extension 中對(duì)request進(jìn)行處理杂伟。我們?cè)诮酉聛?lái)的章節(jié)會(huì)看到更多這方面的內(nèi)容移层。

在提交通知請(qǐng)求后,我們鎖屏或者將應(yīng)用切到后臺(tái)赫粥,并等待設(shè)定的時(shí)間后观话,就能看到我們的通知出現(xiàn)在通知中心或者屏幕橫幅了:


關(guān)于最基礎(chǔ)的通知發(fā)送,可以參考DemoTimeIntervalViewController
的內(nèi)容越平。

取消和更新

在創(chuàng)建通知請(qǐng)求時(shí)频蛔,我們已經(jīng)指定了標(biāo)識(shí)符。這個(gè)標(biāo)識(shí)符可以用來(lái)管理通知秦叛。在 iOS 10 之前,我們很難取消掉某一個(gè)特定的通知挣跋,也不能主動(dòng)移除或者更新已經(jīng)展示的通知。想象一下你需要推送用戶賬戶內(nèi)的余額變化情況避咆,多次的余額增減或者變化很容易讓用戶十分困惑 - 到底哪條通知才是最正確的舟肉?又或者在推送一場(chǎng)比賽的比分時(shí)路媚,頻繁的通知必然導(dǎo)致用戶通知中心數(shù)量爆炸,而大部分中途的比分對(duì)于用戶來(lái)說(shuō)只是噪音磷籍。

iOS 10 中适荣,UserNotifications 框架提供了一系列管理通知的 API,你可以做到:

  • 取消還未展示的通知
  • 更新還未展示的通知
  • 移除已經(jīng)展示過(guò)的通知
  • 更新已經(jīng)展示過(guò)的通知

其中關(guān)鍵就在于在創(chuàng)建請(qǐng)求時(shí)使用同樣的標(biāo)識(shí)符弛矛。
比如,從通知中心中移除一個(gè)展示過(guò)的通知:

let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 3, repeats: false)
let identifier = "com.onevcat.usernotification.notificationWillBeRemovedAfterDisplayed"
let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger)

UNUserNotificationCenter.current().add(request) { error in
    if error != nil {
        print("Notification request added: \(identifier)")
    }
}

delay(4) {
    print("Notification request removed: \(identifier)")
    UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [identifier])
}

類似地丈氓,我們可以使用 removePendingNotificationRequests,來(lái)取消還未展示的通知請(qǐng)求万俗。對(duì)于更新通知,不論是否已經(jīng)展示闰歪,都和一開(kāi)始添加請(qǐng)求時(shí)一樣,再次將請(qǐng)求提交給 UNUserNotificationCenter 即可:

// let request: UNNotificationRequest = ...
UNUserNotificationCenter.current().add(request) { error in
    if error != nil {
        print("Notification request added: \(identifier)")
    }
}

delay(2) {
    let newTrigger = UNTimeIntervalNotificationTrigger(timeInterval: 1, repeats: false)
    
    // Add new request with the same identifier to update a notification.
    let newRequest = UNNotificationRequest(identifier: identifier, content:newContent, trigger: newTrigger)
    UNUserNotificationCenter.current().add(newRequest) { error in
        if error != nil {
            print("Notification request updated: \(identifier)")
        }
    }
}

遠(yuǎn)程推送可以進(jìn)行通知的更新库倘,在使用 Provider API 向 APNs 提交請(qǐng)求時(shí)论矾,在 HTTP/2 的 header 中apns-collapse-id
key 的內(nèi)容將被作為該推送的標(biāo)識(shí)符進(jìn)行使用杆勇。多次推送同一標(biāo)識(shí)符的通知即可進(jìn)行更新。
對(duì)應(yīng)本地的removeDeliveredNotifications
蚜退,現(xiàn)在還不能通過(guò)類似的方式,向 APNs 發(fā)送一個(gè)包含 collapse id 的 DELETE 請(qǐng)求來(lái)刪除已經(jīng)展示的推送钻注,APNs 服務(wù)器并不接受一個(gè) DELETE 請(qǐng)求传黄。不過(guò)從技術(shù)上來(lái)說(shuō) Apple 方面應(yīng)該不存在什么問(wèn)題,我們可以拭目以待《涌埽現(xiàn)在如果想要消除一個(gè)遠(yuǎn)程推送膘掰,可以選擇使用后臺(tái)靜默推送的方式來(lái)從本地發(fā)起一個(gè)刪除通知的調(diào)用。關(guān)于后臺(tái)推送的部分佳遣,可以參考王巍之前的一篇關(guān)于 iOS7 中的多任務(wù)的文章识埋。

關(guān)于通知管理,可以參考 Demo 中 ManagementViewController
的內(nèi)容零渐。為了能夠簡(jiǎn)單地測(cè)試遠(yuǎn)程推送窒舟,一般我們都會(huì)用一些方便發(fā)送通知的工具,Knuff 就是其中之一诵盼。我也為 Knuff 添加了apns-collapse-id
的支持惠豺,你可以在這個(gè) fork 的 repo 或者是原 repo 的 pull request 中找到相關(guān)信息。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末风宁,一起剝皮案震驚了整個(gè)濱河市洁墙,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌戒财,老刑警劉巖热监,帶你破解...
    沈念sama閱讀 218,640評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異饮寞,居然都是意外死亡孝扛,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,254評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門幽崩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)苦始,“玉大人,你說(shuō)我怎么就攤上這事慌申∧把。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,011評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)柠贤。 經(jīng)常有香客問(wèn)我香浩,道長(zhǎng),這世上最難降的妖魔是什么臼勉? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,755評(píng)論 1 294
  • 正文 為了忘掉前任邻吭,我火速辦了婚禮,結(jié)果婚禮上宴霸,老公的妹妹穿的比我還像新娘囱晴。我一直安慰自己,他們只是感情好畸写,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,774評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布氓扛。 她就那樣靜靜地躺著,像睡著了一般千所。 火紅的嫁衣襯著肌膚如雪蒜埋。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,610評(píng)論 1 305
  • 那天待错,我揣著相機(jī)與錄音火俄,去河邊找鬼础倍。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的犹菇。 我是一名探鬼主播揭芍,決...
    沈念sama閱讀 40,352評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼筷转!你這毒婦竟也來(lái)了悬而?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,257評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤箕别,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后喘漏,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體奸柬,經(jīng)...
    沈念sama閱讀 45,717評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡篓足,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,894評(píng)論 3 336
  • 正文 我和宋清朗相戀三年栈拖,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了没陡。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,021評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡贴彼,死狀恐怖器仗,靈堂內(nèi)的尸體忽然破棺而出童番,到底是詐尸還是另有隱情,我是刑警寧澤轨香,帶...
    沈念sama閱讀 35,735評(píng)論 5 346
  • 正文 年R本政府宣布臂容,位于F島的核電站,受9級(jí)特大地震影響脓杉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜尿赚,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,354評(píng)論 3 330
  • 文/蒙蒙 一吼畏、第九天 我趴在偏房一處隱蔽的房頂上張望嘁灯。 院中可真熱鬧,春花似錦性雄、人聲如沸羹奉。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,936評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)细卧。三九已至筒占,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間止邮,已是汗流浹背奏窑。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,054評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工良哲, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人滑沧。 一個(gè)月前我還...
    沈念sama閱讀 48,224評(píng)論 3 371
  • 正文 我出身青樓巍实,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親令漂。 傳聞我的和親對(duì)象是個(gè)殘疾皇子丸边,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,974評(píng)論 2 355

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

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)纬朝、插件骄呼、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,105評(píng)論 4 62
  • 極光推送: 1.JPush當(dāng)前版本是1.8.2,其SDK的開(kāi)發(fā)除了正常的功能完善和擴(kuò)展外也緊隨蘋(píng)果官方的步伐隅茎,SD...
    Isspace閱讀 6,719評(píng)論 10 16
  • 努力吧吹鼓手 我們圍繞你的身邊 世界就在你的手間 Photo by Dnyaneshwar Vaidya
    憨憨爹閱讀 179評(píng)論 0 0
  • 一覺(jué)睡醒辟犀,不知身處何方堂竟,倍感孤獨(dú)臣咖; 回顧過(guò)往歷程 好像從未真正踏入社會(huì),不明人情世故 從剛來(lái)珠海便結(jié)識(shí)了韋家人開(kāi)始...
    Lisa姚閱讀 191評(píng)論 0 0
  • 今天是第二天了疚漆!時(shí)差沒(méi)倒過(guò)來(lái)刁赦!加上飛機(jī)上的疲憊,估計(jì)得幾天恢復(fù)了丸升!早上10點(diǎn)多和兒子起床牺氨,煎了個(gè)雞蛋墩剖,炒了培根夷狰,然...
    妮兒_ebf9閱讀 156評(píng)論 0 1