如何从Javascript调用Objective-C方法并将数据发送回iOS中的Javascript? [英] How to invoke Objective-C method from Javascript and send back data to Javascript in iOS?

查看:104
本文介绍了如何从Javascript调用Objective-C方法并将数据发送回iOS中的Javascript?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在iOS中,如何在UIWebView中从Javascript调用Objective-C方法并将其发送回Java数据?我知道可以使用Webkit库在OS X上完成此操作,但是在iOS上可以吗? PhoneGap如何实现这一目标?

解决方案

有一个API可直接从Objective-C调用JavaScript,但是您不能直接从Javascript调用Objective-C.

如何告诉您的Objective-C代码通过WebView中的Java脚本执行某些操作

您必须将Javascript操作序列化为一个特殊的URL,并在UIWebView的委托的shouldStartLoadWithRequest方法中拦截该URL.

- (BOOL)webView:(UIWebView *)webView
        shouldStartLoadWithRequest:(NSURLRequest *)request
                    navigationType:(UIWebViewNavigationType)navigationType;

您可以在该序列中反序列化特殊URL,并在Objective-C方面将其解释为所需的操作. (您应该在上述shouldStartLoadWithRequest方法中返回NO,以便UIWebView不会使用您的虚假URL实际发出HTTP请求来加载网页.)

如何从Objective-C运行Java代码

然后,您可以通过在Webview上调用此方法来从Objective-C运行Javascript.

- (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script;

示例代码

我建议您使用伪造的URL方案,这样很容易区分您的操作URL和合法请求之间的区别.您可以按照以下方式在Javascript中发出此请求:

// JavaScript to send an action to your Objective-C code
var myAppName = 'myfakeappname';
var myActionType = 'myJavascriptActionType';
var myActionParameters = {}; // put extra info into a dict if you need it

// (separating the actionType from parameters makes it easier to parse in ObjC.)
var jsonString = (JSON.stringify(myActionParameters));
var escapedJsonParameters = escape(jsonString);
var url = myAppName + '://' + myActionType + "#" + escapedJsonParameters;
document.location.href = url;

然后在UIWebView.delegateshouldStartLoadWithRequest方法中,您可以检查URL方案和片段以检查它是正常请求还是特殊操作之一. (URL的片段是#之后的内容.)

- (BOOL)webView:(UIWebView *)webView
        shouldStartLoadWithRequest:(NSURLRequest *)request
                    navigationType:(UIWebViewNavigationType)navigationType {

    // these need to match the values defined in your JavaScript
    NSString *myAppScheme = @"myfakeappname";
    NSString *myActionType = @"myJavascriptActionType";

    // ignore legit webview requests so they load normally
    if (![request.URL.scheme isEqualToString:myAppScheme]) {
        return YES;
    }

    // get the action from the path
    NSString *actionType = request.URL.host;
    // deserialize the request JSON
    NSString *jsonDictString = [request.URL.fragment stringByReplacingPercentEscapesUsingEncoding:NSASCIIStringEncoding];

    // look at the actionType and do whatever you want here
    if ([actionType isEqualToString:myActionType]) {
        // do something in response to your javascript action
        // if you used an action parameters dict, deserialize and inspect it here
    }


    // make sure to return NO so that your webview doesn't try to load your made-up URL
    return NO;
}

(如果您需要帮助将json字符串反序列化为NSDictionary,请阅读此答案.)

In iOS, how can I call an Objective-C method from Javascript in a UIWebView and have it send data back to the Javascript? I know that this could be done on OS X using the Webkit library, but is this possible on iOS? How does PhoneGap achieve this?

解决方案

There is an API to call JavaScript directly from Objective-C, but you cannot call Objective-C directly from Javascript.

How to tell your Objective-C code to do something from the Javascript in your WebView

You have to serialize your Javascript action into a special URL and intercept that URL in the UIWebView's delegate's shouldStartLoadWithRequest method.

- (BOOL)webView:(UIWebView *)webView
        shouldStartLoadWithRequest:(NSURLRequest *)request
                    navigationType:(UIWebViewNavigationType)navigationType;

There you can deserialize that special URL and interpret it to do what you want on the Objective-C side. (You should return NO in the above shouldStartLoadWithRequest method so the UIWebView doesn't use your bogus URL to actually make an HTTP request to load a webpage.)

How to Run Javascript Code from Objective-C

Then you can run Javascript from Objective-C by calling this method on your webview.

- (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script;

Example Code

I recommend using a bogus URL scheme so it will be easy to tell the difference between your action URLs and legit requests. You can make this request in the Javascript along these lines:

// JavaScript to send an action to your Objective-C code
var myAppName = 'myfakeappname';
var myActionType = 'myJavascriptActionType';
var myActionParameters = {}; // put extra info into a dict if you need it

// (separating the actionType from parameters makes it easier to parse in ObjC.)
var jsonString = (JSON.stringify(myActionParameters));
var escapedJsonParameters = escape(jsonString);
var url = myAppName + '://' + myActionType + "#" + escapedJsonParameters;
document.location.href = url;

Then in the UIWebView.delegate's shouldStartLoadWithRequest method, you can inspect the URL scheme and fragment to check if it's a normal request or one of your special actions. (The fragment of a URL is what comes after the #.)

- (BOOL)webView:(UIWebView *)webView
        shouldStartLoadWithRequest:(NSURLRequest *)request
                    navigationType:(UIWebViewNavigationType)navigationType {

    // these need to match the values defined in your JavaScript
    NSString *myAppScheme = @"myfakeappname";
    NSString *myActionType = @"myJavascriptActionType";

    // ignore legit webview requests so they load normally
    if (![request.URL.scheme isEqualToString:myAppScheme]) {
        return YES;
    }

    // get the action from the path
    NSString *actionType = request.URL.host;
    // deserialize the request JSON
    NSString *jsonDictString = [request.URL.fragment stringByReplacingPercentEscapesUsingEncoding:NSASCIIStringEncoding];

    // look at the actionType and do whatever you want here
    if ([actionType isEqualToString:myActionType]) {
        // do something in response to your javascript action
        // if you used an action parameters dict, deserialize and inspect it here
    }


    // make sure to return NO so that your webview doesn't try to load your made-up URL
    return NO;
}

(Read this answer if you need help deserializing your json string into an NSDictionary.)

这篇关于如何从Javascript调用Objective-C方法并将数据发送回iOS中的Javascript?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆