我一直在使用WebViewJavascriptBridge在iOS應用程序中橋接Objective-C和JavaScript。它工作的很好,但它不支持從被調用的本機Objective-C函數返回調用JavaScript代碼的值。調用Objective-C函數時將值返回到JavaScript
我很確定科爾多瓦(PhoneGap)以某種方式做回調,但我一直在試圖瞭解底層機制如何工作。
有沒有人遇到同樣的問題,並設法找到解決方案?現在
我一直在使用WebViewJavascriptBridge在iOS應用程序中橋接Objective-C和JavaScript。它工作的很好,但它不支持從被調用的本機Objective-C函數返回調用JavaScript代碼的值。調用Objective-C函數時將值返回到JavaScript
我很確定科爾多瓦(PhoneGap)以某種方式做回調,但我一直在試圖瞭解底層機制如何工作。
有沒有人遇到同樣的問題,並設法找到解決方案?現在
如果你的意思是,「返回」的意義上,你的JS調用者將看到從調用返回的結果,我不知道該怎麼做。我懷疑這將需要一定程度的線程操作在JS中不可用。相反,你可以重新編碼你的JS端邏輯來創建一個結果處理函數。在僞代碼:
res = CallObjC(args);
work with res...
變爲
CallObjC(args, function(res) { work with res...});
誠然有點彆扭,但習慣了就好了 - 這是一個很常見的模式。在內部,JS橋代碼創建請求到回調函數的映射。當ObjC代碼有結果時,它使用WebView的stringByEvaluatingJavaScriptFromString調用定位並調用回調的JS橋代碼。
@Richard - 對您發佈的解決方案要小心。設置window.location來調用shouldStartLoadWithRequest可能會導致webview中的功能丟失,並且還會將消息丟失到ObjectiveC。目前的做法是使用一個iframe,並有一些可以緩衝消息的消息隊列。
,我從來沒有用過WebViewJavascriptBridge,但我一直在使用一個簡單的委託在Objective-C做到了這一點,所以也許這將幫助你:
MyScript.js
// requestFromObjc
// functionName (required):
// the name of the function to pass along to objc
// returnedResult (not used by caller):
// the result given by objc to be passed along
// callback (not used by caller):
// sent by objc, name of the function to execute
function requestFromObjc(functionName, objcResult, callback)
{
if (!objcResult)
{
window.location = "myapp://objcRequest?function=" + functionName + "&callback=" + arguments.callee.name + "&callbackFunc=" + arguments.callee.caller.name;
}
else
{
window[callback](objcResult);
}
}
function buttonClick(objcResult)
{
if (!objcResult)
{
// ask for the color from objc
requestFromObjc("buttonColor&someParam=1");
}
else
{
// do something with result (in this case, set the background color of my div)
var div = document.getElementById("someDiv");
div.style.background = objcResult;
}
}
的mypage.html
<html>
<head>
<script type="text/javascript" src="MyScript.js"></script>
</head>
<body>
<div id="someDiv">
This is my div! Do not make fun of it, though.
</div>
<button onClick="buttonClick(undefined)">
Click Me!
</button>
</body>
</html>
ViewController.m
-(NSString *) javaScriptResultForRequest:(NSDictionary *) params
{
if ([params[@"function"] isEqualToString:@"buttonColor"])
{
NSArray *colors = @[ @"red", @"yellow", @"blue", @"green", @"purple" ];
return colors[arc4random_uniform(colors.count)];
}
else
{
return @"undefined";
}
}
-(BOOL) webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
if ([[[request URL] scheme] isEqualToString:@"myapp"])
{
// parse the URL here
NSURL *URL = [request URL];
if ([URL.host isEqualToString:@"objcRequest"])
{
NSMutableDictionary *queryParams = [NSMutableDictionary dictionary];
NSArray *split = [URL.query componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"&="]];
for (int i = 0; i < split.count; i += 2)
{
queryParams[split[i]] = split[i + 1];
}
NSString *result = [self javaScriptResultForRequest:queryParams];
NSString *jsRequest = [NSString stringWithFormat:@"%@(\"%@\", \"%@\", \"%@\")", queryParams[@"callback"], queryParams[@"function"], result, queryParams[@"callbackFunc"]];
// now we send this to the target
[self.webView stringByEvaluatingJavaScriptFromString:jsRequest];
return NO;
}
}
return YES;
}
顯然,這是不是試圖做相同功能的純JS慢得多,因爲所有的迴路有跳通過。但是,如果您需要在您的ObjC代碼中的JS代碼中使用某些內容,則可能適用於您。
你會如何寫這兩個參數?當我運行這個函數時,我得到了太多參數的錯誤。 – Dagrooms
應該可能會用您的代碼創建一個新問題,以及發生錯誤的時間和位置。 – DrC