65.9K
CodeProject 正在变化。 阅读更多。
Home

构建混合应用程序的历程与原生 iOS 开发的比较

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.90/5 (7投票s)

2016 年 2 月 16 日

CPOL

13分钟阅读

viewsIcon

25229

你有一个应用程序的想法,并决定自己动手,无论是独自一人还是与一小群人一起,而且你的应用程序开发没有得到专业组织。那么这篇文章非常适合你。上述背景正是我实现原生 iOS 和混合应用程序的背景。

使用混合方法而不是原生方法更具挑战性,但可能具有优势。

目标群体

你有一个应用程序的想法,并决定自己动手,无论是独自一人还是与一小群人一起,而且你的应用程序开发没有得到专业组织。那么这篇文章非常适合你。上述背景正是我实现原生 iOS 应用程序,然后又实现混合 Cordova 应用程序的情况。了解了这种背景和接下来的文章,你或许能够更好地判断自己实现混合应用程序的可行性。

动机

在你走向自己软件产品的过程中,你将面临 **如何将软件交付给客户** 的决定。我称之为 **软件项目中非常根本性的决定之一,而且事后很难改变——至少会引起相当大的努力和成本。** 因此,在走向一个方向或另一个方向之前,应仔细考虑以下方面:

  • 软件是否在移动场景中使用?
  • 是否需要支持不同的操作系统和设备,以及如何实现?
  • 是否需要集中服务或数据存储?
  • 软件是否需要特定于设备的功能?
  • 是否需要(持续)互联网连接?

我已经回答了我的两个软件开发项目中的这些以及更多问题。

对于一个微小的工具 DSTimeK,用于 Scrum 场景,我们决定将其作为移动原生 iOS 应用程序交付。请参阅 [这里](http://yaazone.com/blog/strategic-questions-and-lessons-learned-with-first-app-development-project-in-ios) 总结学习内容的博客。

基于第一个项目的经验,并回答了 FlAuMoQ(用于化学领域的学习软件)的相同问题列表,我们决定交付一个混合应用程序,该应用程序可在移动设备上本地运行。请参阅 [这里](http://yaazone.com/blog/itmeetsapo-working-title-a-platform-independent-app-to-be-used-in-private-context-and-build-with-business-software) 包含有关该决定的更多信息的博客。

本文将 **仔细审视 FlAuMoQ 所使用的混合应用程序方法,并最终反思这是否是正确的方法**。我将不讨论一般的(抽象的)差异。它将使用具体的需求,并解释实现这些需求的选项。基本上,你可以跟随构建混合应用程序的旅程的一部分,面对不同的挑战。

FlAuMoQ 中使用的技术组件

基于选择混合 Cordova 方法的决定,使用了以下组件。

总的来说,独立于目标交付平台

  • 使用基于 HTML5 和 Java Script 的开源库 [openui5-runtime-mobile-1.24.6.zip](https://openui5.hana.ondemand.com/downloads/openui5-runtime-mobile-1.24.6.zip)。
    顺便说一句:应用程序还决定使用 [openUI5](http://openui5.org/),但通常任何其他库,如 Bootstrap,都可以承担其部分功能。openUI5 库 intended to be run in the web browser,但也可以混合运行(参见 [这里](http://help.sap.com/saphelp_uiaddon10/helpdata/en/29/3eb945f0e945aaa776812481b4c533/content.htm))。
  • NetBeans 作为开发环境
  • 这些工件可在任何 Web 浏览器中执行

对于 iOS

  • 框架:cordova -v: 5.1.1,Cordova 平台版本 ios: 3.8.0
  • XCode 作为开发环境
  • 设备测试:iPhone 5s,iOS 版本 8.4.1

对于 Android

  • 框架:cordova -v: 4.3.0,Cordova 平台版本 android 3.7.1
  • Android Developer Studio 作为开发环境
  • 设备测试:Samsung Galaxy S2,Android 版本 4.1.2

适用于 Windows

  • 框架:cordova -v: 4.3.0,Cordova 平台版本 windows wp8
  • Windows Visual Studio 作为开发环境
  • 设备测试:Windows Lumia 640,Windows Phone 8.1 Update 2

根据平台的不同,使用了其他 Cordova 插件。下方是运行 FlAuMoQ 的真实设备图片。

FlAuMoQ 在 iPhone 5s、Samsung Galaxy S2 和 Windows Lumia 640 上运行

混合应用开发中的挑战

混合应用开发照常进行。使用你选择的库(我这里是 openUI5),你同时也选择了你的开发和运行时环境。该库提供了一组特殊功能,你可以用它来实现你的需求。在 Web 浏览器中实现和测试应用程序后,使用 Cordova 框架构建工件,使其可在不同设备上执行。与原生开发相比,使用上述技术组件组合的实现过程更具迭代性。仅仅因为使用了框架而产生的间接性。在这个过程中,需要克服各种挑战。

选择的自由 vs. 免于选择的自由

以下列表显示了满足 **发送电子邮件** 要求的不同选项:

  • 处理此要求的明显方法是使用你为应用程序选择的库。对于发送电子邮件,openUI5 有一个方法...
    sap.m.URLHelper.triggerEmail(sEmail?, sSubject?, sBody?, sCC?, sBCC?)
    ...(查看 [这里](https://openui5.hana.ondemand.com/#docs/api/symbols/sap.m.URLHelper.html) 的 API 参考)。在 Web 浏览器中使用此方法会打开操作系统电子邮件客户端。在 Android 上构建应用程序后,即使在 Android 模拟器中,也发现 `triggerEmail` 不起作用。有时这只是一个强烈的迹象,但不一定意味着它在设备本身上不起作用。但即使在设备上,使用给定的组件及其版本也未能成功。
    此时,“共享”远不止电子邮件,并且通过 Cordova 方法共享可能更有优势的想法已经成熟。

  • 发送电子邮件的下一个方法是通过库的“出口”。在 openUI5 中(其他库也有),有一个 HTML 容器,可以在其中传递类似这样的 HTML...
    <a href="mailto:me@me.com">email me here!<a>
    ...。此外,还有机会在 JavaScript 级别直接使用...编码。
    window.open('mailto: me@me.com?subject=subject&body=body');
    ...。在 Android 模拟器上两者都不会被解释。

  • Cordova 通过使用其核心插件(参见 [这里](http://docs.telerik.com/platform/appbuilder/creating-your-project/using-plugins/using-core-plugins/using-core-plugins))提供对特定设备功能的访问。插件的例子有“设备方向”、“相机”或“联系人”。不幸的是,发送电子邮件不属于其中。自定义插件 `de.appplant.cordova.plugin.email-composer` 提供了帮助。通过在 Android 设备上调用以下代码...
    cordova.plugins.email.open({ subject: sEmailTitle, body: sEmailText});
    ...显示了这个,它超出了要求的范围。
    Android 上的“打开方式”菜单并选择电子邮件
  • 现在,人们可能会认为需求已经实现,但测试也必须在交付所支持的所有其他平台上进行。在 iOS 设备上,自定义插件不起作用,因为它主要为 Android 构建。因此,根据平台的不同,会调用不同的电子邮件共享方法。对于 iOS,`triggerEmail` 在设备上有效,并显示如下:
     
    通过电子邮件在 iOS 上共享

    它没有显示如此漂亮的“打开方式”对话框,但发送电子邮件的要求得到了满足。
最终,这意味着根据设备的不同,需要进行不同的调用。而且,这里有不同的前进方向。可以通过类似这样的调用轻松实现...
if ( sap.ui.Device.os.name === sap.ui.Device.os.OS.ANDROID ) { ... do this ... }

...直接在库级别。

 

迭代各种选项的另一个例子是 **在新窗口中打开 URL 的要求**。这里的挑战在于,大多数调用最终都会进入“InAppBrowsing”,这并非期望的行为。当用户打开 FAQ 等补充信息时,应用程序应保持打开状态。长话短说,这些是有效的:

  • 在 Web 浏览器中
    sap.m.URLHelper.redirect(url, true);
  • 在 Android 设备上
    navigator.app.loadUrl(url, {openExternal: true});
    一个核心 Cordova 插件功能,仅由 Android 平台支持。
     
  • 在 iOS 设备上
    window.open(url, "_system");
    JavaScript 标准。
     
  • 在 Windows 设备上
    window.open(url, "_system");

与原生开发的不同之处在于(例如,仅使用 iOS 时),你没有那么多选择,并且在 iOS 不支持某些功能时可能没有替代方案。同时,原生开发环境可能提供更多发送电子邮件或打开 URL 的方法。

所以我的结论是:**混合开发让你在使用的组件的不同层面上拥有选择的自由,并且可能有更多解决需求的方法。它增加了必须处理的复杂性。**

调试与测试

使用混合方法 **需要在所有级别上进行调试和测试**。首先是在 Chrome Web 浏览器中调试和测试库,使用 Chrome 开发者工具。对于 Android - 然后在 Android 模拟器中,之后在 Android 设备上进行 JavaScript 调试,这可以通过 Chrome 和 chrome://inspect 或 weinre(参见 [这里](https://people.apache.org/~pmuellr/weinre-docs/latest/Home.html))实现。在 Windows 和 iOS 上差别不大。

对原生应用程序执行相同的操作要容易一些,但两种方式都可以。

使用混合开发的另一个大优势是 **第三方对核心应用程序的测试要容易得多**。为了进行测试,需要将工件,例如 iOS 的 `*.app`,提供给测试人员。原生开发应用程序的测试人员需要一个用户才能从商店下载工件,工件需要有正确的签名(证书/配置描述文件),他们的设备被注册为测试设备等等。混合测试方式只是将 Web 源代码放在 Web 服务器上,然后将 URL 发送给所有测试人员。缺点是只能测试核心(Web)应用程序。由于 FlAuMoQ 的设备相关部分和与设备的交互不是很多,因此这不成问题。

处理复杂性

由于选择的自由、调试和测试以及所有随之而来的努力,我(作为一个处理项目所有 IT 部分的“一人团队”)有时会将范围缩小到必需的最低限度。下面是为 FlAuMoQ 构建的屏幕概览。由于每个 Cordova 或特定于设备的绕行都意味着在添加另一个平台和设备测试时需要额外的努力,因此此处显示的所有功能都包含在核心 Web 应用程序中。

“阴阳离子查找器”(FlAuMoQ)的功能概览

有时,了解一个需求的复杂性会让人望而却步,不去尝试。这里的例子是复杂的广告集成逻辑。在实现 iOS DSTimeK 时,应用了以下逻辑。当应用程序打开时,会打开一个插页式广告,并在功能下方始终显示一个横幅广告。当用户点击“特殊临时免费功能按钮”时,会显示另一个广告,最后广告会移除 4 小时。这意味着要完成与 Apple Store 发送和验证请求、保存计时器以及动态显示广告或不显示广告的复杂协调。更不用说平台特定的差异了。

对于混合开发,由于上述原因,实现相同的功能变得过于困难,最终我只在功能下方显示了一个简单的 Google 广告横幅。

这里的主要信息是:**作为一个非专业级的混合 Cordova 程序员,你倾向于省略一些东西,仅仅因为它不容易或直观编程,并且需要大量努力**。

渲染或所见即所得

在应用程序中,某个时候使用了下拉框中的选择。库级别使用的控件称为 `sap.m.Select`。在 Web 浏览器中显示控件或使用 Cordova 和 Windows 平台运行时,它会打开一个覆盖窗口部分的小框架。

Select 控件在 Windows Phone 和 iOS 上渲染(覆盖全屏)

 

当 Cordova 解释控件并在 Android 或 iOS 设备上运行时,控件打开时会覆盖整个屏幕。我在其他几个地方也遇到了这种行为,例如使用 `SplitApp` 控件,即使我将其配置为具有固定宽度滑动进出,它也会占用整个屏幕。

 

**使用框架的混合方法增加了关于如何在相应设备上渲染平台无关控件的逻辑**。渲染可能与最初指定的不同。使用原生开发时,有原生控件,它们只有一个渲染器,例如 iOS 环境,因此它们的外观只有一种方式。你所看到的(一次)就是你得到的。此外,原生开发的“外观和感觉”更流畅一些。

一次编程,随处运行 - 示例:集成分析

为网站或 iOS 集成 Google Analytics 非常容易。只需调用 JavaScript `www.google-analytics.com/analytics.js`,然后在不同位置(主要是导航期间)调用 `ga_storage._trackPageview('/start);`,这在混合开发中也同样容易。区别在于 **混合开发只需一次,并且可以在所有设备上运行**。请参阅应用程序测试期间的页面访问的初始结果:

测试期间的 Google Analytics 结果

当然,这种重用优势不仅适用于 Google Analytics 的集成,也适用于整个实现。但值得一提的是,它给我留下了深刻的印象,因为它开箱即用,没有任何特定于设备的绕行。

额外的交付渠道选项

而且,拥有这样一个可重用的 Web 应用程序还有另一个优势。该应用程序,至少其核心功能,最终也可以仅作为网页提供,即使最初并非如此。只需将源代码放在网页上,即可在任何 Web 浏览器中显示。当然,然后为了(至少一点点)达到与应用商店功能对等,还需要拥有自己的支付流程以及必要的安全和身份验证流程。

同样适用于添加更多平台的努力。最后,我决定将 Windows Phone 8 添加到交付中。准备 Windows 的应用程序工件的努力包括执行以下操作:

  • 学习处理新的开发环境
  • 为所有必需的尺寸添加图标
  • 在应用程序上进行测试,特别是特定于设备的部件
  • 更改 Cordova 配置文件以使用新图标和一些 Windows 特定设置

现在,如果你认为例如 Amazon Fire 或其他平台会变得有趣,你可以 **稍后添加它,只需最小的努力**。

总结 - 两个项目后的经验教训

有了这两种方法的知识,我不会再用原生方式重写 DSTimeK。总的来说,软件的功能越不复杂,就越有可能实现为非原生应用程序。

使事情复杂化的是,你从一开始就知道应用程序的范围和所有需求。动画、性能、多平台、对图形的高期望、流畅的用户体验、使用设备功能(相机、GPS、动画、存储数据……)、与应用商店互动、使用(持续)互联网连接、维护工作以及所有这些通用的原生 vs. 混合质量都起着重要作用。

由于 FlAuMoQ 的复杂性相对较低,因此该方法被证明优于原生方法。该应用程序甚至可以完全作为 Web 应用程序运行,或者作为使用原生 Web 容器的混合应用程序运行——无需与设备交互。在这两种替代情况下,应用程序将在服务器上运行,并在移动浏览器中呈现。所使用的混合方法允许离线使用应用程序,将库本地嵌入 Cordova 中(提高了性能),并且可以使用设备功能,这使得它比替代的 Web 应用程序或使用原生 Web 容器的混合应用程序更好或更完整。

如果我不关心时间、金钱和资源,我会选择原生开发,仅仅因为渲染非常准确,使用起来感觉更流畅,并且提供了更多独立的控件。但由于情况并非如此,我会建议我背景中的任何人也选择平台无关的编程。

其他资源

© . All rights reserved.