iOS“默认”UIWebView/WebKit 上的 WebAudio 支持

Posted

技术标签:

【中文标题】iOS“默认”UIWebView/WebKit 上的 WebAudio 支持【英文标题】:WebAudio support on iOS "default" UIWebView/WebKit 【发布时间】:2014-09-06 14:42:14 【问题描述】:

欢迎提出任何改进问题或标题的建议。

客观题在上,完整题如下:

    如何确定 Cordova 项目支持 WebKit 的哪个“版本”和/或 WebAudio API 的哪个构建/版本?我是 Objective-C 和 XCode 的完全新手,如果对此有明显的答案,请原谅我。

    有没有办法使用更新版本的 WebKit 构建 Cordova 应用程序以支持更新的 WebAudio 实现?

    有点主观,但考虑到我的应用程序的要求,以及这些替代方案在实践中的效果,任何人都可以评论我可以调查的 WebAudio 替代方案吗?不幸的是,我为这个应用程序在 javascript/html 上投入了大量资金,但需要考虑是否甚至潜入 Objective-C 来重写应用程序或构建一个原生扩展(插件)是否会取得成果。

这些要求基本上是:

播放短音频样本(最长 2-3 秒),延迟低于 50 毫秒以响应 UI。 需要从最终标注中修复延迟。也就是说,从最终调用 .playSound(...) 开始,不能有额外的可变延迟。这是一个音序器。 加载 MP3 或 OGG 样本(不是原始音频)。 可以动态加载和卸载样本集。

我知道的 ios 的唯一选项是 Flash/AIR、带 HTMl5 音频的 Javascript、带 WebAudio 的 Javascript 和原生 Objective-C。最后一个包括与 Cordova 一样的本机扩展/插件。

问题的详细描述如下。

我在使用 Javascript 为 iPad 开发吉他应用程序时遇到了困难,并且遇到了一些糟糕的解决方案。该应用程序使用 WebAudio 创建波表合成器,并实时响应用户输入。播放的核心功能可能会以约 100-200 毫秒的延迟摆脱困境,但应用程序的感觉和一些次要功能依赖于响应更快的约 10-50 毫秒延迟。

我(是的,不明智)完全在桌面 Chrome 中开发了该应用程序,并在 iOS Safari 中进行了一些测试,这让我相信一切都会正常运行。我(不明智地)推迟了使用 Cordova/Phonegap 或 CocoonJS 构建的令人不快的工作,因为我认为在(咳嗽)目标平台上进行快速迭代开发胜过测试。

有什么比发现所有代码都无法在目标平台上运行更糟糕的呢?发现很难确定您的代码是否适用于您的目标平台,因为构建和调试非常有问题......

我遇到的问题,如果当之无愧的话:

使用 Cordova 构建时,应用程序无法初始化。我没有控制台输出。 org.apache.cordova.console 插件偶尔工作,我还不能确定这是否可以解决(其他人也有类似的问题)。 我可以打开 Safari 并附加远程开发控制台,但无法在应用加载和初始化之前执行此操作。再说一次,很难弄清楚 WebAudio 会发生什么。 我在某些运行中获得了一个测试 WebAudio 应用程序来产生声音;在其他运行中它是沉默的。没有控制台输出来帮助识别这一点。 从 webkitAudioContext 迁移到最终的无前缀 AudioContext 涉及一些小的代码更改。然而,前者(显然)仍被 Cordova 构建的 WebKit 版本(或者,所有本机 iOS 应用程序都可以访问的版本?)使用,而后者用于(远、远、远更有用和可靠)开发)最新版本的 Chrome。因此,似乎我必须编写一些可以使用任一版本的 API 的适配器代码,但没有可靠的方法在我的目标平台上调试它。 互联网上的大量(不是最近的)喋喋不休让我想知道 WebAudio 是否会在使用其旧版本 WebKit 的混合应用程序中充分执行(假设我最终会解决上述所有问题并让应用程序制作声音)。我花了很多时间进行分析和优化以使其在 Safari 中可接受地运行,但没有意识到这可能与独立应用程序有很大不同的性能(或者就此而言,更好性能)。李> 不特定于 WebAudio,但由于 Cordova 多次复制的(不变的)音频样本数量,我的应用程序需要 分钟来构建每次更改。这是告诉我为什么 Cordova/Phonegap 有如此痛苦的名声的众多危险信号之一。

在底部,我被困在一个地方,可能需要付出相当大的努力才能确定是否需要付出更多的努力来追求已经投资的技术选择(WebAudio,JS/HTML),如果任何有相关经验的人都可以帮助我预测这项工作的结果。我可以开始学习 Objective-C 并为 Cordova 插件编写原生代码(至少有几个现有的项目可以支持简单的原生音频)。我同样可以开始在 Flash 中进行完全重写,这将解决应用程序中的其他问题(例如管理可扩展的 UI 和简化代码和构建管理),但据我所知,保证音频延迟很差,并且肯定会有其他问题。如果我能让现有的代码库在 iOS(iPad 2 及更高版本)上工作,我会很高兴。不幸的是,我没有几个月的时间重新开始,但是如果重新开始是唯一可行的选择...

感谢任何帮助。

【问题讨论】:

【参考方案1】:

首先我可以给你一些调试的提示:

根据我自己的经验,我知道在deviceReady 被解雇之前出现的这种“加载错误”是一件非常痛苦的事情,而且很难找到。

你可以尝试两件事:

首先,要附加到 Safari 远程调试器,请在初始化 WebAudio 内容之前编写alert('test'); 。诀窍在于,只要您没有处理警报消息,应用程序就会停止执行。所以有足够的时间来附加远程调试器,处理警报消息并从那里获取远程输出。

您可以尝试调试的另一件事是weinre,另一个远程调试器。要设置weinre,请通过sudo npm -g install weinre 安装它,在您的开发人员机器上打开一个weinre localhost 实例并将<script src="http://<your developer machine IP>:8080/target/target-script-min.js#anonymous"></script> 行粘贴到您的index.html 中。如果我没记错的话,你必须在包含任何其他脚本之前注入这一行。

用您的浏览器连接到http://localhost:8080,在那里找到远程控制台并启动您的应用程序。我使用这个工具在我的代码中发现了一些难以发现的问题。


我无法专门为您提供 WebAudio 方面的帮助,但您看过 Low Latency Plugin for Phonegap 吗?前段时间,当我在 Phonegap 项目中遇到一些音频延迟问题时,我偶然发现了它,事实证明它对我很有帮助。

查看链接页面上的 YouTube 演示。通过其预加载音频的能力和更多改进,它的性能非常好,并且看起来非常适合您的用例。当然,您不需要自己编写本机代码。

【讨论】:

警报方法是一个有用的提示。我部分想知道移动开发的整个混合方法是否仍然比它的价值更麻烦。令人沮丧的是,我的代码,包括低延迟音频,目标设备上,在网络浏览器中运行良好,但似乎 a) 这对于 Cordova 可能不是真的(或类似的)应用程序,并且 b)尝试在目标构建上进行实际开发非常繁重,以至于开始学习 Objective-C 可能更容易。从这个意义上说,任何让混合开发者感觉可能的事情现在都会非常令人鼓舞。 嗯,我知道你的感受,但不幸的是,必须始终在目标设备上进行持续测试,这是我自己在进入混合开发时必须快速学习的一课。你应该看看你的构建过程,也许还有一些优化潜力。如果您应该尝试自己进行插件开发或调试,我建议您使用 Xcode 进行部署,因为这证明我对于“本机”调试更快、更舒适。【参考方案2】:

    虽然在浏览器中进行开发很方便,但它无法替代真实设备。无论你使用 PhoneGap、Flash、Objective-C 等,都是如此。

    有些你承认,但值得重申。

    永远,永远假设因为您的应用程序在您的桌面上运行,它就可以在您的目标上运行。由于 iOS 上可用的 WebKit 版本不同(取决于操作系统版本),因此对于混合应用程序来说确实如此,但对于本机应用程序也是如此。众所周知,您应该永远依赖 iOS 模拟器来告诉您确定应用程序是否可以在真实设备上正常运行。此外,iOS 模拟器并没有实现真机具备的很多功能,因此唯一的测试方法是使用真机。

    永远,永远假设如果它在您的桌面上运行良好,那么它会在您的目标上运行良好。混合和非混合开发也是如此。例如,iOS 模拟器仅受 PC 能力的限制,包括速度和内存。这意味着应用程序可以在模拟器上完美运行,但由于内存限制而在真实设备上崩溃,或者它在桌面上可能很快而在设备上速度极慢。再次,在实物上进行测试。

    如果可能,请尝试在多个设备上进行测试。针对您定位的最低速度设备进行优化。如果您打算针对 iPhone 4s 及更新机型,请购买一部并针对它进行优化 - 针对 iPhone 5s 进行优化会有所帮助,但它只会告诉您有关 iPhone 5s 的信息,而不会告诉您其他任何信息。

    认识到您不仅针对 iOS,还针对特定的 WebKit。每个版本的 iOS 都有不同的 WebKit 版本,并且不可协商。换句话说,您不仅针对 iOS 6、7、7.1,而且对于混合开发,您也针对他们的 WebKit 版本。每个都有自己的怪癖和陷阱。 (就平台 SDK 而言,本机开发也是如此——每个版本都有自己的怪癖和陷阱。)

    Cordova 不针对特定版本的 WebKit - 它针对系统 Web 浏览器,或者在 iOS 的情况下,UIWebKit。用户在其平台上拥有的任何版本都是您将获得的版本。这使得 android 变得可怕(在我看来),但也可能在 iOS 上引起一些咬牙切齿。测试,测试,测试。

    研究

    确定网络音频支持(以及是否需要任何前缀)很容易:http://caniuse.com/#feat=audio-api(如果未显示所有 iOS 版本,请单击“显示全部”按钮)。在这里,您会很容易地发现 iOS 6.0 及更高版本使用 webkit 前缀支持 Web Audio。当我考虑使用 HTML5 或 CSS3 功能时,我可以使用... 是我工作流程的标准功能。有一个类似的 Ecmascript 功能站点(例如 http://kangax.github.io/compat-table/es5/)。

    考虑使用非核心插件(尽管这意味着您可以使用下面的第一个项目符号)。在 Cordova 插件库中搜索音频——有一对看起来很有希望:http://plugins.cordova.io/#/search?search=audio。另请查看 PlugReg:http://plugreg.com/search?q=audio。如果您需要同时在网络和设备上运行,您需要检测您所在的设备,以便了解是否使用插件与网络音频。 (就个人而言,现在将其抽象出来似乎是个好主意,这样您就可以拥有一个到音频生成后端的通用接口,然后可以根据设备的可用技术进行交换。)

    这就是说,我不知道这些插件是否能满足您的需求。网络音频可能是这里的最佳选择,但了解它是否在设备上运行良好的唯一方法是尝试一下

    快速迭代开发

    如果您愿意接受有限的调试选项(即仅 Weinre),请考虑使用 PhoneGap Developer 应用程序 (http://app.phonegap.com)。只要您不使用任何非核心插件,您就可以让应用在检测到代码更改时自动重新加载,而无需昂贵的构建周期。

    虽然我通常不建议这样做,但您可以通过在您的平台 www 目录中工作并使用 Xcode 进行部署来避免一些不必要的复制。请务必在使用任何 CLI 命令之前将更改复制回根 www 目录。

    调试

    现在使用 Safari 进行调试对于 iOS 混合开发来说是最好的。 (Chrome 开发工具更好,但它们适用于 Android...) [注意:如果使用 PhoneGap 开发者应用程序,这不适用。不幸的是,你必须使用 Weinre,这与 Safari 的调试器相差甚远。]

    不用担心登录到 Xcode 的控制台——放弃控制台插件的要求。而是担心登录到浏览器的控制台。 [仅在使用 Safari/Weinre 作为调试器时适用]

    考虑 GapDebug。他们有一个不会在每次应用退出时不断关闭调试器的工具,这可能会有所帮助。

    @qefzec 给出的alert 提示很好。您也可以使用window.location.reload()。 GapDebug 也可以帮助缓解这种情况,因为它通常可以在记录任何重要内容之前重新连接。

    确保对所有未捕获的异常启用中断。 (您可以在Debugger 选项卡中进行设置。)这有助于捕捉您甚至没有注意到的错误。 (也许您的间歇性网络音频问题可能会遇到这种情况。)

    回调在任何环境中都难以调试。在回调的顶部放置一个断点,然后让调试器继续执行(|> 按钮)。它会完全跳过你的回调代码——没关系。它会在执行时闯入您的回调。

    即使有了我们现在拥有的所有调试功能(还不能匹配原生),console.logalert 仍然是你的朋友。

希望对一些人有所帮助。混合开发可能是有益的,但它需要研究和对非本地调试工具的耐心。 CLI 在每个版本中都在改进,我所看到的一些针对 4.x 的内容将突飞猛进地改进 CLI。当然,你可以使用原生(如果你正在做大量的音频处理,你可能想要,甚至只是制作一个原生插件),但它也有许多相同的陷阱作为非本地开发,所以你不会有一个神奇的更容易的时间。 (我的两分钱。)


** 2014 年 9 月 7 日编辑 **


所以我在阅读您的原始帖子时有些失明,并错过了您实际上已经使用 Mobile Safari 在 iOS 上进行了一些测试。 我的错!!以下是这方面的一些注意事项:

Mobile Safari 与 UIWebView 完全一样。

Mobile Safari 的渲染应该与 UIWebView 渲染相同——也就是说,布局引擎是相同的。

Mobile Safari 使用 JIT 编译器将 JavaScript 性能提高 2-3 倍。该引擎提供给 UIWebView 实例,这意味着您在 Mobile Safari 中所做的任何优化都针对错误的引擎。

您可以在 Mobile Safari 中测试布局和一些“感觉”(如元素大小等)。

不要依赖 Mobile Safari 来测试性能。你真的需要成为一个 UIWebView。当然,由于所有其他浏览器都是 UIWebView 浏览器,因此您可以使用 Google Chrome 或任何其他 iOS 浏览器替代品(Opera Mini 除外)很好地估计这一点,但您将没有调试选项。

李>

iOS 8 看起来会改变这一点,但仅限于 WKWebView。有计划让 PhoneGap 与此一起使用,但我认为它们还有一些路要走(只有 iOS 8 会看到性能改进)。

还有一个需要注意的关键区别——在 Cordova 容器中操作时,DOM 中有一个额外的 iframe,它充当 web本机桥梁。它通常不会影响任何事情,但如果您调试 Cordova 应用程序并看到代码中实际上没有的 DOM 元素,了解它在其中做什么会很有用。

【讨论】:

我还没有听说过 GapDebug,但它看起来很有希望,特别是它在关闭设备上的应用程序时让调试器保持打开状态(这在 Safari 上非常烦人!)。感谢您的提示。 @Kerri 感谢您的详细回复。我想对这一切做出回应。不过有一条评论:我一直在设备上进行测试,只是在浏览器中,而不是在混合原生应用程序中。所以令我惊讶的是,目标设备上 iOS Safari 中使用的 WebKit 似乎与我使用 Cordova 构建应用程序时得到的 WebKit 不同。这是不正确的吗?如果正确,我将尝试了解如何知道我正在获取哪个 WebKit,如果不正确,则尝试找出混合应用程序与 Safari 中的不同之处。 另外,我一直使用 caniuse.com,它告诉我我的代码应该可以在 iOS 6.x+ 上运行(尽管现在需要 API 嗅探,因为无前缀 WebAudio 需要)。我一直认为,因为我找不到关于 WebKit 版本的更详细的信息,所以一旦包装在本机容器中,事情应该可以工作,尽管有一些可能的集成更改。最近我确定这个假设似乎是错误的,但我仍然不清楚。我的应用程序使用WebKit目标设备上以出色的性能运行。从这个意义上说,我从一开始就在目标平台上进行了测试。 哦,嘿,我才知道你是谁!看起来你的书是关于这个主题的书。我正在检查:) 虽然我很乐意再卖这本书,但你可能已经超越了它——它涵盖了很多 PhoneGap,但它并没有像音频那样详细您已经不得不处理 - 它使用媒体插件来进行音频捕获和播放,这就是它的结束。它确实讨论了本地化、文件 API、DOM 布局、其他核心插件(GPS、加速度计、网络信息、视频等)和一些第三方插件。因此,尽管我很高兴你能得到它,但我不确定它在这种情况下是否会对你有所帮助。现在我疯了!让我纠正一下:请买我的书!

以上是关于iOS“默认”UIWebView/WebKit 上的 WebAudio 支持的主要内容,如果未能解决你的问题,请参考以下文章

选项卡图标在 iOS 4 上更改默认颜色

JQuery 移动 IOS 设备如何在 web 上删除默认滚动

ios上表单默认样式

iOS 上 PDF 文档的默认纸张大小和单位

iOS:默认后退按钮显示在自定义左侧导航按钮上

JavaScript restdb.io codehook在POST上设置默认日期值