编程语言
首页 > 编程语言> > 如何在UIWebView中从Javascript调用Objective-C方法?

如何在UIWebView中从Javascript调用Objective-C方法?

作者:互联网

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

[FlurryAPI logEvent:@"EVENT_NAME"];

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

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

“ FlurryAPI.h”具有以下内容:

@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 docs,但是其中描述的示例都是针对新声明的方法的,我认为这可能更易于实现,因为已经定义了Obj-C方法.

预先感谢您的任何投入.

解决方法:

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

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

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

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

- (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中可用的类似动态函数调用.但是,这实施起来要复杂得多,并可能带来安全风险.我建议实现上述代码中所示的路由逻辑.

标签:javascript,ios,webkit,phonegap-plugins,flurry
来源: https://codeday.me/bug/20191013/1904511.html