簡要:本系列文章講會對expo進行全面的介紹,本人從2017年6月份接觸expo以來,對expo的研究斷斷續續,一路走來將近10個月,廢話很少說,接下來你看到內容,講所有來與官網html
我猜去所有機翻+我的修改補充+demo測試的形式,對expo進行一次大補血!歡迎加入expo興趣學習交流羣:597732981node
【以前我寫過一些列關於expo和rn入門配置的東i西,你們能夠點擊這裏查看:從零學習rn開發】python
相關文章:react
Expo大做戰(一)--什麼是expo,如何安裝expo clinet和xde,xde如何使用ios
Expo大做戰(二)--expo的生命週期,expo社區交流方式,expo學習必備資源,開發使用expo時關注的一些問題git
Expo大做戰(三)--針對已經開發過react native項目開發人員有針對性的介紹了expo,expo的侷限性,開發時項目選型注意點等github
Expo大做戰(四)--快速用expo構建一個app,expo中的關鍵術語json
Expo大做戰(五)--expo中app.json 文件的配置信息後端
Expo大做戰(六)--expo開發模式,expo中exp命令行工具,expo中如何查看日誌log,expo中的調試方式react-native
Expo大做戰(七)--expo如何使用Genymotion模擬器
Expo大做戰(八)--expo中的publish以及expo中的link,對link這塊東西沒有詳細看,你們能夠來和我交流
接下來就開始擼碼
推送通知
推進通知是一個重要特性,由於「增加黑客」會說(Push Notifications are an important feature to, as 「growth hackers」 would say, ),保留並從新吸引用戶,並經過他們的注意力貨幣化等等。從個人角度來看,只需知道相關事件什麼時候發生在應用程序中即可方便使用,這樣我就能夠跳回來閱讀更多內容。讓咱們看看expo如何與作到這一點。擾流警報:這幾乎太簡單了(Spoiler alert: it’s almost too easy)。
注意:iOS和Android模擬器沒法接收推送通知。要測試它們,您須要使用真實設備。此外,在模擬器上調用Permissions.askAsync時,不管您是否選擇容許,它都會當即以「未肯定」狀態做爲狀態解決。
鏈接推送通知有三個主要步驟:發送用戶的Expo Push Token到您的服務器,當您想發送通知時使用令牌調用Expo的Push API,而且響應接收 and/or 選擇應用程序中的通知(例如跳轉到通知所指的特定屏幕)。
1.將用戶的Expo Push Token保存在服務器上爲了向其餘人發送推送通知,咱們須要瞭解他們的設備。固然,咱們本身知道咱們用戶的賬戶信息,但Apple,Google和Expo不瞭解您的專有用戶賬戶系統中與「Brent」相對應的設備。Expo負責經過expo推送令牌識別Apple和Google的設備,這種令牌每次在設備上安裝應用程序時都是惟一的。咱們所須要作的就是將此令牌發送到您的服務器,以便您能夠將其與用戶賬戶相關聯,並在未來用於發送推送通知。
import { Permissions, Notifications } from 'expo'; const PUSH_ENDPOINT = 'https://your-server.com/users/push-token';// async function registerForPushNotificationsAsync() { const { status: existingStatus } = await Permissions.getAsync( Permissions.NOTIFICATIONS ); let finalStatus = existingStatus; // only ask if permissions have not already been determined, because // iOS won't necessarily prompt the user a second time.
//僅詢問權限是否還沒有肯定,由於
// iOS不必定會再次提示用戶。 if (existingStatus !== 'granted') { // Android remote notification permissions are granted during the app // install, so this will only ask on iOS
//在應用程序期間授予Android遠程通知權限
//安裝,因此這隻會在iOS上詢問 const { status } = await Permissions.askAsync(Permissions.NOTIFICATIONS); finalStatus = status; } // Stop here if the user did not grant permissions
//若是用戶沒有授予權限,請在此中止 if (finalStatus !== 'granted') { return; } // Get the token that uniquely identifies this device
//獲取惟一標識此設備的令牌 let token = await Notifications.getExpoPushTokenAsync(); // POST the token to your backend server from where you can retrieve it to send push notifications.
//將令牌發佈到您的後端服務器,您能夠從中檢索該令牌以發送推送通知。
return fetch(PUSH_ENDPOINT, { method: 'POST', headers: { Accept: 'application/json', 'Content-Type': 'application/json', }, body: JSON.stringify({ token: { value: token, }, user: { username: 'Brent', }, }), }); }2.用用戶令牌調用Expo的Push API
推送通知必須來自某個地方,而且某個地方是您的服務器,可能(若是您想要,您能夠編寫一個命令行工具來發送它們,它們都是同樣的)。 當您準備發送推送通知時,請將expo推送令牌從用戶記錄中取出,並使用普通的舊HTTPS POST請求將其發送到Expo API。 咱們已經採起了幾種語言爲您打包:
exponent-server-sdk-node for Node.js. Maintained by the Expo team.
exponent-server-sdk-python for Python. Maintained by community developers.
exponent-server-sdk-ruby for Ruby. Unmaintained.
ExpoNotificationsBundle for Symfony. Maintained by SolveCrew.
若是您想以其餘語言實現它,請查看源代碼。
Expo推送通知工具對於在開發過程當中測試推送通知也頗有用。它可以讓您輕鬆地將測試通知發送到您的設備。
3.處理接收和/或選擇通知(Handle receiving and/or selecting the notification)
對於Android來講,這一步徹底是可選的 - 若是您的通知純粹是信息性的,而您在接收或選擇時不想處理它們,那麼您已經完成了。通知將出如今系統通知托盤中,正如您指望的那樣,點擊它們能夠打開/關閉應用程序。
對於iOS來講,處理推送通知是明智的,由於不然用戶將永遠看不到它們。系統通知列表中不會顯示在iOS上預先登陸應用程序時發出的通知。一般的解決方案是隻手動顯示通知。例如,若是您在Messenger for iOS上收到消息,請將應用程序預先安排好,但沒有打開此對話,您將看到通知從自定義通知用戶界面的屏幕頂部向下滑動。
幸運的是,處理推送通知對於Expo來講很簡單,您只需將偵聽器添加到Notifications對象。import React from 'react'; import { Notifications, } from 'expo'; import { Text, View, } from 'react-native'; import registerForPushNotificationsAsync from 'registerForPushNotificationsAsync'; export default class AppContainer extends React.Component { state = { notification: {}, }; componentWillMount() { registerForPushNotificationsAsync(); // Handle notifications that are received or selected while the app // is open. If the app was closed and then opened by tapping the // notification (rather than just tapping the app icon to open it), // this function will fire on the next tick after the app starts // with the notification data.
// 處理在應用程序中接收或選擇的通知
// 當他們在打開狀態。 若是應用程序已關閉,而後經過點擊打開應用程序
// 通知(而不是隻是點擊應用程序圖標打開它),
// 這個函數會在應用程序啓動後觸發下一個勾子
// 與通知數據。
this._notificationSubscription = Notifications.addListener(this._handleNotification); } _handleNotification = (notification) => { this.setState({notification: notification}); }; render() { return ( <View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}> <Text>Origin: {this.state.notification.origin}</Text> <Text>Data: {JSON.stringify(this.state.notification.data)}</Text> </View> ); } }通知處理時間
從上面的狀況來看,根據收到通知時的狀態,您的應用程序可以處理通知的時間並不徹底清楚。 詳細,請參閱下表:
HTTP / 2 API
雖然有幾種語言的服務器端SDK能夠幫助您發送推送通知,但您可能但願直接經過HTTP / 2 API發送請求。
- 發送通知
使用如下HTTP標頭向https://exp.host/--/api/v2/push/send發送POST請求:(Send a POST request to
https://exp.host/--/api/v2/push/send
with the following HTTP headers:)
accept: application/json accept-encoding: gzip, deflate content-type: application/json
此API目前不須要任何身份驗證。
這是一個使用cURL的「hello world」請求(用您本身的替換佔位符推送令牌):curl -H "Content-Type: application/json" -X POST https://exp.host/--/api/v2/push/send -d '{ "to": "ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]", "title":"hello", "body": "world" }'HTTP請求正文必須是JSON。 它能夠是單個消息對象或最多100個消息的數組。 咱們建議您在發送多個郵件時儘可能使用數組,以便有效減小須要向Expo服務器發送的請求數量。 這是發送兩條消息的示例請求主體:
[{ "to": "ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]", "sound": "default", "body": "Hello world!" }, { "to": "ExponentPushToken[yyyyyyyyyyyyyyyyyyyyyy]", "badge": 1, "body": "You've got mail" }]
//完整代碼這樣curl -H "Content-Type: application/json" -X POST https://exp.host/--/api/v2/push/send -d '[
{ "to": "ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]", "sound": "default", "body": "Hello world!" },
{ "to": "ExponentPushToken[yyyyyyyyyyyyyyyyyyyyyy]", "badge": 1, "body": "You've got mail" }]'
一旦成功,HTTP響應將是一個JSON對象,其數據字段是一個推送收據數組,每一個對應於請求中相應索引處的消息。 繼續上面的例子,這是一個成功的響應主體的樣子:
{ "data": [ {"status": "ok"}, {"status": "ok"} ] }當傳遞消息時出錯時,收據的狀態將爲「錯誤」,而且收據將包含有關錯誤的信息。 有關響應格式的更多信息記錄以下。
注意:即便收據顯示「OK」,也不能保證設備已收到信息; 「OK」表示咱們已成功將消息發送給Android或iOS推送通知服務。 例如,若是收件人設備處於關閉狀態,則Android或iOS推送通知服務將嘗試傳遞消息,但設備不必定會收到該消息。
若是您發送單個未包裝在數組中的消息,則數據字段將爲未包裝在數組中的推送收據。
消息格式每條消息必須是具備給定字段的JSON對象:
type PushMessage = { /** * An Expo push token specifying the recipient of this message.
* Expo推送令牌,指定此消息的收件人。 */ to: string, /** * A JSON object delivered to your app. It may be up to about 4KiB; the total * notification payload sent to Apple and Google must be at most 4KiB or else * you will get a "Message Too Big" error.
*一個JSON對象傳遞給你的應用程序。 它可能高達約4KiB; 總數
*發送給Apple和Google的通知有效負載必須最大爲4KiB或其餘
*你會獲得一個「消息太大」的錯誤。 */ data?: Object, /** * The title to display in the notification. Devices often display this in * bold above the notification body. Only the title might be displayed on * devices with smaller screens like Apple Watch.
*通知中顯示的標題。 設備常常在此顯示
*在通知主體上方加粗。 只有標題可能會顯示在上面
* Apple Watch等小屏幕設備。 */ title?: string, /** * The message to display in the notification
*要在通知中顯示的消息 */ body?: string, /** * A sound to play when the recipient receives this notification. Specify * "default" to play the device's default notification sound, or omit this * field to play no sound.
*收件人收到此通知時播放的聲音。指定
*「默認」播放設備的默認通知聲音,或省略此
*現場不播放聲音。 */ sound?: 'default' | null, /** * Time to Live: the number of seconds for which the message may be kept * around for redelivery if it hasn't been delivered yet. Defaults to 0. * * On Android, we make a best effort to deliver messages with zero TTL * immediately and do not throttle them * * This field takes precedence over `expiration` when both are specified.
*生存時間:能夠保留消息的秒數
*若是尚未交付,請從新發送。 默認爲0。
*
*在Android上,咱們盡最大努力以零TTL傳遞消息
*當即,不要扼殺他們
*
*這兩個字段在指定時優先於`expiration`。 */ ttl?: number, /** * A timestamp since the UNIX epoch specifying when the message expires. This * has the same effect as the `ttl` field and is just an absolute timestamp * instead of a relative time.
*自UNIX紀元指定消息到期時的時間戳。 這個
*與`ttl`字段具備相同的效果,而且只是一個絕對時間戳
*而不是相對時間。 */ expiration?: number, /** * The delivery priority of the message. Specify "default" or omit this field * to use the default priority on each platform, which is "normal" on Android * and "high" on iOS. * * On Android, normal-priority messages won't open network connections on * sleeping devices and their delivery may be delayed to conserve the battery. * High-priority messages are delivered immediately if possible and may wake * sleeping devices to open network connections, consuming energy. * * On iOS, normal-priority messages are sent at a time that takes into account * power considerations for the device, and may be grouped and delivered in * bursts. They are throttled and may not be delivered by Apple. High-priority * messages are sent immediately. Normal priority corresponds to APNs priority * level 5 and high priority to 10.
*消息的傳遞優先級。 指定「默認」或省略此字段
*在每一個平臺上使用默認優先級,在Android上爲「正常」
*和iOS上的「高」。
*
*在Android上,普通優先級消息不會打開網絡鏈接
*睡眠設備及其交付可能會延遲以節省電池。
*若是可能,高優先級消息會當即傳送並可能喚醒
*睡覺設備打開網絡鏈接,消耗能源。
*
*在iOS上,正常優先級消息會在考慮時發送
*設備的功耗考慮因素,可能會被分組和交付
*爆發。 它們受到限制,可能沒法由Apple提供。高優先級
*消息當即發送。 正常優先級對應於APN優先級
* 5級,高優先級爲10。 */ priority?: 'default' | 'normal' | 'high', // iOS-specific fields /** * Number to display in the badge on the app icon. Specify zero to clear the * badge.
*號碼顯示在應用程序圖標上的徽章中。 指定零來清除
*徽章。 */ badge?: number, }響應格式
響應是一個帶有兩個可選字段,數據和錯誤的JSON對象。 若是整個請求出現錯誤,那麼HTTP狀態碼將是4xx或5xx,而且錯誤將是一個錯誤對象數組(一般只有一個):
{ "errors": [{ "code": "INTERNAL_SERVER_ERROR", "message": "An unknown error occurred." }] }若是存在影響單個消息但不是整個請求的錯誤,則HTTP狀態代碼將爲200,錯誤字段將爲空,而且數據字段將包含描述錯誤的推送收據:
{ "data": [{ "status": "error", "message": "\"ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]\" is not a registered push notification recipient", "details": { "error": "DeviceNotRegistered" } }] }若是全部消息都已成功傳送到Android和iOS推送通知服務,則HTTP狀態碼也將爲200。
重要說明:特別是,查找具備錯誤字段的詳細信息對象。若是存在,它多是如下值之一:DeviceNotRegistered,MessageTooBig,MessageRateExceeded和InvalidCredentials。你應該像這樣處理這些錯誤:
DeviceNotRegistered:設備不能再接收推送通知,您應該中止向給定的expo推送令牌發送消息。
MessageTooBig:總通知有效負載太大。在Android和iOS上,總有效負載不得超過4096字節。
MessageRateExceeded:您發送消息的頻率過高,沒法給定設備。實施指數退避並慢慢重試發送消息。
InvalidCredentials:您的獨立應用程序的推送通知憑證無效(例如:您可能已撤銷它們)。運行exp build:ios -c爲iOS從新生成新推送通知憑證。
若是咱們沒法將消息傳遞給Android或iOS推送通知服務,則收據的詳細信息可能還包括特定於服務的信息。這主要用於調試和報告可能的錯誤給咱們。
下一張繼續介紹,這一篇主要介紹了:expo的消息推送機制, 歡迎你們關注個人微信公衆號,這篇文章是否被你們承認,個人衡量標準就是公衆號粉絲增加人數。歡迎你們轉載,但必須保留本人博客連接!