无星的RN学习之旅(四)——通信、持久化存储、iOS打包
說說最近項目的一些感想吧。
一、RN的創意
RN其實我覺得是一個很有創意的想法。不知道各位寫RN項目的時候,有沒有打開Xcode看過app的層級關系,我發現RN的這個想法,真的很有創意。
作為一名原生的開發,一直都是一個控制器上放一個View,然后在這個底層的View上添加UI控件,當需要一個新的視圖的時候,創建一個新的視圖控制器,再放新的View。
重點來了!RN并不是這么做的
RN是將App創建的時候生成的根視圖控制器,也就是底層的視圖控制器,作為根本,然后通過JS文件寫的視圖,也就是View,不停的增加在這個rootViewCtrl上,進行覆蓋替換。
二、Text的區別
或許有的兄弟還沒遇到這個坑,假如使用圖片或者其他背景色作為背景,往上添加Text標簽的時候,安卓默認為透明背景色,但是蘋果默認為灰白色。因此,在寫App的時候,需要在Text的樣式添加backgroundColor為transparent
backgroundColor:'transparent', 復制代碼三、原生與RN的通信
以前對原生與RN的通信不太了解。現在有了一些想法。
1.callback的通信方式,是會返回一個callback,這個callback是可以保存的,也就是說這個返回結果可以保存再用的。
2.promise,這個就比較有趣了,形象的說,這是個“通道”,RN的方法中,放一個promise的參數,在原生的module中,可以先定義幾個promise的回調,在不同的地方用。 舉個例子,我在RN中寫幾個方法。分別是:調用A方法,調用B方法,調用C方法,調用D方法。都是帶Promise的。
(lz是iOS開發,iOS中可以先聲明幾個變量)在iOS的module中,可以先聲明幾個promise的回調。比如先聲明
RCTPromiseResolveBlock resolveARCTPromiseResolveBlock resolveBRCTPromiseResolveBlock resolveCRCTPromiseResolveBlock resolveDRCTPromiseRejectBlock rejectA RCTPromiseRejectBlock rejectB RCTPromiseRejectBlock rejectC RCTPromiseRejectBlock rejectD 復制代碼這四個回調的函數可以先聲明,為什么會叫他通道,原因就是它其實可以這么理解,你將本來理解可能混亂的東西專一化,定義一個A方法成功的回調resolveA和一個A方法失敗的回調rejectA,這兩個回調只用于A方法。這么理解起來是不是清晰多了。因此可以理解為他是一個原生回調給RN的通信通道。
3.原生直接發消息,通過
[self sendEventWithName:@"EventReminder" body:@{@"name": eventName}]; 復制代碼這種方式注意了,請使用單例。
#pragma mark -- RCTEventEmitter類單例 + (id)allocWithZone:(NSZone *)zone {static RNBridge *sharedInstance = nil;static dispatch_once_t onceToken;dispatch_once(&onceToken, ^{sharedInstance = [super allocWithZone:zone];});return sharedInstance; } 復制代碼不然可能會報bridge為空。
詳情可見
無星的RN學習之旅(三)
四、RN與webView中html的通信
這塊我感覺有坑,但因為html不是強項,因此交給我們前端去做了。按官網的標準,使用onMessage()發送的消息在html中經常接受不到,不知道是為什么,希望有知道的旁友可以教教我=。=
五、debug是個坑!!!
在我使用真機調試的時候,經常報找不到資源,這時候需要將appdelegate的j什么什么的我給忘了- -明天去公司復制一下代碼。
jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil]; // jsCodeLocation = [NSURL URLWithString:@"http://自己的ip地址/index.ios.bundle?platform=ios&dev=true"]; 復制代碼需要把地址更換為ip地址,注意,debug模式,手機和電腦必須處于同一個網段下。差不多就是這個地方來回換,總能debug進去。
當點擊事件報錯的時候,注意一下飄紅信息,有的是debug模式的錯誤,忽略即可。 等明天上班再上圖。。。這個地方的圖有點難搞了。。。調試出錯了我再截圖回頭放上來
六、RN的持久化存儲,AsyncStorage
其實這一塊是我旁邊的安卓大佬寫的,我沒啥了解的,我要說的也不是如何存儲。。 我要說的是取出。先說下可能出現的應用場景:
在App初始化的時候,可能需要從本地取儲存的數據,iOS原生開發都是在沙盒里存儲,安卓也有對應的地方去存儲。但現在換RN了,可能有的老哥就不知道咋辦了。
其實不管那些亂七八糟的,RN的存儲也是基于原生去封裝的。就iOS來說,數據其實還是存在沙盒中,位于Documents文件夾下,會默認創建一個名為
RCTAsyncLocalStorage_V1 復制代碼的文件夾,其中有個默認名為
manifest.json 復制代碼的文件,因此就可以直接讀取出來。
這里給大家一個查看真機沙盒的方法:
顯示包內容,這樣就能下載真機的沙盒地址了不過這里要注意了,里面存的json,都不是正兒八經的json。。。會多很多的轉義符\和雙引號單引號。這里我的推薦做法是先用json解析成字典,在對其進行特殊符號的去除操作(明天上代碼- -)。如下:
#pragma mark -- JSON轉字典 +(NSDictionary *)jsonToDic:(NSString *)jsonString {NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];NSError *error = nil;id jsonObject = [NSJSONSerialization JSONObjectWithData:jsonDataoptions:NSJSONReadingAllowFragmentserror:&error];if (jsonObject != nil && error == nil){return jsonObject;}else{// 解析錯誤return nil;} }#pragma mark -- 去除RN存儲數據解析后的字符串含有 " 和 轉義符 +(NSString*)removeEscapeCharacter:(NSString*)string{ // 首先自己定義一個NSCharacterSet, 包含需要去除的特殊符號NSCharacterSet *set = [NSCharacterSet characterSetWithCharactersInString:@"@/:;()¥「」"、[]{}#%-*+=_\\|~<>$€^?'@#$%^&*()_+'\""];NSString *responseString = [string stringByTrimmingCharactersInSet:set];return responseString; } 復制代碼這是我能想到的最好辦法了,如果還有大佬有更高級的方法,麻煩告訴一聲~~
七:(偽)modal與alert沖突
為什么要說一個偽字呢,因為我發現,似乎不是沖突,而是在某些情況下modal的彈窗或者alert的彈窗會導致應用卡死,應該算是一個bug吧。就比如做跳轉webview的時候alert等情況下。。想了一下,這個地方的代碼不太好上,還是等各位自己遇到吧。。。。
八:debug產生的奇怪效果
1.原生的UI優先級會更高:當你某個效果跳轉展現原生UI的時候,你進行reload,你會發現應用重新刷新,但是頁面卻仍然是原生的頁面再最上層,這個原生的UI是不會進行reload的。。這時候只能重啟服務來重新打開app
2.modal視圖層在最上面。你也可以試試彈一個modal,reload也不會刷新這個modal。
九:iOS打包
cd到項目目錄下
然后手動在項目目錄下的iOS文件夾創建一個bundle文件夾
然后打開命令行,輸入
react-native bundle --entry-file index.ios.js --bundle-output ./ios/bundle/index.ios.jsbundle --platform ios --assets-dest ./ios/bundle --dev false 復制代碼執行完畢之后,你就發現bundle文件夾下就多了靜態資源文件。
但注意了,只有require導入的圖片資源會被放進來
靜態網頁的css樣式之類的,資源可能不會被放進來,這時候怎么辦?答案是手動導入。
暫時就想到這么多,等項目完成了再進行一下經驗完善~~~
2017-11-17
如果你使用上面的打包報錯,報錯信息為
error: options '--entry-file' missing 復制代碼請使用以下命令打包:
react-native bundle --platform ios --entry-file index.ios.js --bundle-output ./ios/bundle/index.ios.jsbundle --assets-dest ./ios/bundle --dev false 復制代碼新版本0.5版本以上(沒有index.ios.js的)用下面這個,其實就是改了一丟丟
react-native bundle --entry-file index.js --bundle-output ./ios/bundle/index.jsbundle --platform ios --assets-dest ./ios/bundle --dev false 復制代碼轉載請說明來自:www.jianshu.com/u/fef769674…
無星的RN學習之旅(一)-環境安裝以及新建項目
無星的RN學習之旅(二)-RN與原生的通信
無星的RN學習之旅(三)-bridge is not set.
無星的RN學習之旅(五)-關于react-navigation多層級頁面返回時,去掉逐層推出動畫
無星的RN學習之旅(六)-第三方App跳轉,蘋果商店跳轉,loading框
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的无星的RN学习之旅(四)——通信、持久化存储、iOS打包的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微信小程序 - 文字收缩与展开
- 下一篇: 模态框的封装