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

标签 javascript ios webkit flurry phonegap-plugins

我正在使用 Phonegap 开发一个 native 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 方法已经定义了。

预先感谢您的任何意见。

最佳答案

实现此目的的一种方法是在具有 shouldStartLoadEvent 的 UIWebView 上设置委托(delegate)。在该事件中,您检查 UIWebView 尝试导航到的 URL。现在要从 JavaScript 到 Objective-C 进行通信,您需要指定自己的自定义 anchor ,这将触发不同的操作。例如,要记录某些内容,您可能决定使用 anchor “#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 中已经定义的方法这一事实并避免对路由逻辑进行硬编码的唯一方法是使用 @selectors 或 Objective-C 中提供的类似动态函数调用。然而,这实现起来要复杂得多,并且可能存在安全风险。我建议实现如上面代码所示的路由逻辑。

关于javascript - 如何在 UIWebView 中从 Javascript 调用 Objective-C 方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7887224/

相关文章:

javascript - .css 转换不适用于 jquery

css - 编辑输入类型 ="search"伪元素 Button ('x' )

html - Chrome/webkit 的奇怪错误。随机大小变化

javascript - Angular $sce 阻塞了我的音频 blob src

javascript - 返回或重定向到 url

javascript - 在不使用 eval 的情况下将类型存储在变量中时创建对象实例

iOS ad-hoc 版本未安装在设备上

javascript - package.json 使用 npm 调用 Harp 和浏览器同步

ios - 更改 UIAlertViewController 色调颜色

ios - 为 iOS 应用程序中的 UIWebView 预填充 HTML5 离线应用程序缓存