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

2023-12-10

我正在使用 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 菜鸟。我读过苹果文档但其中描述的示例都是新声明的方法,我想这可能更容易实现,因为 Obj-C 方法已经定义了。

预先感谢您的任何意见。


一种方法是在具有 shouldStartLoadEvent 的 UIWebView 上设置委托。在该事件中,您检查 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 中提供的类似动态函数调用。然而,这实施起来要复杂得多,并且可能存在安全风险。我建议实现如上面代码所示的路由逻辑。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 UIWebView 中从 Javascript 调用 Objective-C 方法? 的相关文章

  • 如何立即启动setInterval循环? [复制]

    这个问题在这里已经有答案了 在一个简单的setInterval setInterval function Do something every 9 seconds 9000 第一个动作将在 9 秒后发生 t 9s 如何强制循环立即执行第一个
  • 这种类型注释在没有 TypeScript 的 React 代码中如何工作?

    我在看这段代码示例 https reacttraining com react router web example auth workflow在 ReactRouter 页面上 这篇文章很有趣 const PrivateRoute com
  • 频繁绘制 CGPath 时的性能

    我正在开发一个将数据可视化为折线图的 iOS 应用程序 该图被绘制为CGPath在全屏自定义中UIView最多包含 320 个数据点 数据经常更新 图表需要相应地重新绘制 刷新率为 10 秒就很好了 到目前为止很容易 然而 我的方法似乎需要
  • JS 保留以零结尾的小数[重复]

    这个问题在这里已经有答案了 在JavaScript中 是否可以 锁定 十进制数 以保留以零结尾的 浮点数 例如 我有 2 个不同的数字 如下所示 伪代码 let a 1 0 let b 1 00 a b true should be fal
  • iOS 循环对象的属性并添加操作

    我有一个具有几个类似属性的类 UISliders 我想添加用户开始和结束使用每个滑块时的操作 每个滑块都将链接到同一个选择器 因此我考虑只是迭代它们 而不是编写 10 个几乎相同的代码块 问题是 最有效的方法是什么 我尝试过这样的事情 在运
  • 如何在 React Native 上显示 SVG 文件?

    我想显示 svg 文件 我有一堆 svg 图像 但我找不到显示的方式 我尝试使用Image and Use的组成部分反应本机 svg https github com magicismight react native svg但他们不这样做
  • Google 地图 API -> OpenGLES 崩溃

    日志是从 Crashlytics 粘贴的 对于许多用户来说 崩溃经常发生 据我所知 它与设备 iOS 版本无关 我在我的代码中找不到任何错误 这似乎是纯粹的库问题 是 Google 地图 API 错误吗 我可以做些什么来修复它 或者我应该在
  • 全局传递 xhr onload 函数的值

    在我正在创建的应用程序中 我有以下 XMLHttpRequest 并且我正在尝试传递结果data在 的里面xhr onload 到在同一父函数中创建的数组中 var url http api soundcloud com resolve j
  • ES6继承:使用`super`访问父类的属性

    JavaScript 的super关键字 当我在 Chrome Babel TypeScript 上运行代码时 得到了不同的结果 我的问题是哪个结果是正确的 规范的哪一部分定义了这种行为 下面的代码 class Point getX con
  • webpack中动态加载外部模块失败

    我正在尝试建立以下架构 一个核心 React 应用程序 它具有一些基本功能 并且能够在运行时加载其他 React 组件 这些额外的 React 组件可以按需加载 并且它们在构建核心应用程序时不可用 因此它们不能包含在核心应用程序的捆绑包中
  • 如何将 Vue.js 作用域样式应用于通过视图路由器加载的组件?

    如何将 Vue js 作用域样式应用于通过以下方式加载的组件
  • 苹果企业程序分发问题[关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 这个问题涉及到Apple iOS 开发者企业计划 http developer apple com programs ios enterprise 我
  • Web组件中嵌套槽的内容不可见

    我有一个 Web 组件 它应该接受任意元素来包装其内容 虽然我可以在 Chrome 开发工具中看到插槽已正确分配 但 DOM 中什么也没有出现 以前有人见过这个问题吗 定义 class ExampleParent extends HTMLE
  • 分发内部业务 IOS 应用程序

    我遇到了 IOS 应用程序分发的一个令人困惑的部分 因此 我需要简单细分一下我的限制 即仅将我的应用程序分发给我的员工 同事或任何被视为 内部 的人 这是表明我不希望该应用程序出现在应用程序商店中的另一种方式 我的情况是我为几家公司开发 他
  • RemoteIO 音频单元播放回调中的 AudioBufferList 内容

    我想 拦截 音频数据传送到 iOS 设备扬声器的过程 我相信这可以使用 RemoteIO 音频单元和回调来完成 在下面的playbackCallback中 ioData实际上包含任何音频数据吗 static OSStatus playbac
  • 为什么 Node.js 应用程序只能从 127.0.0.1/localhost 访问?

    我本来打算教我的朋友介绍 Node 但是后来 我想知道为什么这个代码来自nodejs org var http require http http createServer function req res res writeHead 20
  • 在 JavaScript 函数的 Django 模板中转义字符串参数

    我有一个 JavaScript 函数 它返回一组对象 return Func id name 例如 我在传递包含引号的字符串时遇到问题 Dr Seuss ABC BOOk 是无效语法 I tried name safe 但无济于事 有什么解
  • 将多维数组转换为单数组(Javascript)

    我有一个对象数组 来自 XLSX js 解析器 因此其长度和内容各不相同 表示已给予项目的资助 简化后 它看起来像这样 var grants id p 1 location loc 1 type A funds 5000 id p 2 lo
  • 如何在运行脚本之前提交活动单元格中所做的更改? (Google 表格/Google Apps 脚本)

    我正在使用 Google Apps 脚本在 Google 表格中创建提交表单 该表单位于一页上 提交内容被移至第二个隐藏页面 当用户填写表单后 他们按下提交页面上的按钮以激活脚本 我遇到的问题是 当用户填写最后一个单元格然后单击按钮时 输入
  • 为什么使用 iPhone 或 iOS 设备在“iframe”中查看“position:fixed”时不起作用?

    我研究过 stackoverflow 似乎position fixed在 iOS 移动设备的 iframe 中 https stackoverflow com questions 15874910 position fixed and if

随机推荐

  • PutSql - 日期格式错误

    我正在尝试从 Teradata 读取数据并将其填充到 Oracle 数据库 请在下面找到我的流程 ExecuteSQL gt SplitAvro gt ConvertAvroToJSON gt ConvertJSONToSQL gt Put
  • 从Python中不同类中的类调用方法

    假设我有这个代码 class class1 object def init self don t worry about this def parse self array do something with array class cla
  • 覆盖滚动禁用

    So I have an overlay like below screenshot from example site 当菜单 A 部分 打开时 它会在主 div B 部分 上显示一个覆盖层 但是 当菜单打开时 我仍然可以滚动主 div
  • 使用正则表达式在 sed 中进行替换时,加上量词无法按预期工作

    输入是 PermitRootLogin 否 为什么以下 sed 表达式不能与 sed 一起使用 echo PermitRootLogin no sed s PermitRootLogin s PermitRootLogin yes 但是当我
  • 具有doctrine2、symfony2 和 postgresql 实体的案例

    我在使用 postgres 数据库的 symfony2 应用程序中遇到了关于 Dodocy2 的问题 我收到错误 SQLSTATE 3F000 Invalid schema name 7 ERROR schema main does not
  • 为什么 shell 会忽略通过变量传递给它的参数中的引号字符? [复制]

    这个问题在这里已经有答案了 这些工作如广告所示 grep ir hello world grep ir hello world 这些不 argumentString1 ir hello world argumentString2 ir he
  • 使用 ADF Pipeline 中的自定义活动从 OnPrem SQL Server 复制到 DocumentDB

    我正在尝试从本地 SQL 服务器中的 SQL 表复制数据 并使用 Azure 数据工厂管道中的自定义活动将其上传到文档数据库 谁能告诉我如何使用 IDotNetActivity 或任何其他接口或类来完成它 实际上 自定义活动目前无法访问本地
  • 使 HTML 不适用于 Windows 10 中的 Sphinx 文档

    我正在尝试遵循tutorial关于如何为项目设置 sphinx 和 Readthedocs 我当时在实习时使用过 Sphinx 在 ubuntu 上 设置非常无缝 我刚刚推出了sphinx quickstart在我的 anaconda po
  • 如何调用Enum单独的方法?

    我有一个枚举 可能如下所示 我的目标是拥有一个enum使用一些常见方法 我通过添加抽象方法来强制执行此操作 和一些 枚举值个体 方法 以下代码编译 public enum MyEnum VALUE Override public void
  • 在 iPhone 中使用图像(普通和 @2x)

    所以我正在构建一个使用图像作为按钮的应用程序 我提供了普通图像和 2x 图像 但是我不完全确定应该使用哪一个 如果我使用normal png 或使用基本上没有区别 电子邮件受保护 但是我读到使用 2x 需要更多内存 所以我觉得我不应该这样做
  • 为什么我们需要指定init方法?

    即使不指定以下代码块也可以正常运行init方法 如果是这样的话 这样做的目的是什么 init方法服务 struct Person var name String var age Int init name String age Int se
  • 通过USB端口发送和接收数据[关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 目前不接受答案 我想通过 USB 端口向设备发送 接收数据 从我的 Vista 电脑 是否有一个免费 便宜的图书馆可以做到这一点 以及这个项目的参与程度如何 不考虑
  • 将事件转发给所有JAVA组件

    我不知道如何解决这个问题 我正在开发一个图形编辑器 可以在其中绘制弧 线 我手动将圆弧组件的大小设置为 1000x1000 因此当拖放此圆弧时我不必更改它 然后我在这个组件中绘制所需尺寸的弧线 每个弧形组件都安装了鼠标监听器 问题是 只有最
  • 为什么这些梯度累积实现不起作用?

    Note 经过实验 我发现只有在 GPU 上训练时才会出现这个问题 我创建了一个 github 问题 50454 此时我不确定到底发生了什么 我正在研究梯度累积的实现 然而 这些方法似乎都不起作用 下面我描述了两种理论上可行但似乎与 Ten
  • 尝试将 EmailJS 与 React 结合使用时,服务 ID 无效

    我在我的网站上创建了一个联系我的表单 为此我使用了 EmailJS 然而 当我尝试通过联系表给自己发送邮件时 我收到了 400 错误The service ID is invalid 我遵循了该教程的每个步骤 因为我之前没有使用过 Emai
  • 可选类型“NSURL?”的值未拆封;你的意思是使用“!”吗?或者 '?'?

    我使用 Xcode 6 Beta 6 启动了一个 Swift 项目 该项目还使用了 Core Data 升级到 Xcode 6 GM 后 编译时出现以下错误 Users AppDelegate swift 58 52 Value of op
  • 如何在android中下载谷歌地图的特定区域

    我正在制作一个 Android 应用程序 它将在屏幕上显示谷歌地图 通过单击按钮 用户可以下载他 她的特定区域并将其存储在内部存储中 稍后 当互联网连接较差或不可用时 用户可以使用之前下载的离线地图 如何制作这样的应用程序 请指导我 谢谢
  • Perl 命令行多行替换

    我正在尝试使用命令行 perl 替换多行文件中的文本 我正在使用 Ubuntu Natty 以下是我的文本文件 称为 test txt 的内容 mysqld Basic Settings IMPORTANT If you make chan
  • 使用 sqlalchemy 时出现编程错误:(psycopg2.errors.UndefinedColumn)

    我在查询使用 sqlalchemy 在 postgres db 本地 上创建的表时遇到问题 虽然我能够执行并接收查询结果 SELECT FROM olympic games 当我尝试访问单个列或对表执行任何其他操作时收到错误消息 SELEC
  • 如何在 UIWebView 中从 Javascript 调用 Objective-C 方法?

    我正在使用 Phonegap 开发一个本机 iPhone 应用程序 因此一切都是用 HTML 和 JS 完成的 我正在使用 Flurry SDK 进行分析并希望使用 FlurryAPI logEvent EVENT NAME 跟踪事件的方法