繁体   English   中英

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

[英]How do I call an Objective-C method from Javascript in UIWebView?

我正在使用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文档,但是其中描述的示例都是针对新声明的方法的,我认为这可能更易于实现,因为已经定义了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中可用的类似动态函数调用。 但是,这实施起来要复杂得多,并可能带来安全风险。 我建议实现上述代码中所示的路由逻辑。

不要使用他们的Objective-C库,而使用他们的js库,您就不必担心Objective-C。 :)

PhoneGap具有添加本机插件,为iOS添加Flurry日志事件插件的功能,我将执行以下操作:

添加一个PGFlurry PhoneGap插件类:

PGFlurry.h

#import <PhoneGap/PGPlugin.h>

@interface PGFlurry : PGPlugin
- (void)logEvent:(NSArray*)arguments withDict:(NSDictionary*)options;
@end

PGFlurry.m

#import "PGFlurry.h"
#import "FlurryAPI.h"

@implementation PGFlurry
// if you init Flurry somewhere else you can remove this method
- (PGPlugin*) initWithWebView:(UIWebView*)theWebView {
  self = [super init];
  if (self == nil) {
    return nil;
  }

  // init and start Flurry
  [FlurryAPI startSession:@"API key"];

  return self;
}

- (void)logEvent:(NSArray*)arguments withDict:(NSDictionary*)options {
  [FlurryAPI logEvent:[arguments objectAtIndex:0]];
}
@end

将JavaScript插件帮助程序添加到www文件夹:

Flurry.js

PhoneGap.addConstructor(function() {
  if(!window.plugins) {
    window.plugins = {};
  }

  window.plugins.flurry = {
    logEvent: function(name) {
      return PhoneGap.exec("PGFlurry.logEvent", name);
    }
  }
});

通过将键和值对都添加为“ PGFlurry”的键/值对,将插件添加到PhoneGap.plist

现在您应该可以像这样使用它:

<!DOCTYPE html>
<html>
  <head>
    <script src="phonegap.js" type="text/javascript"></script>
    <script src="flurry.js" type="text/javascript"></script>
    <script type="text/javascript">
      document.addEventListener("deviceready", function() {
        window.plugins.flurry.logEvent("Testing");
      }, false);
    </script>
  </head>
  <body>
  </body>
</html>

您可以在以下位置找到由我编写的Phonegap Flurry插件

https://github.com/designerkamal/Phonegap-Flurry-Plugin

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM