說說最近項(xiàng)目的一些感想吧。
一递沪、RN的創(chuàng)意
RN其實(shí)我覺得是一個(gè)很有創(chuàng)意的想法豺鼻。不知道各位寫RN項(xiàng)目的時(shí)候,有沒有打開Xcode看過app的層級關(guān)系款慨,我發(fā)現(xiàn)RN的這個(gè)想法儒飒,真的很有創(chuàng)意。
作為一名原生的開發(fā)檩奠,一直都是一個(gè)控制器上放一個(gè)View桩了,然后在這個(gè)底層的View上添加UI控件,當(dāng)需要一個(gè)新的視圖的時(shí)候埠戳,創(chuàng)建一個(gè)新的視圖控制器井誉,再放新的View。
重點(diǎn)來了乞而!RN并不是這么做的
RN是將App創(chuàng)建的時(shí)候生成的根視圖控制器琼富,也就是底層的視圖控制器套耕,作為根本,然后通過JS文件寫的視圖,也就是View嘴瓤,不停的增加在這個(gè)rootViewCtrl上斋竞,進(jìn)行覆蓋替換益眉。
二陕壹、Text的區(qū)別
或許有的兄弟還沒遇到這個(gè)坑,假如使用圖片或者其他背景色作為背景共郭,往上添加Text標(biāo)簽的時(shí)候祠丝,安卓默認(rèn)為透明背景色疾呻,但是蘋果默認(rèn)為灰白色。因此写半,在寫App的時(shí)候岸蜗,需要在Text的樣式添加backgroundColor為transparent
backgroundColor:'transparent',
三、原生與RN的通信
以前對原生與RN的通信不太了解〉現(xiàn)在有了一些想法璃岳。
1.callback的通信方式,是會返回一個(gè)callback悔捶,這個(gè)callback是可以保存的铃慷,也就是說這個(gè)返回結(jié)果可以保存再用的。
2.promise蜕该,這個(gè)就比較有趣了犁柜,形象的說,這是個(gè)“通道”堂淡,RN的方法中馋缅,放一個(gè)promise的參數(shù),在原生的module中淤齐,可以先定義幾個(gè)promise的回調(diào)股囊,在不同的地方用袜匿。
舉個(gè)例子更啄,我在RN中寫幾個(gè)方法。分別是:調(diào)用A方法居灯,調(diào)用B方法祭务,調(diào)用C方法,調(diào)用D方法怪嫌。都是帶Promise的义锥。
(lz是iOS開發(fā),iOS中可以先聲明幾個(gè)變量)在iOS的module中岩灭,可以先聲明幾個(gè)promise的回調(diào)拌倍。比如先聲明
RCTPromiseResolveBlock resolveA
RCTPromiseResolveBlock resolveB
RCTPromiseResolveBlock resolveC
RCTPromiseResolveBlock resolveD
RCTPromiseRejectBlock rejectA
RCTPromiseRejectBlock rejectB
RCTPromiseRejectBlock rejectC
RCTPromiseRejectBlock rejectD
這四個(gè)回調(diào)的函數(shù)可以先聲明,為什么會叫他通道噪径,原因就是它其實(shí)可以這么理解柱恤,你將本來理解可能混亂的東西專一化,定義一個(gè)A方法成功的回調(diào)resolveA和一個(gè)A方法失敗的回調(diào)rejectA找爱,這兩個(gè)回調(diào)只用于A方法梗顺。這么理解起來是不是清晰多了。因此可以理解為他是一個(gè)原生回調(diào)給RN的通信通道车摄。
3.原生直接發(fā)消息寺谤,通過
[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;
}
不然可能會報(bào)bridge為空变屁。
詳情可見
無星的RN學(xué)習(xí)之旅(三)
四眼俊、RN與webView中html的通信
這塊我感覺有坑,但因?yàn)閔tml不是強(qiáng)項(xiàng)粟关,因此交給我們前端去做了泵琳。按官網(wǎng)的標(biāo)準(zhǔn),使用onMessage()發(fā)送的消息在html中經(jīng)常接受不到誊役,不知道是為什么获列,希望有知道的旁友可以教教我=。=
五蛔垢、debug是個(gè)坑;骱ⅰ!鹏漆!
在我使用真機(jī)調(diào)試的時(shí)候巩梢,經(jīng)常報(bào)找不到資源,這時(shí)候需要將appdelegate的j什么什么的我給忘了- -明天去公司復(fù)制一下代碼艺玲。
jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];
// jsCodeLocation = [NSURL URLWithString:@"http://自己的ip地址/index.ios.bundle?platform=ios&dev=true"];
需要把地址更換為ip地址括蝠,注意,debug模式饭聚,手機(jī)和電腦必須處于同一個(gè)網(wǎng)段下忌警。差不多就是這個(gè)地方來回?fù)Q,總能debug進(jìn)去秒梳。
當(dāng)點(diǎn)擊事件報(bào)錯(cuò)的時(shí)候法绵,注意一下飄紅信息,有的是debug模式的錯(cuò)誤酪碘,忽略即可朋譬。
等明天上班再上圖。兴垦。徙赢。這個(gè)地方的圖有點(diǎn)難搞了。探越。狡赐。調(diào)試出錯(cuò)了我再截圖回頭放上來
五、RN的持久化存儲扶关,AsyncStorage
其實(shí)這一塊是我旁邊的安卓大佬寫的阴汇,我沒啥了解的,我要說的也不是如何存儲节槐。搀庶。
我要說的是取出拐纱。先說下可能出現(xiàn)的應(yīng)用場景:
在App初始化的時(shí)候,可能需要從本地取儲存的數(shù)據(jù)哥倔,iOS原生開發(fā)都是在沙盒里存儲秸架,安卓也有對應(yīng)的地方去存儲。但現(xiàn)在換RN了咆蒿,可能有的老哥就不知道咋辦了东抹。
其實(shí)不管那些亂七八糟的,RN的存儲也是基于原生去封裝的沃测。就iOS來說缭黔,數(shù)據(jù)其實(shí)還是存在沙盒中,位于Documents文件夾下蒂破,會默認(rèn)創(chuàng)建一個(gè)名為
RCTAsyncLocalStorage_V1
的文件夾馏谨,其中有個(gè)默認(rèn)名為
manifest.json
的文件,因此就可以直接讀取出來附迷。
這里給大家一個(gè)查看真機(jī)沙盒的方法:
顯示包內(nèi)容惧互,這樣就能下載真機(jī)的沙盒地址了
不過這里要注意了,里面存的json喇伯,都不是正兒八經(jīng)的json喊儡。。稻据。會多很多的轉(zhuǎn)義符\和雙引號單引號艾猜。這里我的推薦做法是先用json解析成字典,在對其進(jìn)行特殊符號的去除操作(明天上代碼- -)攀甚。如下:
#pragma mark -- JSON轉(zhuǎn)字典
+(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{
// 解析錯(cuò)誤
return nil;
}
}
#pragma mark -- 去除RN存儲數(shù)據(jù)解析后的字符串含有 " 和 轉(zhuǎn)義符
+(NSString*)removeEscapeCharacter:(NSString*)string{
// 首先自己定義一個(gè)NSCharacterSet, 包含需要去除的特殊符號
NSCharacterSet *set = [NSCharacterSet characterSetWithCharactersInString:@"@/:;()¥「」"秋度、[]{}#%-*+=_\\|~<>$€^?'@#$%^&*()_+'\""];
NSString *responseString = [string stringByTrimmingCharactersInSet:set];
return responseString;
}
這是我能想到的最好辦法了,如果還有大佬有更高級的方法钱床,麻煩告訴一聲~~
六:(偽)modal與alert沖突
為什么要說一個(gè)偽字呢荚斯,因?yàn)槲野l(fā)現(xiàn),似乎不是沖突查牌,而是在某些情況下modal的彈窗或者alert的彈窗會導(dǎo)致應(yīng)用卡死事期,應(yīng)該算是一個(gè)bug吧。就比如做跳轉(zhuǎn)webview的時(shí)候alert等情況下纸颜。兽泣。想了一下,這個(gè)地方的代碼不太好上胁孙,還是等各位自己遇到吧唠倦。称鳞。。稠鼻。
七:debug產(chǎn)生的奇怪效果
1.原生的UI優(yōu)先級會更高:當(dāng)你某個(gè)效果跳轉(zhuǎn)展現(xiàn)原生UI的時(shí)候冈止,你進(jìn)行reload,你會發(fā)現(xiàn)應(yīng)用重新刷新候齿,但是頁面卻仍然是原生的頁面再最上層熙暴,這個(gè)原生的UI是不會進(jìn)行reload的。慌盯。這時(shí)候只能重啟服務(wù)來重新打開app
2.modal視圖層在最上面周霉。你也可以試試彈一個(gè)modal,reload也不會刷新這個(gè)modal亚皂。
八:iOS打包
cd到項(xiàng)目目錄下
然后手動在項(xiàng)目目錄下的iOS文件夾創(chuàng)建一個(gè)bundle文件夾
然后打開命令行诗眨,輸入
react-native bundle --entry-file index.ios.js --bundle-output ./ios/bundle/index.ios.jsbundle --platform ios --assets-dest ./ios/bundle --dev false
執(zhí)行完畢之后,你就發(fā)現(xiàn)bundle文件夾下就多了靜態(tài)資源文件孕讳。
但注意了匠楚,只有require導(dǎo)入的圖片資源會被放進(jìn)來
靜態(tài)網(wǎng)頁的css樣式之類的,資源可能不會被放進(jìn)來厂财,這時(shí)候怎么辦芋簿?答案是手動導(dǎo)入。
暫時(shí)就想到這么多璃饱,等項(xiàng)目完成了再進(jìn)行一下經(jīng)驗(yàn)完善~~~
2017-11-17
如果你使用上面的打包報(bào)錯(cuò)与斤,報(bào)錯(cuò)信息為
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的)用下面這個(gè),其實(shí)就是改了一丟丟
react-native bundle --entry-file index.js --bundle-output ./ios/bundle/index.jsbundle --platform ios --assets-dest ./ios/bundle --dev false
轉(zhuǎn)載請說明來自:http://www.reibang.com/u/fef7696741c8
無星的RN學(xué)習(xí)之旅(一)-環(huán)境安裝以及新建項(xiàng)目
無星的RN學(xué)習(xí)之旅(二)-RN與原生的通信
無星的RN學(xué)習(xí)之旅(三)-bridge is not set.
無星的RN學(xué)習(xí)之旅(五)-關(guān)于react-navigation多層級頁面返回時(shí)荚恶,去掉逐層推出動畫
無星的RN學(xué)習(xí)之旅(六)-第三方App跳轉(zhuǎn)撩穿,蘋果商店跳轉(zhuǎn),loading框