前言
在常見的hybridApp框架開發過程中,一般oc調用js時都是使用執行一段js調用到某個方法的方式,如下兩種:
//UIWebView
- (nullable NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script;
//WKWebView
- (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^ _Nullable)(_Nullable id, NSError * _Nullable error))completionHandler;
通過這兩種方式我們可以執行一段js,在交互過程中可以理解為調用一段預先定義好的callback函數去實現到js的回調。
同步返回值
開門見山話不多說,這里教大家如何簡單實現同步返回,demo我甚至都不想給大家寫了,因為實在是太簡單了,并且不限于UIWebView或WKWebView,基本沒有什么遷移的羈絆。
在UIWebView和WKWebView中有如下兩個代理
//UIWebView 雖說是私有的,但是從來沒有因此被拒過
- (NSString *)webView:(UIWebView *)sender runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText;
//WKUIDelegate
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable result))completionHandler;
下面看一下簡單的調用過程
- 先來看WKWebview的情況
//js
var result = prompt("123");//直接返回
alert('return'+result);//'return123'
//oc
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable result))completionHandler{
//通過completionHandler將返回值傳回js,在js層面實現直接返回的效果
completionHandler(prompt);
}
- 再來看UIWebview的情況
//js
var result = prompt("123");//直接返回
alert('return'+result);
//oc
//在UIWebview中得先子類化UIWebview并重寫實現prompt的方法,之后便可直接使用
- (NSString *)webView:(UIWebView *)sender runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)text initiatedByFrame:(CGRect)frame{
//直接ruturn,在js層面實現直接返回的效果
return prompt;
}
可以看到,跨兩種webvie的實現都可以使用同樣的js代碼(當然,即使用window.webkit.messageHandlers.currentCookies.postMessage也可以在js層面進行封裝從來實現js api的一致性)去與oc交互,并能直接用變量接受到返回值,大大提高了代碼可讀性,讓你不再陷與callback地獄之中!
最后還是附上demo吧:https://github.com/ycace/iOS-WebView-Sync-Return