摘要:洞悉华为云数字化差旅App的架构变迁之路,体验混合开发魅力。
本文分享自华为云社区《DTSE Tech Talk 第21期丨从原生迈向混合,小而美团队如何搞定APP高效定制?》,作者:华为云社区精选 。
令开发者们心动的App端开发神器究竟长什么样?小而美的团队如何精准拿捏客户多元化定制需求,实现高效开发?在企业通用服务类App中,如何瞄准团队定位,快速engage客户?
近日,华为云DTSE技术布道师徐意带来了《揭秘华为云数字化差旅:如何用混合开发玩转高效定制》的主题分享。徐意与开发者们交流了华为云数字化差旅移动端APP从原生框架到混合开发的演进过程,以及如何通过React Native及Hybrid混合开发框架去提升开发效率,解决企业客户多样的定制化诉求,让开发者对混合框架的选择及可能解决的场景有一定的了解和认识。此外,针对中小企业混合开发实践,徐意也从团队定位、研发投入及生态构建等视角给予了专业的建议。
华为云数字化差旅,源于华为18年差旅管理实践,定位于企业差旅管理市场。依托“全场景、全流程、全数据”的建设思路,通过搭建一体化的数字化差旅管理平台,为客户提供从差旅申请、审批、预订、行中保障、报销及差旅分析的一站式出行服务,助力其实现精益管理、提质增效、安全合规,不断提升员工出行体验,使能企业数字化转型成功。截止目前,华为云数字化差旅服务范围已经涉及170+国家和地区,向全球480w+企业客户提供高品质服务,最终把数字化差旅带入每个企业、每个员工。
APP原生框架以性能高、体验好、功能丰富、稳定性高等特点而著称。但是由于其也存在开发成本高、移植性差、发布节奏慢等劣势,在现今越来越敏捷的交付节奏下,逐渐难以满足开发者及企业的诉求。
华为云数字化差旅在市场拓展过程中,随着企业客户的不断增加,多层面的差异性逐渐显现,差旅业务开发面临着诸多挑战:对接模式的差异、企业白牌定制、企业业务及个性化模块定制、企业差旅管理政策差异、企业紧急政策要求、多团队版本配合、特殊场景需求保障等等。在高频的项目交付中,“体验要好、交付要快、功能稳定、成本要低”成为客户的一致诉求。如何在持续满足客户需求的同时推进技术升级,也是当前差旅团队亟待思考的点。
从框架诉求、开发能力模型、维护成本3个维度出发,华为云数字化差旅开发团队综合评估了市面上主流成熟的混合开发框架,通过分析Hybrid、React Native、Flutter、Uni-app等框架的优缺点,结合实际业务诉求,先引入React Native框架去尝试解决业务交付难题。
差旅团队在项目中首先尝试通过相对简单直接的单RN包的方式引入React Native框架能力,之后尝试使用配套的热更新能力,实现整RN包热更新。通过前期的尝试,在一个新业务开发中,团队逐步体验到Android与iOS代码合一、效率提升、问题修复效率高等框架优势:
效率方面:实现两端一套代码的诉求,业务开发、调试效率显著提升;
性能方面:整体交互性能稍有下降,但综合体验符合预期;
难度方面:业务开发技能JavaScript,上手更快;
热更新方面:具备热更新能力,提升灵活性。
在引入React Native框架后,团队之前面临的种种客户交付跳转看似也有了可行的解决方案。但团队逐步在做去割接其他业务时,也浮现出一些新的框架问题:
除了以上框架问题之外,团队通过持续构建RN能力生态,不断提升客户个性化诉求的场景覆盖及交付效率:
差旅APP内应用场景的复杂多样性使得框架层面在一些场景上需要使用到webview模块的使用,即通过APP内置浏览器打开web页面给用户提供一些服务能力,团队总结为如下4类场景:
基于以上各类应用场景,差旅APP首先通过Android及iOS原生功能的开发及配置满足如支付等三方应用跳转场景及电话、邮件、相册、文件、定位、多媒体等能力场景,同时又进一步构建一套较完备的JSBridge方法库,将web页面所需的原生能力封装成API,包括界面交互类(如返回、刷新、导航栏等)、登录类(登录信息获取、实时登录等)、系统信息类(系统、版本、安全区域、设备id、暗黑、字体等)及其他功能类(分享、定位、跳转、业务功能等)。
在提供各类方法能力的同时,团队注意到web端的能力诉求涉及一定的敏感信息类,故在提供这类能力的同时,设计并构建了一套webview安全加固策略:域名白名单管控;JSBridge 方法管控;业务Token权限管控。
为持续支撑业务发展、提升用户体验、沿袭“全场景、全流程、全数据”的建设思路,华为云数字化差旅团队基于自身技能及业务特点,会始终保持研究投入。对于差旅App未来发展,给出了三个阶段的规划:
在最后的分享环节,针对中小企业在面临繁重、多元定制的交付需求等问题,讲师也从团队定位、APP框架选型、研发投入、生态构建、网络安全意识提升等方面给出了可行性的建议,希望开发者们能够依托混合开发玩转高效定制,快速响应客户需求,实现自身技术的迭代升级。
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack
在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/
我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为
我有一大串格式化数据(例如JSON),我想使用Psychinruby同时保留格式转储到YAML。基本上,我希望JSON使用literalstyle出现在YAML中:---json:|{"page":1,"results":["item","another"],"total_pages":0}但是,当我使用YAML.dump时,它不使用文字样式。我得到这样的东西:---json:!"{\n\"page\":1,\n\"results\":[\n\"item\",\"another\"\n],\n\"total_pages\":0\n}\n"我如何告诉Psych以想要的样式转储标量?解