如何在UIWebView中从Javascript调用Objective-C方法? [英] How do I call an Objective-C method from Javascript in UIWebView?

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

问题描述

我正在使用Phonegap开发本机iPhone应用程序,因此所有操作均以HTML和JS完成.我正在使用Flurry SDK进行分析,并想使用

I'm developing a native iPhone app using Phonegap, so everything is done in HTML and JS. I am using the Flurry SDK for analytics and want to use the

[FlurryAPI logEvent:@"EVENT_NAME"];

跟踪事件的方法.有没有办法用Javascript做到这一点?因此,在跟踪链接时,我会想像使用

method to track events. Is there a way to do this in Javascript? So when tracking a link I would imagine using something like

<a onClick="flurryTrackEvent("Click_Rainbows")" href="#Rainbows">Rainbows</a>
<a onClick="flurryTrackEvent("Click_Unicorns")" href="#Unicorns">Unicorns</a>

"FlurryAPI.h"具有以下内容:

"FlurryAPI.h" has the following:

@interface FlurryAPI : NSObject {
}

+ (void)startSession:(NSString *)apiKey;
+ (void)logEvent:(NSString *)eventName;
+ (void)logEvent:(NSString *)eventName withParameters:(NSDictionary *)parameters;
+ (void)logError:(NSString *)errorID message:(NSString *)message exception:(NSException *)exception;

+ (void)setUserID:(NSString *)userID;
+ (void)setEventLoggingEnabled:(BOOL)value;
+ (void)setServerURL:(NSString *)url;
+ (void)setSessionReportsOnCloseEnabled:(BOOL)sendSessionReportsOnClose;

@end

我只对logEvent方法感兴趣.如果现在还不清楚,我对JS很满意,但是对Obj-C的菜鸟有所了解.我已阅读 Apple文档,但其中描述的示例都是针对新声明的方法的,我想这可能更容易实现,因为已经定义了Obj-C方法.

I'm only interested in the logEvent method(s). If it's not clear by now, I'm comfortable with JS but a recovering Obj-C noob. I've read the Apple docs but the examples described there are all for newly declared methods and I imagine this could be simpler to implement because the Obj-C method(s) are already defined.

在此先感谢您的输入.

推荐答案

一种方法是在UIWebView上设置一个具有shouldStartLoadEvent的委托.在该事件内,您检查UIWebView试图导航到的URL.现在要从JavaScript与Objective-C进行通信,您需要指定自己的自定义锚,这将触发不同的操作.例如,要记录某些内容,您可能决定使用锚点"#FAPI_LogEvent_Click_Rainbows".

One way to do this is to setup a delegate on the UIWebView which has the shouldStartLoadEvent. Inside that event, you check what URL the UIWebView is trying to navigate to. Now to communicate from JavaScript to Objective-C, you need to specify your own custom anchors which will trigger different actions. For example, to log something, you might decide to use the anchor "#FAPI_LogEvent_Click_Rainbows".

在JavaScript中,您可以定义如下方法:

In JavaScript, you could have methods defined like such:

function flurryTrackEvent(text) {
  window.location.href = 'FAPI_LogEvent' + text;
}
function flurrySetUserID(userID) {
  window.location.href = 'FAPI_SetUserID' + userID;
}

接下来,在Objective-C中,您将实现shouldStartLoadEvent并捕获"这些href导航,并告诉浏览器不要加载它们.您将需要自行拆分字符串并调用适当的函数.这是一些代码:

Next, in Objective-C, you would implement the shouldStartLoadEvent and "capture" these href navigations, and tell the browser not to load them. You will need to split the string up yourself and call the appropriate function. Here's some code:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType () {
  NSString *theAnchor = [[request URL] fragment];
  if ([theAnchor hasPrefix:@"FAPI_LogEvent"]) {
    NSString *textToLog = [theAnchor substringFromIndex:[@"FAPI_LogEvent" length]];
    [FlurryAPI logEvent:textToLog];
    return NO; // prevent the UIWebView from navigating to this anchor
  } else if ([theAnchor hasPrefix:@"FAPI_SetUserID"]) {
    NSString *userID = [theAnchor substringFromIndex:[@"FAPI_SetUserID" length]];
    [FlurryAPI setUserID:userID];
    return NO; // prevent the UIWebView from navigating to this anchor
  }
}

事件已经在Objective-C中定义的事实并没有多大帮助,因为您需要实现自己的路由行为以调用适当的Objective-C方法.您可以利用以下事实的唯一方法是,已在Objective-C中定义了这些方法并避免对路由逻辑进行硬编码,那就是使用@selector或在Objective-C中可用的类似动态函数调用.但是,这实施起来要复杂得多,并可能带来安全风险.我建议实现上面代码中所示的路由逻辑.

The fact that the events are already defined in Objective-C doesn't really help much since you need to implement your own routing behavior to call the appropriate Objective-C method. The only way you could take advantage of the fact that the methods are already defined in Objective-C and avoid hard coding the routing logic, would be using @selectors or similar dynamic function calling which is available in Objective-C. However, this is much more complicated to implement and probably presents a security risk. I would recommend implementing the routing logic like is shown in the code above.

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

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