無星的RN學習之旅(四)——通訊、持久化存儲、iOS打包

說說最近項目的一些感想吧。css

1、RN的創意

RN其實我以爲是一個頗有創意的想法。不知道各位寫RN項目的時候,有沒有打開Xcode看過app的層級關係,我發現RN的這個想法,真的頗有創意。html

做爲一名原生的開發,一直都是一個控制器上放一個View,而後在這個底層的View上添加UI控件,當須要一個新的視圖的時候,建立一個新的視圖控制器,再放新的View。前端

重點來了!RN並非這麼作的

根視圖.png

RN是將App建立的時候生成的根視圖控制器,也就是底層的視圖控制器,做爲根本,而後經過JS文件寫的視圖,也就是View,不停的增長在這個rootViewCtrl上,進行覆蓋替換。react

2、Text的區別

或許有的兄弟還沒遇到這個坑,假如使用圖片或者其餘背景色做爲背景,往上添加Text標籤的時候,安卓默認爲透明背景色,可是蘋果默認爲灰白色。所以,在寫App的時候,須要在Text的樣式添加backgroundColor爲transparentios

backgroundColor:'transparent',
複製代碼

3、原生與RN的通訊

之前對原生與RN的通訊不太瞭解。如今有了一些想法。web

1.callback的通訊方式,是會返回一個callback,這個callback是能夠保存的,也就是說這個返回結果能夠保存再用的。json

2.promise,這個就比較有趣了,形象的說,這是個「通道」,RN的方法中,放一個promise的參數,在原生的module中,能夠先定義幾個promise的回調,在不一樣的地方用。 舉個例子,我在RN中寫幾個方法。分別是:調用A方法,調用B方法,調用C方法,調用D方法。都是帶Promise的。react-native

promise.png

(lz是iOS開發,iOS中能夠先聲明幾個變量)在iOS的module中,能夠先聲明幾個promise的回調。好比先聲明promise

RCTPromiseResolveBlock resolveA
 RCTPromiseResolveBlock resolveB
 RCTPromiseResolveBlock resolveC
 RCTPromiseResolveBlock resolveD

RCTPromiseRejectBlock rejectA
RCTPromiseRejectBlock rejectB
RCTPromiseRejectBlock rejectC
RCTPromiseRejectBlock rejectD
複製代碼

這四個回調的函數能夠先聲明,爲何會叫他通道,緣由就是它其實能夠這麼理解,你將原本理解可能混亂的東西專注化,定義一個A方法成功的回調resolveA和一個A方法失敗的回調rejectA,這兩個回調只用於A方法。這麼理解起來是否是清晰多了。所以能夠理解爲他是一個原生回調給RN的通訊通道。bash

3.原生直接發消息,經過

[self sendEventWithName:@"EventReminder" body:@{@"name": eventName}];
複製代碼

這種方式注意了,請使用單例。

單例.png

#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學習之旅(三)

4、RN與webView中html的通訊

這塊我感受有坑,但由於html不是強項,所以交給咱們前端去作了。按官網的標準,使用onMessage()發送的消息在html中常常接受不到,不知道是爲何,但願有知道的旁友能夠教教我=。=

5、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模式的錯誤,忽略便可。 等明天上班再上圖。。。這個地方的圖有點難搞了。。。調試出錯了我再截圖回頭放上來

6、RN的持久化存儲,AsyncStorage

其實這一塊是我旁邊的安卓大佬寫的,我沒啥瞭解的,我要說的也不是如何存儲。。 我要說的是取出。先說下可能出現的應用場景:

在App初始化的時候,可能須要從本地取儲存的數據,iOS原生開發都是在沙盒裏存儲,安卓也有對應的地方去存儲。但如今換RN了,可能有的老哥就不知道咋辦了。

其實無論那些亂七八糟的,RN的存儲也是基於原生去封裝的。就iOS來講,數據其實仍是存在沙盒中,位於Documents文件夾下,會默認建立一個名爲

RCTAsyncLocalStorage_V1
複製代碼

的文件夾,其中有個默認名爲

manifest.json
複製代碼

的文件,所以就能夠直接讀取出來。

這裏給你們一個查看真機沙盒的方法:

1.png
2
3

4.png
顯示包內容,這樣就能下載真機的沙盒地址了

不過這裏要注意了,裏面存的json,都不是正兒八經的json。。。會多不少的轉義符\和雙引號單引號。這裏個人推薦作法是先用json解析成字典,在對其進行特殊符號的去除操做(明天上代碼- -)。以下:

#pragma mark -- JSON轉字典
+(NSDictionary *)jsonToDic:(NSString *)jsonString {
  NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
  NSError *error = nil;
  id jsonObject = [NSJSONSerialization JSONObjectWithData:jsonData
                                                  options:NSJSONReadingAllowFragments
                                                    error:&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框

相關文章
相關標籤/搜索