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

我正在使用Phonegap开发一个原生的iPhone应用程序,所以一切都是用HTML和JS完成的。 我正在使用Flurry SDK进行分析,并希望使用

[FlurryAPI logEvent:@"EVENT_NAME"]; 

跟踪事件的方法。 有没有办法在Javascript中执行此操作? 因此,在跟踪链接时,我会想象使用类似的东西

 Rainbows Unicorns 

“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 noob。 我已经阅读了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中已定义方法并避免硬编码路由逻辑这一事实的唯一方法是使用@selectors或Objective-C中提供的类似动态函数调用。 但是,这实现起来要复杂得多,并且可能存在安全风险。 我建议实现如上面代码中所示的路由逻辑。

PhoneGap具有添加本机插件的function,为iOS添加Flurry日志事件插件我会做这样的事情:

添加PGFlurry PhoneGap插件类:

PGFlurry.h

 #import  @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); } } }); 

将插件添加到PhoneGap.plist ,将键和值“PGFlurry”添加到“插件”字典中。

现在你应该能够像这样使用它:

           

你可以找到我写的Phonegap Flurry插件

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

不要使用他们的objective-c库,使用他们的js库,你不必担心objective-c。 🙂