更新記錄
在react native v0.29版本之后修改了遠(yuǎn)程服務(wù)的訪問方式令宿,因此對(duì)此庫(kù)做了響應(yīng)的更新跳座。
同時(shí)支撐了自動(dòng)安裝集成方式
rnpm install react-native-DebugServerHost
。具體詳情可查看github主頁(yè)。
前言
大家都知道android端的react native可以運(yùn)行時(shí)修改server host,開發(fā)模式下?lián)u一搖設(shè)備虱咧,呼出調(diào)試菜單,就可以修改server host,不需要重新打包很方便瑞凑。不知道為什么,iOS環(huán)境卻沒有提供相關(guān)功能概页。
于是這個(gè)工具就出來了:react-native-debug-server-host籽御。我們知道直接修改源碼很容易實(shí)現(xiàn)需求,但不侵入原有代碼才是上策惰匙,后面部分有實(shí)現(xiàn)原理的簡(jiǎn)單介紹技掏。
如何使用
使用方式簡(jiǎn)單的不能再簡(jiǎn)單了,只要把DebugServerHost
整個(gè)目錄引用到xcode工程中项鬼,恭喜你哑梳,你已經(jīng)安裝完畢。
運(yùn)行一下绘盟,看你的調(diào)試菜單是不是多了一項(xiàng):
修改server host
可以通過手工輸入鸠真,也就是直接在文本框中手工打字,原則上不建議這么做龄毡,太虐心了吠卷。因此提供了更方便的修改途徑:掃描二維碼。
具體操作步驟:
將服務(wù)器地址通過二維碼生成工具沦零,生成二維碼祭隔。
點(diǎn)擊
Input URL With QRScan
,打開掃一掃工具蠢终,掃描二維碼序攘。點(diǎn)擊
OK
,會(huì)自動(dòng)執(zhí)行reload
動(dòng)作寻拂。
很方便是吧程奠。集成和使用說完了,下面說下具體實(shí)現(xiàn)祭钉。只關(guān)心使用的朋友就不用繼續(xù)往下看了瞄沙。
該庫(kù)中使用了二維碼掃描庫(kù)
QRCodeReaderViewController
,如果你的工程中也使用了這個(gè)庫(kù)慌核,保留工程中的距境,刪除庫(kù)中的源文件即可。
實(shí)現(xiàn)原理
調(diào)試菜單的實(shí)現(xiàn)在RCTDevMenu
這個(gè)類中垮卓,每次打開調(diào)試菜單時(shí)垫桂,都會(huì)調(diào)用menuItems
這個(gè)方法,它是用來創(chuàng)建菜單選項(xiàng)的粟按,所以我們要添加自己的調(diào)試菜單诬滩,只需要在末尾追加就可以了霹粥。
考慮到react native更新頻率較快,并且直接修改源碼的方式不太科學(xué)疼鸟,因此創(chuàng)建RCTDevMenu
的分類后控,添加自定義菜單,然后使用swizzling技術(shù)替換原有方法空镜。swizzling在react native工具類RCTUtils
中已經(jīng)實(shí)現(xiàn)浩淘。
@implementation RCTDevMenu (serverAddr)
- (NSArray<RCTDevMenuItem *> *)newMenuItems {
NSMutableArray<RCTDevMenuItem *> *items = (NSMutableArray *)[self newMenuItems];
RCTDevMenuItem *item = [RCTDevMenuItem buttonItemWithTitle:@"Debug server host" handler:^{
[[NSNotificationCenter defaultCenter] postNotificationName:ChangeServerAddrNotification
object:nil
userInfo:nil];
}];
[items addObject: item];
return items;
}
@end
可以看到,我們添加了一項(xiàng)菜單Debug server host
吴攒,處理hander發(fā)送了一個(gè)通知张抄,用來告知處理類打開UI面板,讓用戶設(shè)置server host洼怔。
- (void)changeServerAddr:(NSNotification *)notification {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:_serverAddrviewController animated:YES completion:^{
NSLog(@"");
}];
});
}
到這里欣鳖,已經(jīng)實(shí)現(xiàn)了調(diào)試菜單,并讓用戶修改server host選項(xiàng)茴厉。下一步,就要告知RCTBridge
新的server host什荣,因?yàn)榧虞d的動(dòng)作是RCTBridge
執(zhí)行的矾缓。
RCTBridge
有個(gè)RCTBridgeDelegate
,用來告知server host是哪個(gè)稻爬,所以只要實(shí)現(xiàn)該協(xié)議嗜闻,并指定RCTBridge
的具體delegate即可。
//修改RCTBridge的delegate為自定義對(duì)象
- (void)setBridge:(RCTBridge *)bridge {
_bridge = bridge;
if ([_bridge isKindOfClass:[RCTBatchedBridge class]]) {
RCTBatchedBridge *batched = (RCTBatchedBridge *)_bridge;
[batched.parentBridge setValue:self forKey:@"delegate"];
} else {
[_bridge setValue:self forKey:@"delegate"];
}
}
//為簡(jiǎn)單起見桅锄,server host傳遞放在全局配置文件中
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge {
NSURL *serverUrl = nil;
NSString *url = [[NSUserDefaults standardUserDefaults] objectForKey:@"RCT_SERVER_ADDR_URL"];
if (url != nil && url.length > 1) {
serverUrl = [NSURL URLWithString: url];
}
return serverUrl;
}
核心實(shí)現(xiàn)基本就差不多了琉雳,剩下沒什么好說的,有興趣直接看源碼吧友瘤。
如果有幫助到你就給顆星吧翠肘,_