1. 問(wèn)題
在 AppHost.framework【注1】(以下簡(jiǎn)稱 AppHost) 的編碼中,需要處理很多預(yù)先導(dǎo)入到 webview 里的 js 文件,有一些不關(guān)鍵功能是用 .js 的文件讀到內(nèi)存的,還有一些比較短小的 js 源碼,如;
(function(e){
e.setAttribute('src','%@');
document.getElementsByTagName('body')[0].appendChild(e);
})(document.createElement('script'));
要寫(xiě)到代碼里和 objc 代碼一起。還有,在 AppHost 里,有個(gè) ah_doc 模塊,在編寫(xiě)注釋時(shí),需要輸出完整的 js 代碼,如
window.appHost.invoke('startNewPage', { 'url': 'http://you.163.com/','title': 'title',
'type': "push",
'backPageParameter': {
'url': 'http://qian.163.com',
'title': 'title',
'type': 'push'
}
})
這個(gè)字符串里包含了大量的單引號(hào)、雙引號(hào),而且為了保持可讀性、維護(hù)性,需要多行輸出。
這是非常典型的問(wèn)題,傳統(tǒng)的多行字符串聲明有沒(méi)有方法很好的解決?
2.常見(jiàn)多行聲明方式
- 利用@""包裹起來(lái),換行
NSString *a = @"[AppHost] "
@"It is called \"jsbridge\"."
@"like window.ah('ready') = function(){};"
@"fail to inject javascript";
- 利用""包裹起來(lái),換行
NSString *b = @"[AppHost] "
"It is called \"jsbridge\"."
"like window.ah('ready') = function(){};"
"fail to inject javascript";
-
最最常見(jiàn)的 \ 號(hào)分隔,保留縮進(jìn)(注意觀察截圖里的 linenum 和代碼的距離)
\分隔符,保留縮進(jìn) -
最最常見(jiàn)的 \ 號(hào)分隔,不保留縮進(jìn)(注意觀察截圖里的 linenum 和代碼的距離)
\分隔符,不保留縮進(jìn) 非多行
NSString *d = @"[AppHost] It is called \"jsbridge\".like window.ah('ready') = function(){};fail to inject javascript";
輸出結(jié)果
可見(jiàn),對(duì)于 a\b\c1\d 變量的值而言等價(jià)的。對(duì) c,有個(gè)陷阱:實(shí)際上獲得的字符串是包含編輯器縮進(jìn)。我們現(xiàn)在基本都會(huì)讓編輯器自動(dòng)縮進(jìn)代碼,所以容易出錯(cuò)。
上面 4 種寫(xiě)法,都需要處理字符"
引號(hào)嵌套的問(wèn)題,或者需要手動(dòng)加 "
號(hào),或手動(dòng)寫(xiě) \
號(hào),要么一行損失掉可讀性。
作者一般用 d 方法:在 vscode
里寫(xiě)好 JavaScript 代碼,放在 sublime text
里 先replace("\"","\\\"")
,然后command+j
合并行,再貼到Xcode
里。直到我發(fā)現(xiàn)無(wú)意中創(chuàng)建的一個(gè)宏完美的解決了這個(gè)問(wèn)題。
ah_doc_code(window.appHost.invoke('startNewPage', { 'url': 'http://you.163.com/','title': 'title',
'type': "push",
'backPageParameter': {
'url': 'http://qian.163.com',
'title': 'title',
'type': 'push'
}
}))
優(yōu)點(diǎn)
- 多行,保存源碼中的縮進(jìn)和換行
- 單雙引號(hào)混排,不需要轉(zhuǎn)義
- 使用簡(jiǎn)單,只需要包含在對(duì)
()
中,甚至都不需要外層加雙引號(hào)、#號(hào)(NSString) -
神似 ruby 中的多行字符串聲明(以下代碼是 AppHost 里生成自動(dòng)測(cè)試用例的片段)ruby 中的多行字符串
3. 那個(gè)宏 lei 了
#define ah_ml(str) @#str
??簡(jiǎn)單的令人發(fā)指。用例:
result = [NSString stringWithFormat:ah_ml((function(e){
e.setAttribute("src",'%@');
document.getElementsByTagName('body')[0].appendChild(e);
})(document.createElement('script'));), urlToRequest.absoluteString];
查看預(yù)處理的代碼,代碼e.setAttribute("src",'%@');
里的引號(hào)自動(dòng)轉(zhuǎn)義。
result = [NSString stringWithFormat:@"(function(e){ e.setAttribute(\"src\",'%@'); document.getElementsByTagName('body')[0].appendChild(e); })(document.createElement('script'));", urlToRequest.absoluteString];
完美呈現(xiàn)。
4.注
- AppHost.framework 是作者在網(wǎng)易有錢(qián)、嚴(yán)選工作中,抽離出來(lái) JSBridge 的庫(kù),實(shí)現(xiàn) native 和 h5 之間的通訊,內(nèi)置諸多常用的功能,在業(yè)務(wù)簡(jiǎn)單的情況下可開(kāi)箱即用,復(fù)雜情況允許靈活定制。預(yù)計(jì)在4月底開(kāi)源。