裝飾模式整合UIWebView與WKWebView


一、在閱讀過無數關於WebView的文章後,纔有此文的出現。某種意義上,此文的初衷並不是技術分享,而是對抄襲的不滿。但願閱讀此文的你是乾乾淨淨的。
二、選擇WebView做爲第一篇技術文章的緣由,是由於網絡上衆多對於第二代webview引擎的介紹不盡人意,且關於JS交互極爲模糊,作事不應是作完整嗎?假若你想琢磨,可在源碼中一窺究竟。
三、若是你有更加高明的思路,請Email:xorshine@icloud.com,或者在github上說明。
四、GSWebView下載地址 GSWebView文檔
javascript


  • iOS8以前閉源的UIWebView與以後開源的WKWebView,在開發中爲了支持iOS8如下的系統,難免要費些功夫。不多見到一個框架能如GSWebView通常將二者的用法簡化。java

  • GSWebView內部是對UIWebView與WKWebView的封裝,可是,它被設計成具備良好的代碼體驗。沒有過多的類讓人耳目眩暈。假若你使用過UIWebView,那麼,使用GSWebView則更加容易,你能很清楚的看出GSWebView是基本符合UIWebView的使用習慣。git

  • 使用GSWebView能從根本上解決開發者對於兩代web引擎封裝的困惑。github

1.爲什麼要從UIWebView更新到WKWebView?

假若你仔細觀察過UIWebView的內存佔用和內存泄漏,你會認爲蘋果的工程師在此處開了小差,而這個小差很難被接受。當你對比WKWebView時,你會感受到它對於內存佔用優化上的作出的努力。web

性能測試:
UIWebView WKWebView 備註
iOS 版本 8.4 8.4 ———
iPhone 6 6 真機測試
測試網頁 天貓首頁 天貓首頁 ———
內存佔用峯值 132.2MB 8.4MB ———
加載耗時 3.1s 2.6s mach_absolute_time();
FPS 無明顯差別 無明顯差別 Instruments (core animation)
測試次數 2 2 ———

注:該項測試或許存在很大的主觀性,當我加載天貓首頁時,這個結果出乎意料,差異大到使人難以接受。objective-c


2.如UIWebView同樣使用GSWebView

  • 無數的類堆積的時候,究竟是OOP仍是POP,當你看到WKWebView時,GSWebView纔會成爲你的真愛,WKWebView的設計......哎,但性能好纔是真的好!網絡

  • 引入WebKit與JavaScriptCore庫,就可開始使用GSWebView。app

使用介紹:一樣都是WebView,一樣的款式,GSWebView如何打造不同的內涵與代碼體驗?

熟悉的屬性、方法框架

@property (nonatomic, readonly, strong) UIScrollView *scrollView;
@property (nonatomic, readonly) BOOL canGoBack;
@property (nonatomic, readonly) BOOL canGoForward; 

- (void)reload;
- (void)stopLoading;
- (void)goBack;
- (void)goForward;
//......and so on

形神皆似的協議方法post

#prama mark - GSWebViewDelegate
- (BOOL)gswebView:(GSWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(GSWebViewNavigationType)navigationType;
- (void)gswebViewDidStartLoad:(GSWebView *)webView;
- (void)gswebViewDidFinishLoad:(GSWebView *)webView;
- (void)gswebView:(GSWebView *)webView didFailLoadWithError:(NSError *)error;

3.GSWebView的JavaScript交互

  • GSWebView定義了兩套協議GSWebViewDelegate和GSWebViewJavaScript,GSWebViewDelegate定義了加載狀態,GSWebViewJavaScript則只定義了JS交互。

  • 當你把方法名就這麼一傳,連參數都不要,回調天然完成,絲滑般天然......

#prama mark - GSWebViewJavaScript
 /**
   交互協議
 */
@protocol GSWebViewJavaScript <NSObject>
@optional

/**
   調用OC方法
     
     - (NSArray<NSString *>*)gswebViewRegisterObjCMethodNameForJavaScriptInteraction
     {
        return @[@"getCurrentUserId"];
     }
 
     - (void)getCurrentUserId:(NSString *)Id
     {
        NSLong@(@"JS調用到OC%@",Id);
     }
 */
- (NSArray<NSString *>*)gswebViewRegisterObjCMethodNameForJavaScriptInteraction;
  • 改動並不是是爲了增長複雜度,而是GSWebView內部的WKWebView必須經過Apple.Inc指定的方法

Adding a scriptMessageHandler adds a function window.webkit.messageHandlers.<name>.postMessage(<messageBody>) for all frames.

EXAMPLE:
JS調用客戶端getConsultationInfo:方法,客戶端獲取到id實現該方法,蘋果要求必須這樣作:

//獲取客戶端iOS版本
var version = (navigator.appVersion).match(/OS (\\d+)_(\\d+)_?(\\d+)?/);  
version = parseInt(ver[1], 10);  

if(version >= 7.0 && version < 8.0){
    getConsultationInfo(id);
}else if(version>=8.0){
    window.webkit.messageHandlers.getConsultationInfo.postMessage(id)
}

這不是貧僧的錯,要怪就怪......


4.注意事項

若是以前使用了UIWebView,現在使用GSWebView,在服務端對JS源碼作出改動後,必需要考慮客戶端老版本的兼容狀況。當改動服務端的JS代碼,勢必致使老版本中的UIWebView交互失效。在下有個建議:
當GSWebView加載成功,咱們調用服務端預先寫好的方法 function shouldUseLatestWebView(isBool);

NSString * shouldUseLatestWebView;
if (IS_IOS_8) {
    shouldUseLatestWebView = [NSString stringWithFormat:@"shouldUseLatestWebView('%@')", @"1"];
}else{
    shouldUseLatestWebView = [NSString stringWithFormat:@"shouldUseLatestWebView('%@')", @"0"];
} 
[self.webview excuteJavaScript:jsGetCurrentUserId completionHandler:^(id  _Nonnull params, NSError * _Nonnull error) {
     if (error) {
        NSLog(@"注入JS方法shouldUseLatestWebView出錯:%@",[error localizedDescription]);
    }
}];

服務端用一個全局變量保存isBool的值,當isBool爲字符串1時,說明須要使用的是第二代WebView,服務端必須使用最新的交互方式代碼,若是爲字符串0或者空,則依舊使用原來的代碼交互:

//一個全局的變量
var isBool = "";

function shouldUseLatestWebView(isBool){ 
    isBool = isBool;
}

if(isBool == "0" || isBool == ""){ 
    getConsultationInfo(id); 
}else if(isBool == "1"){ 
     window.webkit.messageHandlers.getConsultationInfo.postMessage(id);
}

如此一來,就能夠作到老版本的兼容。

5.不要吝惜你的建議

大膽的批評GSWebView!
畢竟,代碼體驗與用戶體驗,都一樣,重要。



本做品採用採用知識共享署名-非商業性使用-禁止演繹 3.0 中國大陸許可協議進行許可

    • *

相關文章
相關標籤/搜索