Как мне вызвать метод Objective C из Javascript в UIWebView? - PullRequest
1 голос
/ 29 апреля 2010

Я разрабатываю нативное приложение для iPhone с использованием Phonegap, поэтому все делается в 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 уже определены.

Заранее благодарю за любой вклад.

Ответы [ 4 ]

3 голосов
/ 29 апреля 2010

Один из способов сделать это - настроить делегата в UIWebView, который имеет shouldStartLoadEvent. Внутри этого события вы проверяете, по какому URL пытается перейти UIWebView. Теперь для связи с 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, вы должны реализовать mustStartLoadEvent, «перехватить» эти 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. Однако это гораздо сложнее реализовать и, вероятно, представляет угрозу безопасности. Я бы рекомендовал реализовать логику маршрутизации, как показано в коде выше.

0 голосов
/ 13 августа 2013

Не используйте их библиотеку Objective-C, используйте библиотеку JS, и вам не придется беспокоиться об объективе C. :)

0 голосов
/ 17 ноября 2011

Вы можете найти плагин Phonegap Flurry, написанный мной на

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

0 голосов
/ 26 октября 2011

PhoneGap имеет функциональность для добавления собственных плагинов, чтобы добавить плагин событий журнала Flurry для iOS, я бы сделал что-то вроде этого:

Добавить класс плагина 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);
    }
  }
});

Добавьте плагин к PhoneGap.plist, добавив пару ключ / значение с ключом и значением «PGFlurry» в словарь «плагинов».

Теперь вы можете использовать его следующим образом:

<!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>
...