30天App开发从0到1:APICloud移动开发实战

978-7-115-48273-0
作者: 邹达 李德兴
译者:
编辑: 杨大可杨海玲

图书目录:

详情

本书介绍如何通过APICloud平台快速开发一款APP,从介绍APICloud平台开始,从零搭建APP框架,对数据通信能力、js移动端应用、APICloud引擎架构、第三方开放平台服务应用发布和管理及更新迭代均有详细讲述。 随后详细对UI框架的使用进行分析,通过对热门行业的移动应用开发解决方案的介绍,让读者掌握真正的实战技巧——如何开发一款优质的APP。

图书摘要

版权信息

书名:30天App开发从0到1:APICloud移动开发实战

ISBN:978-7-115-48273-0

本书由人民邮电出版社发行数字版。版权所有,侵权必究。

您购买的人民邮电出版社电子书仅供您个人使用,未经授权,不得以任何方式复制和传播本书内容。

我们愿意相信读者具有这样的良知和觉悟,与我们共同保护知识产权。

如果购买者有侵权行为,我们可能对该用户实施包括但不限于关闭该帐号等维权措施,并可能追究法律责任。

著    邹 达 李德兴

责任编辑 杨大可

人民邮电出版社出版发行  北京市丰台区成寿寺路11号

邮编 100164  电子邮件 315@ptpress.com.cn

网址 http://www.ptpress.com.cn

读者服务热线:(010)81055410

反盗版热线:(010)81055315

请从这里开始您的旅程……


本书围绕APICloud平台,全面、系统、细致地讲述了App开发的相关内容,涉及平台工作原理、内部实现机制和应用开发技巧。本书涵盖了APICloud应用开发的必备知识,包括基础知识、关键技术、开发技巧和行业方案,并从实践角度出发,通过大量的实例代码、详细的操作步骤和丰富的开发截图,帮助开发者迅速掌握APICloud应用开发,有能力制作出好的App。本书是APICloud开发者的最佳入门指南,并配有免费的讲解视频,适合各种层次的APICloud学习者和开发者阅读。


一项技术价值的高低在于其能帮助客户弥补多大的技术差距。移动App已逐渐成为企业业务的基础设施,但移动开发人员的稀缺,导致大量的企业无法组建自身的研发队伍。雪上加霜的是,移动App距离客户更近了,还需要更快速地迭代。APICloud正是为弥补这个缺口而诞生的。尽管APICloud采用HTML5和JavaScript技术降低了开发难度,但仍需要开发者慢慢摸索。本书的出版解决了困扰开发者的问题,进一步弥补了传统企业与优秀互联网公司之间的技术差距。

——林路,北极光创投合伙人

本书是程序员写给程序员的,其中充满了程序员的风格——平实、纯粹,还有理性的乐观。我与本书的作者从各自创业开始,就持有一个共同的理念:App开发平台(乃至操作系统)应该高效、开放、跨平台、功能丰富。本书是这一理念最为具体的说明,而APICloud和中科创达这两家公司,也是该理念的见证者。我会将本书推荐给我的同事、朋友、合作伙伴和客户阅读。事实上,我已经在这么做了。

——邹鹏程,中科创达CTO

和APICloud 的小伙伴们相识好几年了,一直在用他们的平台做各种智能硬件相关的App,也和他们一起举办过面向开发者的社区活动。APICloud CEO刘鑫在用户体验和服务上对细节的无限追求,APICloud CTO邹达在技术上精湛的造诣,让大家用上了一款优秀的产品。早就觉得他们应该出一本书了,所以这次收到样书一点也不意外,更是几乎一气呵成地读完,感觉这本书应该叫“30天App开发从0到100”。本书的内容丰富翔实,包含了 App的规划、开发、调试、性能优化、上架等方方面面,还有数个不同行业的应用范例。无论是App开发的新手,还是“老鸟”,本书都会给你带来全新的知识和视角。在智能设备端,跨平台App已经成为一个不可逆的趋势,而APICloud则是我们的首选!

——刘琰,机智云CTO

这是一本面向初学者但同时又会让有经验的开发者快速晋级的书。我在大学里接触最多的就是新入学的“初级码农”,通过本书可以让他们迅速成长为可以交付App产品的开发者。这种学习体验,对他们重新理解开发的含义以及建立对IT学习的自信心都有极大帮助。另外,以App实现为导向的面向API的编程方法也是我个人非常推崇的一种开发趋势。

——梁震鲁,齐鲁工业大学网络信息中心副主任,国家高级职业指导师,APICloud社区优秀讲师

我一向认为一本计算机类图书的作者,如果能够务实地站在App设计者的角度去思考问题,深入理解问题之间的相互关系,并且会针对程序员经常遇到的关键知识做通俗易懂的阐述和丰富的实例验证,那么他给读者带来的不仅是知识,还有良好的程序员思维。希望本书的读者能够从中领会作者的良苦用心。

——孙增斌,英特尔在线业务平台总监

本书是一本很好的开发入门教程,通俗易懂、由浅入深,并提供了丰富的实际案例,详细介绍了如何使用前端开发语言和丰富的APICloud平台扩展模块来跨平台开发移动App。相信每位读者都能从本书中汲取相应的知识,它也将帮助我们的开发团队更好地开发移动App!

——丁美玲,泛亚汽车技术中心高级主任工程师

APICloud平台以独有的快速App开发方式,将移动开发中的软件复用提升到一个新的高度,可以帮助企业在短期内打造出满足业务需求的App,这一点我在实际使用中有切身的体会。本书语言平实流畅、实例内容丰富,是对APICloud生态的又一巨大贡献,也是我们移动开发人员的福音。读读本书,相信你一定会喜欢的!

——刘殿兴博士,中信证券信息技术中心高级副总裁

移动互联改变了人们的生活,更给企业带来经营模式的转变和新的商机。在这一过程中移动App发挥了重要的作用。但是,对一般的非IT企业而言,高效建立App并不断地更新、维持运行,会使企业担负很高的成本。直到有一天,我偶然发现APICloud,它让我非常欣喜。APICloud是中国领先的“云端一体”移动应用云服务开发平台,能够满足移动创新者和传统企业移动化这两个市场的App开发需求,并可以为开发者提供高效App开发和平台管理的一站式服务,包括开发、API集成、测试、渠道打包、运营管理的App全生命周期等。它已有数以万计的成熟开发接口、多个行业的应用模板以及一些优秀开发者提供的快捷功能组件。APICloud已经服务于很多行业的企业客户,并为客户带来省心、安心的App定制开发服务。如果你还在为企业的App开发而烦恼,那就试试APICloud吧,一定会让你取得事半功倍的效果。

——周伊丽,光大银行电子银行部副总经理

APICloud平台是目前开发App最高效的平台之一,本书详尽地讲述了如何通过APICloud平台快速开发一款优质的App,里面有大量的图文案例并配合实战讲解,通俗易懂,容易上手,非常适合初学者学习。

——朱亮,春秋航空运营总监

作为最早一批APICloud的使用者,还记得当初相识的关键字“30天从0到1”,这句话并没有吹牛,我们用APICloud很快就完成了“战旗”的开发,并且经受住了百万日活用户的挑战。我已经好久不写代码了,翻阅本书发现许多当初期望的功能都被逐一实现,只能感慨现在的APICloud用户太幸福了。请记住,当你有想法时,一定要用APICloud启航。

——潘长煌,全民直播CEO


可能很多人不知道,规模大的企业和IT预算多的企业的移动App大部分都是基于混合模式开发实现的。

很多做App开发的技术人员会存在一种偏见,觉得“采用混合模式,基于HTML5技术开发出来的App,体验以及功能会和原生模式开发的存在差距”,所以更愿意使用原生模式开发App。

其实市场上主流的App,绝大部分是基于混合模式开发的。最典型的就是微信,除了聊天功能以外,包括公众号、小程序等都是由混合模式开发技术实现的。再比如电商领域的淘宝、京东等,旅游领域的携程,教育领域的VipKid,信息分类的58等不同应用范围的App,混合模式开发技术使其商品展示及线上市场活动的运营管理都变得非常灵活。此外,在航空、保险、银行等行业中,无论是服务客户的toC模式App,还是对员工进行管理的toE和toB的App,多是使用混合模式开发的,混合模式开发技术成为了绝对主力。

人们不禁要问“为什么这些公司和企事业单位,有着足够的预算和开发资源,还要选择混合模式App开发技术作为企业互联网化的支撑?”答案其实和企业的互联网化及数字化的需求有着直接的联系。以下4个方面,决定了越有实力的企业越需要混合模式App开发技术;同时,也是混合模式App开发技术形成不同行业解决方案的根本优势和企业选择的必要性所在。

“试错”这个词不但在互联网公司中广为流传,在传统公司的互联网化过程中也被广泛接受。

越来越多的CIO在谈各自企业移动战略的时候,都会提到“能否根据业务部门的一个想法,先在一周之内做个原型,快速实现,拿出去让大家看看,然后基于这个原型再修改”。这种快速发起、快速验证、快速调整的方法,已经非常流行。之所以要在短时间内先把业务从想法落到现实,哪怕App粗糙些,也要先实现出来,原因在于具有鲜明企业个性的业务的创新想法可能没有先例可循,很难考虑得特别完整。与其花费三五个月不停地思考业务需求,还不如用一两个星期先把基础的想法落实。哪怕短时间内做出的App并不能真正满足业务的需要,但是可以让业务人员的想法在这个过程中变得有据可依、有的放矢,从而为实现更完整且更切实可行的业务方案先行探索。

“业务部门的一个想法,IT部门一两周就做出来了!”这对于企业的信息化负责人而言,是很重要的褒奖。这种对速度的要求,恰恰是混合模式开发技术最明显的特长和优势,一套代码可同步生成iOS与Android两个平台的App,甚至还能部分兼容微信公众号和小程序。一套代码,并不代表偷懒或工程技术的简化,而更多的是因其不仅节省了代码编写的时间,还避免了多个技术团队之间跨知识结构的协同问题,不再需要iOS与Android工程师们开会讨论差异性问题,更是大幅节省了App与服务器端联机调试的时间成本。但如果同样的功能,同样从零开始,使用传统的原生开发技术基本没有办法在一两个星期内完成有价值业务需求的实现,因为这个时间可能连不同终端碎片化和差异化的问题都不足以解决。所以,CIO为了满足业务发展的需求和数字化速度的要求,在移动战略中往往都会规划使用跨平台的混合模式App开发技术。

在PC时代的B/S架构中,想要实现IT系统的更新并不需要过多地考虑用户端的影响。因为作为用户入口的浏览器一直处于访问网络的状态,只要网络连通,用户随时访问网站都会获得最新的功能和业务。对用户而言,并不真正地存在版本的概念。只要访问服务器,服务器的任何更新都可以随时展示到用户界面上,出现使用问题时,往往只需要清空一次浏览器Cookie基本就可以解决。

但是在移动时代,用户对版本的概念变得越发敏感。而对App的版本管理也成了CIO头痛的问题。通常因为软件开发商能力的制约,或者一些无法避免的bug,让一些已发布的App变得难用甚至会崩溃。此外,一些临时的市场活动、很少但重要的功能、一些不在规划内的产品需求调整等情况,都会直接引出同一个问题“用户必须更新一个版本,重新下载安装,才能满足上述需求”。这种看似日常的版本发布和用户更新,恰恰是传统企业信息化过程中面临的全新问题。

“能否像传统浏览器那样,用户打开的永远是最新的服务和功能?”很多企业的CIO问出了相同的问题,于是大量的、不合规的软件服务商和IT程序员想出了一个“偷懒”的模式。在App中嵌入一些WebView,将一些功能采用传统网页的模式,访问服务器,动态获取。虽然表面上解决了版本更新的问题,实则产生了大量体验很差的App。

企业对业务灵活性的要求,本质是希望像微信小程序一样,可以随时发布一些新的功能,随时动态增改一些功能的入口,让用户任意使用,同时让用户的体验更好。这种对业务灵活性的需求其实需要像小程序一样有强大的混合模式App开发技术来支撑。从而达成“增量更新”“静默更新”“打开获得新功能和新体验”,而不是嵌套WebView,用网页模拟App的方法,以较差的用户体验的代价换取业务灵活的可行性。

当然,目前传统模式开发的App,特别是用Android开发的App也开始部分支持动态更新。这也恰恰说明,业务灵活性是企业互联网化、数字化进程的刚需。只是由于传统技术的制约以及软件开发团队或者服务商能力的限制,真正的原生动态更新始终没有办法大规模进入企业,实现商用。这也让企业对混合模式App开发技术的需求更为迫切,成为每个CIO的必备选项。

业务部门的互联网化意识是因为互联网的广泛普及被带动起来的。所以,传统的由IT部门主导企业信息化的态势发生了微妙的变化。过去,都是由IT部门发起信息化需求,但现在的IT部门越来越像“服务部门”。因为业务团队在不停地发起各种各样“业务+互联网”的信息化需求。这个时候,很多传统企业的IT部门领导,没认识到自己角色的转变,如果还存有拖延、不管不问、你们自己搞不定等类似的想法,就会导致当下很多企业的信息化面临的“各种移动App的彻底碎片化”“各个业务部门自己找软件开发商实现各自的需求”等问题。这不但架空了IT部门的信息化主导地位,更麻烦的是,让后续的集中管理变得艰难无比。几十家甚至上百家不同标准的服务掺杂在企业的核心系统中,甚至有些业务部门为了快速满足自己的需求而脱离了IT部门主导的传统PC核心系统,这些操作都是非常危险的。

IT部门在被业务部门要求满足业务的互联网化需求时,往往发现心有余而力不足。IT部门人手有限,实在没办法逐一满足所有业务部门的移动化需求。如果不管,就会产生前面所提到的“技术栈、开发商”碎片化的问题。这个时候,基于混合模式App开发技术的移动应用平台,就很好地解决了这二者之间的矛盾。

定标准,从而实现“集中管理”。如果企业能够制订一套统一的混合模式App开发技术和移动平台标准,各个业务部门就可以独立寻找自己的软件开发商,用各种方法满足自己的移动业务需求。平台的一致性可以带来标准化的统一。这其中包括技术标准化、开发流程标准化、代码管理标准化、项目管理标准化、验收标准化、管理和运营标准化等。

既要放,也要抓。这就是互联网时代企业信息化的要求,更是IT部门的职责。混合模式App开发技术,有望成为实现企业移动战略的利器之一。

企业互联网化带来的最根本转变就是,内网的信息化变成了外网的互联网化。

传统信息化一般包括内网、固定场所、固定网络环境和固定的设备等关键词。而移动战略背景下的企业互联网化,则同时包括外网、随时、随地、员工个人设备、4G和Wi-Fi等关键词。这些不起眼的变化,给企业的业务带来的却是天翻地覆的调整。

移动设备管理软件(Mobile Devices Management,MDM)曾风靡一时,但是购买了MDM的企业几乎无一例外地发现其很难推进。因为MDM伴随着员工自带设备(Bring Your Own Device,BYOD)。如果用企业的管理软件来管理员工个人设备,肯定会有很多人反对。所以,大部分的MDM最终草草收场,只是管理了企业自己购买的一些移动设备。

企业移动化、互联网化的安全怎么保障? 这要满足3个层面的安全,即设备安全、传统安全和云端安全。

混合模式App开发技术可以实现类似于企业应用商店(如微信公众号)的动态权限绑定和授权模式,能够支持特定设备、特定的人,也可以选择不同的子应用。此外,还可以实现随着用户工作内容的调整,根据设备编码和用户权限来实时分配全新子应用的功能。

这种基于企业移动应用商店的“子应用”模式,也是混合模式App开发技术成为企业移动战略支撑的关键。因为做得好的企业应用商店,不仅能够满足传统原生模式开发的App所不能赋予企业的、对各种安全性的需求,还实现了对业务灵活性的管理目的。

APICloud作为中国主流的混合模式App开发技术服务提供商,一直在以布道者的身份推进混合技术在国内的发展和应用。我们不仅提供技术,也提供商业服务,因此会更多地深入到大量的商业用户中去,如海尔、春秋航空、英特尔、中信证券、上汽等。我们的团队结合不同的商业场景和实际的商业客户需求,编写了本书,希望能够为不同规模的企业在移动信息化和互联网化进程中提供有价值的参考,同时也能够让从事App开发的技术人员有更多可借鉴的实战经验。

刘鑫

APICloud创始人兼CEO

2018年3月于美国硅谷


时光荏苒,转眼间APICloud上线已经有3年多的时间了,在这3年多的时间里,APICloud凭借自身的技术优势和坚持做好开发者生态的信念已经聚集了众多的APICloud开发者。多年开发者的经历让我们理解开发者,也深刻认识到任何一个平台或技术都不是三言两语能说清楚的,要想让开发者快速掌握APICloud应用开发、少走弯路,我们需要编写出一套全面、系统、细致的开发指南。这个想法一直都有,但是随着平台完善、引擎优化、API扩展和生态产品研发等工作的开展,开发指南的编写工作迟迟未能完成。这里也向广大开发者表达歉意。

自从2014年9月15日APICloud平台上线以来,APICloud开发团队一直坚持每周更新一个版本,快速迭代,3年多时间从未间断。现在APICloud平台稳定,功能齐全,生态繁荣,社区活跃,开发者越来越多,要写出好App的需求也越来越迫切,这些让我们感到兴奋的同时,也备感压力。我们必须把自己的设计思想、意图和经验写出来,以满足开发者对技术的热情和渴望,节省开发者宝贵的学习时间,同时也能指导开发者制作出优秀的App。

APICloud是一个功能强大的开发平台,涉及的技术范围很广,虽然是自己亲手设计的产品,也非常清楚开发者需要获知的核心知识,但是,想要把书写好也并非易事。作为官方出品的第一本介绍APICloud的书,如何合理安排内容,如何能够由浅入深、循序渐进地展开,如何才能最快地帮到开发者,这些都让我们反复思考,一遍遍地梳理各个知识点之间的关联。章节的编排确实让我们很费脑筋,这也许就是理想与现实之间的差距吧。本书的作者都是APICloud一线开发工程师,均为纯粹的程序员出身,编码水平稍有自信,但是文学情调基本为零。在本书中,我们力求用通俗的语言来讲述原理和机制,用简洁平实的语言来描述使用流程。但是,本书内容编排上可能还存在不足,用词可能还不够准确,文笔可能还不那么优雅和流畅,这些还请广大读者谅解。

APICloud以新的思想、新的技术、新的模式和新的工具来加速移动应用开发,并且让广大的Web开发人员能够快速成为App开发专家。在本书中,我们会尽可能地通过详细的操作步骤、平实的语言、大量的实例代码和丰富的插图来讲清楚每一个知识点,并且给出大量的开发技巧以适应不同的场景,迅速提高开发者水平。除了介绍应用层开发外,我们还通过增加对原理的剖析,让开发者了解平台的内部工作机制,理解APICloud App设计的原理,从而掌握APICloud 的App开发方式和设计原则。

APICloud团队是国内较早进行Web与Native技术融合的实践者,10多年来见证了混合开发技术在国内“悄悄地、慢慢地”火起来的全过程。APICloud拥有行业领先的高性能App混合渲染引擎,APICloud模块Store汇集了目前App开发需要使用的几乎所有主流API,并一直在持续更新。我们希望能把一切好的功能加入到APICloud平台,目的就是能真正帮助开发者提高效率,降低成本,解决问题。

访问APICloud平台官网,注册成为APICloud开发者,开始APICloud的开发之旅吧!

本书分3个部分,一共包括16章和2个附录。

第一部分是基础教程,适合APICloud初学者。通过第一部分的学习初学者可以了解APICloud平台,熟悉APICloud云控制台操作和开发工具的使用,掌握开发一款App必须具备的核心知识点、常用API和基础开发技巧,可以有能力独自完成一款简单App的开发。读者在学习过程中可以跟随示例代码一步步自己练习,再结合视频讲解学习APICloud应用的设计思想,理解APICloud开发模式,从而找到理解APICloud App开发的正确方法和学习模式,为以后有能力开发大型的复杂App打下基础。

这一部分以一款实际案例的开发过程为例,所涉及的核心知识和编码技巧是开发一款优APICloud App的必备技能,初学者一定要深刻掌握。有一定APICloud开发经验的读者也可以通过这一部分的学习,加深对APICloud应用设计思想和开发模式的理解,对APICloud知识体系有一个更全面的认识,巩固APICloud核心知识点的使用。

这一部分共7章。第1章是一个非常全面的初学者入门教程,对APICloud平台、APICloud App开发流程、学习方法、学习资源做了全面的介绍。第2~7章详细讲解如何从零起点开发一款App,以一个电商O2O App为例,从创建App开始,一步步为其丰富功能,直到开发出一款完整的App。在这个过程中演示了一个APICloud App开发的标准流程,贯穿讲解了APICloud App开发过程中需要使用的所有核心知识点,包括界面布局、网络通信、数据存储、模块扩展和开放服务调用等。

虽然这一部分的内容是根据“APICloud 7天培训课”的课程讲义和视频讲解整理而成的,但是本书对讲义和视频的内容进行了重新梳理和结构优化,确保知识体系的组织更加系统清晰、技术点的阐述更加全面细致、语言描述更加准确。

第二部分的实战技巧是App开发的进阶内容,适合已经具备一定APICloud App开发能力的开发者。这一部分讲述的实战技巧是由诸多一线资深APICloud开发工程师从实战角度出发,总结多个项目经验,由浅入深精心提炼而成。这一部分的主要用意是抛砖引玉,让读者多角度、深层次地发掘APICloud所蕴含的技术能力和技术潜力,从而能够开发出更优质的App产品。

这一部分共5章。第8~11章的每一个实战技巧都可以作为一个独立的APICloud App运行,完整的示例代码和工程配置说明可以在本书的GitHub仓库中下载。读者既可以将其当作一个学习参考的Demo,也可以直接将其应用到具体App项目中,以实现具体的功能需求。第12章主要介绍开发APICloud App的调试技巧,以及常用调试工具的使用。

第三部分是行业应用,向读者介绍APICloud针对不同行业提供的解决方案,阐述为什么越是有实力的企业越需要使用混合模式App开发技术,以及混合模式形成的不同行业解决方案的根本优势和企业选择的必要性,并且列举了主流行业应用中被高频使用的几种模块和API。这一部分共4章(第13~16章),分别介绍IoT、教育、直播和电商这4个领域。

附录A为APICloud App客户端开发规范(Version 1.0),主要总结提升程序质量、App性能及用户体验的开发规范。

附录B为开发工具APICloud Studio 2使用详解,是对这款云端一体的全功能集成开发工具的详细使用说明。

本书配套免费的“APICloud 7天培训课”的完整视频教程(共约70讲)。“APICloud 7天培训课”第1~7天的视频讲解与本书第一部分第1~7章的内容是相互关联的,读者可以通过扫描二维码来观看这一视频教程。

本书的项目源码和资源都放在GitHub仓库1里。我们后续也会通过这个开源分支来更新代码和教程,解决读者所提出的问题,并进行后续版本的适配和代码的优化。

1GitHub搜索框内输入“apicloud 30-APP-0-1”即可。

APICloud一直坚持支持多开发工具的策略,开发者可以使用任意一款自己喜欢的主流编码工具来开发APICloud App,只需要在这些工具中安装相应的APICloud插件就可以了。目前APICloud支持的开发工具包括Atom、Sublime Text、Eclipse、WebStorm、VSCode等。本书通篇使用APICloud Studio 2作为开发工具,APICloud Studio 2是一款基于Atom进行扩展的全功能集成开发工具。读者可以阅读附录B来了解这款工具的详细使用方法。

由于编写时间仓促,书中难免会出现一些错误或者不准确的地方,恳请读者批评指正。如果您有更多的宝贵意见,欢迎到APICloud开发者社区2和我们进行互动和讨论。

2在APICloud官方网站点击“开发者社区”即可。

邹达

APICloud联合创始人兼CTO

2018年3月21日


本书由异步社区出品,社区(https://www.epubit.com/)为您提供相关资源和后续服务。

本书提供如下资源:

要获得以上配套资源,请在异步社区本书页面中点击 ,跳转到下载界面,按提示进行操作即可(本书视频为扫码观看)。注意:为保证购书读者的权益,该操作会给出相关提示,要求输入提取码进行验证。

作者和编辑尽最大努力来确保书中内容的准确性,但难免会存在疏漏。欢迎您将发现的问题反馈给我们,帮助我们提升图书的质量。

当您发现错误时,请登录异步社区,按书名搜索,进入本书页面,点击“提交勘误”,输入勘误信息,单击“提交”按钮即可。本书的作者和编辑会对您提交的勘误进行审核,确认并接受后,您将获赠异步社区的100积分。积分可用于在异步社区兑换优惠券、样书或奖品。

我们的联系邮箱是contact@epubit.com.cn。

如果您对本书有任何疑问或建议,请您发邮件给我们,并请在邮件标题中注明本书书名,以便我们更高效地做出反馈。

如果您有兴趣出版图书、录制教学视频,或者参与图书翻译、技术审校等工作,可以发邮件给我们;有意出版图书的作者也可以到异步社区在线提交投稿(直接访问www.epubit.com/selfpublish/submission即可)。

如果您是学校、培训机构或企业,想批量购买本书或异步社区出版的其他图书,也可以发邮件给我们。

如果您在网上发现有针对异步社区出品图书的各种形式的盗版行为,包括对图书全部或部分内容的非授权传播,请您将怀疑有侵权行为的链接发邮件给我们。您的这一举动是对作者权益的保护,也是我们持续为您提供有价值的内容的动力之源。

“异步社区”是人民邮电出版社旗下IT专业图书社区,致力于出版精品IT技术图书和相关学习产品,为作译者提供优质出版服务。异步社区创办于2015年8月,提供大量精品IT技术图书和电子书,以及高品质技术文章和视频课程。更多详情请访问异步社区官网https://www.epubit.com。

“异步图书”是由异步社区编辑团队策划出版的精品IT专业图书的品牌,依托于人民邮电出版社近30年的计算机图书出版积累和专业编辑团队,相关图书在封面上印有异步图书的LOGO。异步图书的出版领域包括软件开发、大数据、AI、测试、前端、网络技术等。

异步社区

微信服务号


本书能够顺利完成,得到了很多同事和朋友的帮助。

感谢人民邮电出版社对APICloud平台的大力支持。

感谢人民邮电出版社信息技术分社社长、异步社区掌门人刘涛老师在2018 APICloud开发者大会上现场宣布本书预售。

感谢人民邮电出版社杨海玲老师对本书的支持。我们和海玲老师很早就认识,她有丰富的图书策划和出版经验,这次能与她合作非常开心,合作过程也很愉快。感谢海玲老师在本书的编写过程中(从内容组织到最终成稿)给予的悉心指导。

感谢我们的同事尚德聚、颉彬、王梦吉等参与了本书第二部分实战技巧的编写。

感谢广大的APICloud开发者,正是与你们的交流和互动造就了APICloud社区的繁荣,也是你们的需求和应用推动着APICloud平台的不断完善和快速迭代。

感谢所有参与本书不同阶段书稿评审和代码验证的人。

感谢Sean和May,我们相识多年,一起创业,没有你们的唠叨和压迫,我很难按时完成本书的编写。


在这一部分中,第1章将对APICloud平台做一个整体的介绍,包括平台能力、开发模式、学习资源和开发者社区等,之后会介绍如何使用APICloud完成一个最简单的App的完整开发流程。

第2~7章将带领读者从零起步去开发一款O2O类型的电商App,其中会涉及APICloud开发的基础理论和常用技术,帮助读者快速入门。对于第一部分的整体内容,建议读者结合随书附赠的视频教程去学习,理解课程当中讲到的每个技术细节,然后再亲手练习。学会这些内容,就有能力去独立开发一款App了。

第一部分的项目源码和所有资源在GitHub库1 里。我们后续也会通过这个开源分支来更新代码和教程,解决读者所提出的问题,并进行后续版本的适配和代码的优化。

1GitHub搜“apicloud30-APP-0-1”。


主要内容

本章从总体上介绍APICloud平台,包括APICloud应用的开发模式、设计思想、控制台使用流程等,并以一个HelloWorld App为例让读者体验一个完整的APICloud App的开发流程。

学习目标

(1)了解APICloud平台,了解APICloud相关的学习资源、入门资料和常见的问题。让没有接触过APICloud平台的读者,对平台有一个基础的了解;让学习过APICloud并且已掌握一部分技能的读者,通过本章的学习,可以快速找到需要的资料和解决问题的方法。

(2)学习如何在APICloud平台上创建、修改、调试、编译和运行一个最简单的APICloud App。掌握APICloud App完整的开发流程。

要对APICloud平台做一个全面的介绍,需要花很长的时间和很多的篇幅来讲解每一个细节,而本书作者希望能用更多的篇幅来讲解一个App的实际开发过程,讲解具体的代码实现。所以,本章在介绍APICloud平台的时候,是通过抛出一个个问题,然后告诉读者应该到哪儿去找对应的学习资源,到哪儿能够找到解决问题的方案。

本章将从APICloud可以做什么,如何获取使用帮助,APICloud的技术、产品和生态等多个方面对APICloud平台加以介绍。

开发者在接触一个开发平台的时候,通常第一个想法就是去查看这个平台的能力。特别是那些想做App的、有着明确需求的开发者,他们会非常关心自己的需求在这个开发平台上是否能够满足。所以,本书开篇就先来解决这个开发者普遍关心的问题,读者可以带着自己预先想好的需求来了解APICloud平台,了解如何能够快速地在APICloud平台上查找相关的能力。

1.通过官方文档快速搜索功能模块

查看APICloud平台提供的能力,一个最基础也是最有效的方法就是查看APICloud的API文档。

APICloud官方网站中的文档页面如图1-1所示。如需要查看视频播放的功能,可以在文档中搜索“视频播放”,搜索结果如图1-2所示,可以看到在APICloud平台上有多种提供视频播放功能的模块,如videoPlayer(播放本地视频)、moviePlayer(播放网络视频)、polyvPlayer(保利威视播放器)、baiduPlayer(百度播放器)等。

图1-1

图1-2

点击其中一个搜索结果,查看模块的详细文档。比如点击“videoPlayer”之后可以看到这个模块对于视频播放提供了很多API,这些API基本覆盖了一个视频播放器所有常见的功能,如图1-3所示。

图1-3

再比如要查找支付功能,可以在文档中搜索“支付”,通过搜索结果可以看到在APICloud平台上有很多个提供支付功能的模块,如aliPay(支付宝)、wxPay(微信支付)、unionPay(银联支付)、paypal(PayPal支付)、iap(iOS应用内支付)等;也有ping++、beeCloud等第三方聚合类的支付模块。点击每个模块均可以查看具体的API详情。

读者想了解APICloud平台有哪些能力,最简单的方法就是到APICloud官方文档中去搜索相应的功能,这样就可以一目了然地知道APICloud平台有没有相应的模块来支持自己想要的功能。

2. APICloud能力支撑体系

目前在APICloud平台上已经提供了600多个模块,上万个API。这些API基本可以覆盖一款App所需的所有常用功能,为方便表述,它们被分为“平台使用”“基础功能”“界面布局”“设备特性”“功能扩展”和“开放服务”六大类,其分类与具体包含内容如图1-4所示。

图1-4

很多APICloud初学者会关心这些问题:APICloud App的开发模式是什么样的、使用什么技术语言、目前自己的开发团队是否适合使用APICloud开发App、整个APICloud的学习曲线是什么样的、入门简不简单等。

1.开发模式和技术语言

APICloud应用的开发模式是使用标准的HTML、CSS和JavaScript+APICloud扩展API来进行App开发,如图1-5所示。APICloud的App开发使用的是标准的HTML5技术,针对标准HTML5所不具备的功能或是用HTML5实现体验不好的功能(这些功能也是开发者在App开发过程中非常常用的功能)。APICloud提供了600多个扩展模块和上万个API,通过这些模块和API来扩展HTML5的功能,满足App的开发需求。

图1-5

2.扩展API调用方式

APICloud扩展API的调用方式与调用标准的JavaScript方法是完全一样的。APICloud引擎的核心API是放在window.api这个对象下面的,这个对象是APICloud在JavaScript全局作用域内扩展的唯一一个对象,可直接调用。如果想调用某个模块下面的方法,可以通过require的方式动态引入,通过在api.require方法的参数中指定某个模块的名称来引入相应的模块,然后调用模块下面的方法,具体演示如下。

  //核心API在window.api对象下,可以直接调用 
  api.methodName(param, callback); 

 //扩展模块需要require引入,遵守CommonJS规范 
  var module = api.require('moduleName'); 
  module.methodName(param, callback); 

  param: {} //参数,是一个JSON对象 
  callback: function(ret, err){} //回调函数,是一个Function对象,异步方法调用的结果通过此函数返回

所有API的调用方式都是相同的,第一个参数是一个JSON对象,承载着要传递给模块的信息;第二个参数是一个callback函数。APICloud大部分的API调用都是异步方式,在调用的时候,要指定一个callback函数,当这个API操作完成时,操作结果将通过该callback函数回调。

一些常用的调用方式,比如打开一个新窗口,可以调用api.openWin();打开通讯录可以调用api.openContacts(),录音、图片缓存等也是调用相应的方法。如果想去加载文件系统模块,可以通过api.require("fs")来加载fs模块,然后调用fs模块下面的方法。使用条码扫描模块也是类似的。示例如下。

APICloud技术是基于标准的HTML、CSS和JavaScript技术,并在标准的JavaScript基础上扩展了一个核心对象-api对象和数百个模块。这些模块可以使用api.require函数载入,并使用操作标准JavaScript对象的方式调用上述模块列举出方法。

3.扩展API的作用

读者可能会问,APICloud为什么要扩展这么多API呢?其实APICloud所扩展的API都是标准的JavaScript所不支持的方法,或是用标准HTML5来实现但体验不好的功能。读者可以把HTML5理解成一门技术、一门语言,但是它还没有达到一个平台的水平。这就是APICloud为什么要做这些扩展。APICloud所有的扩展主要是围绕以下这4个方面进行的。

总的来说,APICloud扩展的所有功能都是标准HTML5所没有的,如果HTML5有并且在App中运行起来没有任何问题,APICloud平台也没有必要去做这个扩展。APICloud所有扩展的功能其实就是为了去解决HTML5在兼容性、实用性、持续性和扩展性等方面的问题。

4.模块Store

在APICloud模块Store中可以查看APICloud平台扩展的所有功能,如图1-6所示。

图1-6

5. APICloud平台定位

APICloud是一个中间层,是在应用程序和系统之间的一层,在这一层中,APICloud聚合了开发一款App所需要的所有系统调用、开放服务和扩展功能,然后以统一API的形式提供给开发者调用。这就是APICloud平台的定位,如图1-7所示。

图1-7

这部分有大量的内容需要给读者介绍,但是本书不想为此占用大量的篇幅。读者可以通过APICloud官网公开课的视频来详细了解。在官方视频教程2 中有几百集的课程,其中“APICloud视频之初级代码篇第1~3讲3 ”通过几小时的视频给读者详细介绍了APICloud技术、产品、商业模式、案例以及生态的方方面面,如果读者是第一次接触APICloud,我们建议花一定的时间去观看这些公开课的视频。

2在官方网站中,“开发者社区”标签下。

3在官方的视频教程中。

 

开发者在选择或者使用一个平台的时候,一定会遇到很多的问题。遇到问题时应该如何解决?此外,开发者还会关心这个平台在提供技术的同时还能提供哪些服务?有没有一个完整的生态?有没有一个活跃的社区提供技术支持、方便学习和交流?

针对这些问题,本节列举以下APICloud开发者服务体系相关的产品。

1. APICloud开发平台

这里是APICloud的官方网站,也是整个APICloud应用开发和管理平台的入口。

2.开发工具4

4在官方网站点击“开发工具”。

APICloud是一个移动应用的开发平台,开发APICloud应用需要编码工具。对于开发工具来说,APICloud支持包括Atom、Sublime Text、Eclipse、WebStorm、VSCode,以及基于Node.js的CLI命令行工具。开发者在开发APICloud应用的时候,可以使用自己喜欢的任意一款主流的编码工具,只需要在这些工具中安装相应的APICloud插件就可以了。

以Sublime Text3为例,如图1-8和图1-9所示,可以看到这里面有Windows版和Mac版的下载地址,这里所下载的是APICloud为Sublime Text提供的插件。下载完成后,打开Sublime Text,在Sublime Text中安装完APICloud插件之后,就可以在Sublime Text中使用“新建APICloud项目”“新建APICloud文件”“进行Wifi真机同步”“日志输出”“代码管理”等开发APICloud应用所需的相关功能。在其他工具中,如Atom、WebStorm、Eclipse和VSCode等也可以分别安装APICloud为这些工具所提供的对应插件,所有这些APICloud的工具插件都是免费开源的,可以在GitHub的APICloud开源分支5中查看源码。

5在GitHub中搜索“APICloud-DevTools”。

图1-8

本书案例的开发会全程使用APICloud Studio 2作为开发工具,APICloud Studio 2是APICloud提供给开发者的一款基于Atom扩展的全功能集成开发工具。在本书的附录B中,会对APICloud Studio 2开发工具的使用进行全面详细的介绍。

图1-9

3.开发文档6

6在官方网站点击“文档”。

整个APICloud开发文档包含了3部分内容,第一部分是对APICloud的整体介绍以及开发工具的介绍,也就是其网页最左侧的这一列;中间部分是对APICloud API的介绍,包括端API、扩展模块、前端框架、云API等;最右侧是技术专题,这里会把开发过程中常见的问题以技术专题的形式总结出来。不管是对APICloud的初学者,还是已经用APICloud开发过应用的开发者,本书都建议在遇到问题的时候,第一个解决方式就是去查找文档。APICloud文档遵循简洁清晰的书写原则,用到某一个API的时候,直接到文档中查看其对应的使用说明即可。

4. 开发者社区7

7在官方网站点击“开发者社区”。

APICloud有着国内最活跃的HTML5混合开发者社区,在这个社区中,有很多优质和资深的APICloud开发者,用户在使用中遇到的问题在社区中提问都可以第一时间获得解答。APICloud平台上线至今,社区中已经沉淀了很多有价值的帖子和技术专题的讨论,所以非常建议开发者常去社区看看,那里的帖子都是各个开发者学习经验的总结。本书希望读者在开发过程中遇到问题的时候,可以到社区中查找相关的解答或者提问,初学者最好能花一些时间把新手入门的帖子从头到尾看一遍,这是非常有价值的。

5. VIP服务8

8在官方网站点击“VIP服务”。

很多大型企业或者创业公司在选择APICloud的时候,由于整个项目的开发周期比较紧张,而刚刚接触一个新的平台,使用中会遇到一些问题,这些问题在社区中是可以得到解决的,但是可能不够及时。针对这类客户,APICloud提供了VIP技术支持服务,企业也可以去购买APICloud企业版。当然这个是收费的,企业购买完之后,APICloud将以工单的形式提供技术支持,企业客户有任何问题,半个小时之内APICloud官方会有技术支持一对一地进行解答。

6.开源代码分享9

9点击官方网站中“开发者社区”标签下面的源码。

APICloud提供了非常丰富的开源代码,这些源码包括App实例源码,很多都是APICloud开发者所开发的一些App模板源码,也包括一些模块的使用示例代码,以及App开发过程中一些常用的JavsScript框架代码。当然,这里也有模块的源码,因为APICloud的很多模块都是开源的,所以模块的源码就是Android和iOS的模块工程源码。同时,APICloud为Sublime Text、Atom、WebStorm、Eclipse等所有主流的开发工具提供的插件、命令行的CLI工具,以及APICloud Studio所有的代码都是完全免费开源的。

这里也有APICloud前端框架和官方文档的源码,APICloud官方文档本身就是开源的。读者如果发现官方文档的编写存在不够准确或者不够完善的地方,可以随时在官方文档的开源分支中提交修改,一同为APICloud生态发展做贡献。还有APICloud云SDK,也就是APICloud提供的云端服务,官方提供了不同技术语言版本的SDK,包括Node.js、PHP、Java、.NET等,这些不同语言版本的云API SDK也都是开源的。

更多APICloud开源代码可以到APICloud GitHub开源分支10查看。

10在GitHub中搜索“apicloudcom”。

7.商业案例展示11

11在官方网站点击“开发案例”。

目前,基于APICloud平台开发的应用已有2万多款在苹果AppStore上线。在APICloud商业案例展示区,用户可以看到一些用APICloud开发出来的应用案例,每期会展示数百款的已上线App,这些案例都是用APICloud开发的商用App,不是WebApp,也不是微信公众号或HTML5网站。所有这些App旁边都有二维码,用户可以直接扫码安装体验,这些应用都是使用APICloud平台开发的。

如果APICloud的开发者开发了一款App,并且认为其性能体验不错,可以联系APICloud官方的运营人员,申请在官网展示这款App。APICloud可以在案例区为其免费展示,案例区会定期更新申请展示的App。初学者如果想看一下APICloud平台开发出来的App是什么样的运行体验,就可以直接扫码安装运行这些案例,看一下体验和效果。

8.模块Store12(聚合API)

12点击官方网站中,“App开发平台”下面的模块Store。

APICloud模块Store上展示了APICloud平台上所有的扩展模块。APICloud使用行业标准的模块扩展机制,对于具有Android和iOS开发经验的开发者,可以直接按照APICloud模块扩展机制为APICloud贡献模块,这些模块可以选择收费也可以免费。

目前,APICloud平台上有600多个模块,大部分的模块是免费的。大约有1/3是APICloud官方开发的,官方提供的所有模块都是免费的,基本可以覆盖App开发所需的全部基础功能;还有1/3是第三方服务厂商开发的,比如高德地图、科大讯飞语音识别、融云即时通讯等;最后的1/3是个人开发者开发的,个人开发者提供的模块大部分都是收费的。APICloud是想建立一个生态,对于Android和iOS的开发者,可以非常轻松地为APICloud模块Store贡献模块,同时模块开发者可以为其开发的模块标一个价格,让其他开发者购买后使用。

9.模板Store13

13点击官方网站,“App定制服务”下面的模板Store。

APICloud还有一款产品是模板Store。开发者在开发完一个应用之后,如果不想再运营这个应用了,或者是单纯想做一款应用的模板,如果它是一个完整的端到端的应用,整个需求和功能都可以达到一个标准商业应用的水平,就可以将它作为一个模板提交给APICloud。APICloud官方可以把它模板化后成为APICloud模板Store中的一款模板。整体是有一个审核流程的。模板审核通过之后,就可以在APICloud模板Store上进行销售。在模板Store上架后,其他开发者只需一键购买,在线支付,就可以在几分钟之内获得这样一个模板。所购买的产品包括这个模板的管理后台、模板的Android和iOS的安装包以及一些必要的皮肤定制等服务,同时在开发者的APICloud应用控制台中,也会有一个对应的“模板应用”的项目。

10. APICloud应用定制服务14

14点击官方网站中的“App定制服务”。

在APICloud平台上每天都会聚集很多客户的App定制需求,因为很多客户认可APICloud平台和App开发模式,但是由于没有自己的开发团队,所以希望APICloud能够为他们提供App定制服务,或者为他们推荐优质的团队来进行项目实施。APICloud应用定制服务有一套标准化的开发流程和项目管理流程。

这里推荐一些优质的入门资料,读者可以在官方文档页面中找到这些资料。

15点击官方网站中的“开发者社区”,搜索“新手教程集合贴”。

16点击官方网站中的“视频教程”。

在对APICloud平台有了基础的认识后,读者将跟随本节内容从零开始,创建、修改、调试、编译和运行一个最简单的App。这个App不包含任何复杂的开发技术,旨在让读者体验一个完整App的开发流程。在本节的最后,这个应用将可以在移动设备上运行。

在创建App项目之前,首先要有一个APICloud账号,这个账号非常重要,请妥善保管。点击APICloud官方网站右上角的注册按钮即可开始注册。注册过程非常简单,注册完成后请登录账户。

创建一个新的项目有两种方式:

APICloud推荐的集成开发工具是APICloud Studio 2。同时也为其他常用的开发工具软件提供了插件支持,如Sublime、Eclipse、WebStorm、Atom等,读者可以根据自己的使用习惯选择对应的工具。

本书以APICloud Studio 2为例。首先需要下载这个开发工具,选择官网首页的“App开发平台”,然后选择“开发工具”。

在新的页面中根据具体的操作系统选择对应版本的APICloud Studio 2进行下载。下载完成后将压缩包解压到任意位置,在解压后的文件中找到类似“apicloud-studio-2.exe”的文件,这是开发工具的可执行文件。建议为它创建桌面快捷方式以方便使用。

1.在APICloud云平台上创建新项目

在官方网站登录成功后,将鼠标移动到页面右上角的用户名处,在显示的菜单中点击“开发控制台”。

打开控制台页面后,页面左侧是项目列表,现在它是空白的;在中间部分会显示APICloud的更新日志(APICloud平台自上线以来一直坚持每周更新一个版本)等平台动向信息;右侧是个人信息以及一些工具按钮,如图1-10所示。

图1-10

点击左上角的“创建应用”,在弹出的窗口中选中“Native App”(默认选项),在“名称”输入框中填入“HelloAPICloud”并在“说明”输入框中填入任意说明信息,之后点击创建。此时一个新的项目便被创建好了并显示了刚刚创建项目的管理页面,后续会对这个页面的相关功能进行循序渐进的学习。

在项目创建完成后还需要将这个项目检出到本地进行开发,APICloud支持通过git或svn进行代码管理(关于代码版本管理的资料请查阅相关文档),即便读者不了解代码版本管理的相关知识也不妨碍本节的学习。

打开APICloud Studio 2,如果开发者是首次运行此开发工具则需要进行登录。请用之前创建的账号进行登录,否则无法找到相应的项目。登录成功后会进入欢迎页面。

此时开发工具已经获得了账号权限,可以对项目进行操作了。点击菜单栏的“代码管理”→“代码检出”→“APICloud云端应用”,在出现的检索框中输入之前创建的项目名称“HelloAPICloud”,回车确认(也可以从下面的模糊搜索结果中选择相应的项目,如图1-11所示)。

图1-11

在弹出的对话框中选择这个项目在开发设备上的保存位置(例如在桌面上新建一个叫作“HelloAPICloud”的文件夹,然后选择这个文件夹)并点击“检出”。

在新弹出的输入框中保持默认,直接按回车即可,如图1-12所示。

图1-12

开发工具会自动从APICloud云端将账号中的“HelloAPICloud”项目检出到本地计算机上,稍等便可以看到默认打开的代码编辑页面。

2.在APICloud Studio 2上创建新项目

打开APICloud Studio 2并登录之前创建的账号。点击菜单栏中的“文件”→“新建”→ “APICloud移动应用”,分别输入应用名称和应用说明,应用框架选择“空白应用”,之后点击完成。在弹出的对话框中选择新项目的创建位置,点击“创建”。

稍等便可以完成创建。此时在网站的控制台中可以看到刚刚创建的项目。

在开发工具左侧的目录树根目录中选择“html”目录下的“main.html”文件,找到<label id="con">Hello App</label>这一行(第26行),将“Hello App”替换为“Hello APICloud”,之后保存代码如下:

<body> 
  <label id="con">Hello APICloud</label> 
  <div id='sys-info'></div> 
</body>

在修改完项目后需要将修改后的内容从本地提交到云端,保证代码所做的修改在云端编译的时候有效。这个过程如下:

(1)右击项目根目录,选择“git”→“git add + commit”;

(2)在出现的输入区域中输入刚刚进行了哪些修改或总结,例如“修改了main.html”;

(3)保存(快捷键是ctrl/cmd + s);

(4)右击项目根目录,选择“代码管理”→“同步到云端”。

这个操作非常重要,开发者不必每次编辑后都进行这些操作。当完成一个模块或一天的工作后,亦或进行编译前,进行一次同步即可。只有代码同步到云端后才会在编译的App中生效。

APICloud项目的调试有以下两种方式。

对于静态页面通常使用Web浏览器的方式调试,用于检查页面布局和视觉效果,Web调试模式下无法正常运行APICloud扩展API相关的JavaScript代码,很多模块无法调试。我们需要经常在AppLoader中进行扩展模块和运行过程的调试,检查App的逻辑错误。

1.通过浏览器调试

在开发工具左侧目录树中找到“index.html”文件,右击它,并选择“实时预览”。此时会弹出一个检视器,显示刚刚选择的页面。这是一个Chrome的调试窗口,如图1-13所示。

图1-13

为了模仿移动端设备屏幕尺寸,可以点击“Responsive”将视图调整至内置的设备尺寸,或直接在后面输入宽高数值。

2.通过AppLoader在移动端调试

AppLoader是让APICloud项目直接在移动端设备(如手机)上调试的技术,AppLoader包含了App所需模块的运行环境,目前不需要对AppLoader有深入的理解。现在需要针对不同的平台(Android或iOS)下载对应的官方AppLoader:打开下载地址17之后选择AppLoader,在显示的页面中扫描二维码下载AppLoader并安装。

17在文档页面,点击“下载”,然后点击“AppLoader”。

接下来以Android为例,在APICloud Studio 2中右击界面左侧的根目录“HelloAPICloud”,在弹出的菜单中选择“查看WIFI真机同步IP和端口”(如图1-14所示)。界面右上角会弹出相关信息,主要观察IP和端口的内容(如图1-15所示)。接下来要确保测试用的移动端设备和运行Studio 2的电脑在同一网络下(即同一Wi-Fi下)。在移动端打开AppLoader,启动后可以看到AppLoader界面中有一个可以拖动的灰色小圆球。点击这个小圆球,会弹出一个输入窗口,在第一栏输入从Studio中获取的IP地址,并在第二栏输入端口。点击连接后,如果连接成功会得到提示,小圆球将变成绿色;如果连接失败,请尝试关闭计算机防火墙并且检查网络状况是否良好。

图1-14

图1-15

回到APICloude Studio 2,右击“HelloAPICloud”项目目录,选择“WIFI全量同步”(如图1-14所示)。稍等片刻,观察AppLoader,这个测试项目将在AppLoader中运行起来。

APICloud支持自动同步调试,在APICloud Studio 2中右击项目根目录,选择“WIFI自动同步”(如图1-14所示)→“打开”,此时再次编辑页面,效果会实时地显示在测试设备上。

APICloud云端支持证书管理和云编译,可以快速简单地编译App。在Android或iOS平台发布App需要各自的签名证书,对于Android平台,APICloud支持在云平台上一键制作签名证书。对于iOS平台,需要用户拥有Apple开发者账户,并手动完成证书制作。Apple的开发者账户需要购买,如果不想负担此项支出,建议使用Android设备,或使用Android模拟器。

1. Android证书

在网站控制台选择“HelloAPICloud”项目,在其左侧列表中选择“证书”。在右侧页面“Android证书”一栏里选择右上角的“一键创建证书”(如图1-16所示)。此时会出现一个输入栏,输入完整的信息后点击“创建和保存”即可完成创建(请妥善保管这些信息)。创建完成后新的Android证书就被应用了。

图1-16

如果想上传已有的证书,点击“Android证书”一栏的“更新”→“选择证书”,上传自己的证书即可。

关于Android证书的相关内容可参照官方文档。

2. iOS证书

参照上一小节,在证书页面点击“iOS证书”一栏的“更新”,分别上传证书即可。

关于iOS证书的相关内容可参照官方文档。

3.编译项目

在网址控制台选择“HelloAPICloud”项目,在其左侧列表中选择“云编译”。可在这个页面中对App编译平台及相关配置进行设置,这里以Android为例,类型选择“正式版”。点击最下面的“云编译”等待编译完成。

在这个页面中可以设置App所需的权限(如位置、摄像头和通讯录等)、是否进行代码加密、版本信息等,这些功能会在以后的内容中进行介绍。

编译完成后可用移动设备扫码下载,或直接点击下载按钮安装观看效果。之后可将App发布到应用商店。

通过本章的学习,读者应该已经对APICloud平台、学习资源、控制台操作、应用开发流程有了基本的了解,在后续章节中,就可以一步步跟随本书的内容从零起步开发一款App了。


主要内容

带领并教会读者使用APICloud技术实现App的界面布局和静态页面的编写。

学习目标

(1)学习APICloud App的启动过程,了解config.xml配置文件。

(2)了解APICloud五大布局组件和混合渲染模式。

(3)了解api对象和前端框架。

(4)学习如何进行屏幕适配和状态栏处理。

通过第1章的学习,相信读者已经对APICloud平台及其开发流程有了基本的了解。从本章开始本书将带领读者从零起步开发一款App,首先需要明确本书第一部分要带领读者一起开发一款什么样的App。

我们将带领读者开发一款O2O类型的电商App,读者可以在本书的开源仓库1中下载这个App的Android和iOS安装包。安装完毕后,运行这个App体验并查看功能。

1开源仓库中:第一部分\示例项目资源\程序包。

在开发这款App之前需要先做一系列的准备工作,内容包括:

读者可以在本书的GitHub开源仓库中获得相关素材和帮助。因为在本书讲解过程中会直接使用这些资源,读者需要先花一点时间了解它们:需求文档2、效果图与切图3、UI架构设计4、功能架构设计5、开放服务选择6、全部已经完成的静态页面7

2开源仓库中:第一部分\示例项目资源\需求说明\requirement-spec.xlsx。

3开源仓库中:第一部分\示例项目资源\效果图与切图。

4开源仓库中:第一部分\示例项目资源\架构设计\ui-architecture.xmind。

5开源仓库中:第一部分\示例项目资源\架构设计\function-modules.xmind。

6开源仓库中:第一部分\示例项目资源\架构设计\service-modules.xmind。

7开源仓库中:第一部分\示例项目资源\静态网页。

一些其他参考文档如:config.xml配置文件文档、屏幕适配详解、扩展API(api对象)文档、APICloud前端框架文档,可以在官方网站的文档页面被找到。

本节将介绍App的执行流程、引擎初始化后创建的UI组件、config.xml的配置和两个重要的事件。学习了本节内容后读者会对App的启动过程有个初步的了解。

一个App可能由两种方式被启动:

App启动之后做的第一件事是初始化引擎,这是内部过程,开发者不必深究,把主要概念学会就可以了。初始化过程如图2-1所示。

图2-1

(1)对Widget进行初始化(见2.1.2小节)。

(2)对Window进行初始化。

(3)对模块管理进行初始化,关于模块的内容后边会讲,这里不再赘述。

(4)对事件队列进行初始化,APICloud App是事件驱动的,用户的输入都会以事件的方式进行处理,此外App内部也会触发和产生事件;事件通过队列进行管理。

(5)对命令队列进行初始化,命令是由APICloud 内部产生的,每个扩展API的调用都会产生一个内部命令。

引擎在初始化完成后,进入等待状态,对随时插入的用户操作、来自模块以及网络等设备的事件或命令做出响应。

APICloud引擎初始化时会创建两个UI组件实例,它们分别是Widget和Window(参照2.1.1节中的引擎初始化步骤)。

引擎初始化时会创建一个主Widget对象(Main Widget),Widget是APICloud App运行的最小单位,也就是说APICloud App想要运行的话至少要拥有一个Widget的实例。一般来说,一个App包含一个Widget就够了,此时可以把这个Widget看作这个App本身。在存在多个Widget的情况下,最先初始化的主Widget如果被关闭,整个App将会被关闭。

之后会在主Widget中创建一个根Window对象(Root Window),可以把Window理解为一个独立的窗口容器,Window即代表设备屏幕,任何可视化部分都需要装载在某个Window中。这里所说的Window是对移动平台原生窗口概念的封装,可以提供原生的性能。这个根Window之后会装载一个HTML页面,也就是应用打开的第一个页面。这个HTML页面可以通过config.xml配置:找到项目根目录下的config.xml,打开它后找到<content src="index.html" />这一行。这里指定的index.html会被装载到刚刚被创建的根Window中。实际上引擎在解析content标签的时候会触发一个content事件,它的参数中包含index.html,在处理这个事件时index.html就被装载了。

在引擎初始化完成之后,App会去解析config.xml。这个文件在项目根目录下,它其中包含了很多重要的配置信息,并且它会在App的编译和运行时被使用,会影响整个App在平台上的表现,如视觉效果、权限、性能等。一些APICloud模块也会从config.xml文件中获取信息。关于这个文件的可配置项可参照(http://docs.apicloud.com/Dev-Guide/app-config-manual)。

示例如下,设置是否全屏运行:

<preference name="fullScreen" value="true|false" />

使App具有拨打电话的权限:

<permission name="call" />

配置“QQ登录”模块的相关信息:

<feature name="qq"> 
  <param name="urlScheme" value="tencent123345678" /> 
  <param name="apiKey" value="123345678" />
</feature>

APICloud引擎初始化完成后会发出两个重要的事件:

开发者应该在页面的JavaScript代码中注册“apiready”事件,示例如下:

<script type="text/javascript"> 
     apiready = function(){ 
          //TODO 
     } 
</script>

APICloud应用开发虽然使用标准的Web技术,但是与其他Web产品采用B/S架构不同,APICloud应用采用的是完整的Client/Cloud架构,即前后端分离的架构。App中所有的网页文件都是存放在App本地的,只有数据需要从服务端获取。

图2-2所示是APICloud应用的整体架构设计,APICloud的应用设计思想是采用完整的Client/Cloud架构,在移动端实现界面和功能,在服务器端提供数据和服务。其实前后端分离的架构设计,不仅是APICloud应用的设计思想,也是Android和iOS原生App的设计思想。这样设计的好处是所有的界面布局和功能实现都是在App本地完成的,不需要依赖网络。当用户点击交互的时候,App会直接打开本地界面展示和调用本地API实现,不需要像B/S架构那样等待服务端返回远程页面之后再渲染展示,用户体验更好,交互响应更快。

在移动互联网时代,终端产品有很多种类。对于不同类型的客户端,服务端对外提供的数据和服务其实是一样的:通过统一的API接口对外提供。在客户端以产品为导向设计界面,根据不同产品形态的特点进行界面和功能的定制。

APICloud的应用开发使用的就是这样一个完整的前后端分离架构,在App端实现界面和功能,在服务器端提供数据和服务,本书的示例项目也会为读者演示这样的一个架构。

图2-2

在了解APICloud应用的Client/Cloud架构设计之后,接下来一个非常重要的工作就是进行App的UI架构设计。一个原生应用,无论是Android还是iOS的应用,都是由很多不同的窗口组成的,窗口是App界面展示的最小单位,通过一个个窗口的跳转和切换使整个App的界面和功能展示出来。

但是,通常在使用HTML5实现的WebApp中,很多是SPA模式的单页面应用,即通过div的切换来实现界面切换,或是通过a标签来实现页面的跳转。无论是哪种方式,都不是App想要的体验和界面切换效果。所以在使用HTML5技术开发App的时候(注意不是开发WebApp),不管使用什么样的平台或者框架,也不管选择的是哪家厂商,不同的跨平台产品都有一套自己的UI组成结构。

目前Hybrid(混合)的开发模式已经是非常主流的App开发模式,包括“BAT”及很多一线互联网公司,他们的主要App产品都是使用混合技术开发,例如:微信、手机QQ、支付宝、手机淘宝、天猫、京东、美团、大众点评、58同城等。只不过这些大公司都有着一套符合自己业务特点的跨平台技术,用于实现自己的App开发。而APICloud是一个面向所有开发者,能够支持各种类型应用开发的跨平台产品。

使用HTML5技术在APICloud平台上开发一款App,App的UI组成结构需要使用APICloud界面布局的5大组件来进行操作。

如图2-3所示,这是APICloud应用的UI组成结构。一个APICloud应用可以包含Widget、Layout、Window、Frame和UIModule这5种UI类型的组件。首先是Widget,Widget当中可以包含Layout、Window和UIModule;在Window当中,也可以包含Layout、Frame和UIModule;Layout当中可以包含Window和Frame;Frame当中只能包含UIModule。

对于一款App,不管它有几十个界面还是数百个界面,都要使用APICloud的这5大组件进行布局。下面介绍一下APICloud界面布局的五大组件。

图2-3

APICloud App的UI由5大组件组成,每类组件都有一组API进行控制。下面将对这些常用的API进行介绍,关于它们的详细用法可参考官方网站中关于api对象的文档页面。

1. Widget

Widget是APICloud应用运行管理的最小单位,每一个APICloud应用至少包含一个Widget,每一个Widget都具有独立的代码、资源和窗口系统,Widget之间可以相互调用。Widget在UI上表现为一个独立的窗口容器,内部可以包含Layout、Window或UIModule,并且同一时刻,应用中只能有一个Widget在界面上显示。其相关API如下。

2. Layout

Layout旨在实现某一种特定的布局效果,通过定义好的布局组织一组Window或Frame来完成整体的界面布局效果。每一个Layout内部均可包含Window和Frame。

3. Window

Window是一个独立的Native窗口(Android或iOS),是APICloud应用界面布局的基本组件,每一个App都是由多个Window组成的。Window所承载的内容由其所加载的HTML页面决定。每一个Window都是一个独立的Web容器,有其独立的DOM树结构,并且可以独立进行渲染。Window的起点位于屏幕左上角,宽高占满屏幕,不可修改。Window内部可以包含Layout、Frame和UIModule。

4. Frame

Frame是一个独立的Native视图(Android或iOS),与Window类似,Frame所承载的内容由其所加载的HTML页面决定。每一个Frame都是一个独立的Web容器,有其独立的DOM树结构,并且可以独立进行渲染。Frame的位置和宽高可通过参数进行配置。Frame通常作为一个子视图,嵌入到Window或Layout中,Frame内部可以包含UIModule。

5. UIModule

UI模块由一组Native的视图组成,旨在实现某种特定的UI界面效果,可以是全屏展示也可以只是局部区域。每一个UI模块都具有其独立的生命周期、界面布局、事件管理和数据交互。UI模块通常需要嵌入到Window或Frame中使用。

APICloud为什么要有Widget、Layout、Window、Frame和UIModule这5大组件,而不是直接使用HTML5进行布局呢?这五大组件的作用又是什么呢?这就需要讲解一下APICloud混合渲染技术的原理。

如图2-4所示,这是标准浏览器的渲染机制。总体来说,浏览器的渲染机制是单层渲染,一个HTML页面是由很多标签组成的。首先浏览器会对标签进行解析(parse),解析完成后会生成一棵DOM树,在DOM树中会根据标签生成对应的元素(element),然后浏览器会对DOM树进行布局(layout)。布局过程会对整个DOM树进行遍历,这个过程会结合元素的类型和代码中的CSS样式,生成一棵layout树。这个layout树上的节点就是一个个块(block),每个block有自己的宽高、样式、位置和颜色等属性。接下来就要对layout树进行渲染(render),渲染过程会把layout树上的节点,创建为内存里的buffer,然后再画到一张image上,再将这张image贴到屏幕上,这样就可以看到浏览器渲染出的界面了。

图2-4

虽然HTML5和CSS3定义了一些新的标签和特性,像video标签或是一些CSS3的动画,在实现的指导标准上,要求浏览器对这些标签独立渲染,也就是说在整个layout树上,要根据元素类型不同生成很多的子树,然后再对这个子树做分层的独立渲染。虽然HTML5也认识到了浏览器单层渲染所存在的问题,也提出这样一个分层的概念,但是浏览器的绘制方式还是在引擎内部调用平台的2D或3D的接口来进行绘制的,跟通常原生应用的绘制方式还是不一样的。

如图2-5所示,这是一个原生的应用,它是由很多层组成的,大到一个Window,小到一个导航栏、工具栏、按钮,甚至一个文本框,每一个都是独立的组件。App在进行绘制的时候,只需要调用不同的组件布局就可以了,组件和组件之间是完全独立的。如果对某个组件做一个动画,或者数据更新,只要直接找到这个组件,修改这个组件的值就可以了,它并不存在DOM树、layout树这样的生成过程。所以对于一个原生应用,用户进行点击交互的时候,或者执行一个动画的时候,它比浏览器这种单层的渲染速度要快很多,这也就是为什么在渲染层面上Native实现的效果要比HTML5实现的效果体验要好很多的原因。

APICloud开发应用的理念是通过HTML、CSS、JavaScript+APICloud扩展API的方式来进行的。以这种简化的技术开发,但同时要保证开发的App的功能、性能和体验,能够达到原生的要求。所以,一个非常关键的因素就是APICloud引擎支持Native+HTML5的混合渲染。APICloud通过5大组件对整个App的UI结构进行了定义,在渲染机制上与原生应用的分层渲染一致,并且支持Native和HTML5的混合渲染,从而保证用APICloud开发的App的渲染效果和体验。

图2-5

api对象是APICloud在全局作用域内唯一的一个扩展对象(在脚本中可直接调用api下的方法),api对象是APICloud引擎的核心对象,包含了开发一款App要用到的最基础功能,api对象无需引入,可以直接使用。APICloud的扩展模块,都需要通过 api.require()方法引入后才能使用。下面的代码实现了拨打电话的功能:

<script type="text/javascript"> 
apiready = function(){ 
  api.call({ 
    type:"tel", 
    number:"00000000000" 
    }) 
} 
</script>

这里将一个匿名函数注册给apiready,在App启动后,apiready被调用。函数内执行api下的call方法来拨打电话。

如果开发者想打开一个Window,参照下面的代码:

<script type="text/javascript"> 
apiready = function(){ 
  api.openWin({ 
    name:"my",            //这个被打开的Window的名字,以后可以通过这个名字操作这个Window 
    url:'./html/my.html'  //这个Window的HTML文件 
    }) 
} 
</script>

通过api.openWin()可以实现Native过渡动画的窗口跳转,这是很常用的一个功能。

api对象下包含引擎的很多属性和常量。在设计之初,我们希望开发者仅靠使用api对象就可以完成简单App的开发,所以api对象下的方法涉及功能范围很广,包括应用管理、窗口系统、消息事件、网络通信、数据存储、设备访问、多媒体、对话框、模块加载等。同时,api对象下的方法通常都是实现一些轻量级功能的,如文件操作、音视频播放、对话框等,但是涉及复杂的操作和界面展示就需要加载相关的模块来实现。

在进行屏幕适配时,通常要在每个HTML页面的<head></head>标签中添加<meta name= "viewport"content="maximum-scale=1.0,minimum-scale =1.0,user-scalable=0,initial-scale=1.0,width=device-width"/>。这行代码在创建项目和文件模板的时候会被自动添加,如根目录下html文件夹中的main.html文件,它的作用是声明该HTML页面执行时的渲染区域宽度为设备的屏幕可视区域,不做任何缩放,同时禁用缩放功能(默认情况下在移动设备上浏览网页时可以用两个手指进行缩放),保证同原生应用一致的体验。

在制作UI效果图的时候推荐使用 720×1280分辨率作为设计稿的基准尺寸,页面布局时优先考虑像素(px)单位,碰到困难的效果时可考虑em与rem。在写代码时要将效果图的尺寸除以屏幕倍率(例如720×1280的屏幕倍率通常为2),例如一个宽度为200 px的图片通常要写作<img style="width:100px;" src="...">

APICloud提供了前端框架来加速前端开发,前端框架提供了常用的dom操作封装和css样式,它开源在GitHub上8 ,保存在项目根目录下的script/api.jscss/api.css中。前端框架通过$api(和之前的api不同)访问。它非常简单,如果读者使用过jQuery会发现它比jQuery简单得多。例如可以使用$api.byId('xxx')来根据id获取dom元素,$api.trim(‘xxx’)可以去除字符串首尾的空白字符等。这里不建议开发者在APICloud App的页面中引入jQuery等大型框架,因为每个页面是独立的,框架需要在每个页面中进行初始化,这会降低App性能。

8在GitHub搜索“apicloud-js-framework”。

 

下面的代码将id为“main”的dom元素的内容设置为“Hello APICloud”,示例如下:

<script type="text/javascript"> 
apiready = function(){ 
  $api.html( 
    $api.byId("main"), 
    "Hello APICloud" 
    ); 
} 
</script>

沉浸式状态栏如图2-6所示。左侧屏幕顶端状态栏为非沉浸状态,状态栏与App互相分离。右侧屏幕顶端状态栏背景与App融合,为沉浸状态。

图2-6

想要开启状态栏沉浸模式需要完成以下两个步骤:

(1)修改config.xml,实现代码<preference name="statusBarAppearance" value= "true" />

(2)对页面顶端元素使用$api.fixStatusBar()

因为开启沉浸状态后,页面会深入到状态栏下方,此时如果有页面元素显示在顶端则会被遮挡。对被遮挡的元素调用$api.fixStatusBar()会为这个元素添加padding-top样式。其值对于不同运行平台有所不同,开发者不用考虑这些细节,代码如下:

<script type="text/javascript"> 
apiready = function(){ 
  $api.fixStatusBar( 
    $api.byId("header") 
    );   
} 
</script>

开发者还可以通过api.setStatusBarStyle()来设置状态栏的样式,它支持iOS、小米MIUI6.0及以上手机、魅族Flyme4.0及以上手机,以及其他Android6.0及以上手机:

api.setStatusBarStyle({ 
  style: 'light', //可选项,light(状态栏字体为白色,适用深色背景)、dark(状态栏字体为黑色,适用浅色背景),默认light 
  color:'#000'    //可选项,状态栏背景颜色,只 Android 5.0 及以上有效,默认#000 
});

针对iPhone X的特殊造型,Apple为了方便开发者对iPhone X进行适配,在iOS 11中引入了Safe Area的概念。APICloud端引擎也在api对象下添加了safeArea属性和safeareachanged事件,页面重要的元素需要在安全区域以内,避免被遮挡。

对于大多数应用,通过以下几步基本就可以完成iPhone X的适配,其他的特殊情况如横竖屏切换等则需要结合使用场景进行处理。

由于iPhone X顶部的形状特殊,状态栏高度不再是以前的20 px,而是变成了44 px,如果应用开启了沉浸式效果,那么页面顶部会被遮住部分,如图2-7所示。

为了解决这个问题可以修改$api下的fixIos7Bar()方法和fixStatusBar()方法,代码如下:

$api.fixIos7Bar = function(el){ 
    return u.fixStatusBar(el); 
}; 
$api.fixStatusBar = function(el){ 
    if(!$api.isElement(el)){ 
        console.warn('$api.fixStatusBar Function need el param, el param must be DOM Element'); 
        return 0; 
    } 
    el.style.paddingTop = api.safeArea.top + 'px'; 
    return el.offsetHeight; 
};

这里调用了api.safeArea来获取设备的安全显示区域。

由图2-7可以看到,页面底部的标签栏也被虚拟Home键遮挡住了部分。对于虚拟Home键,可以通过openWin()setWinAttr()方法的hideHomeIndicator参数来控制其显示或隐藏,这对于沉浸式体验较高的场景很有用(比如观看视频)。而一般的页面通常做法是避开虚拟Home键,这里参考header的处理,在api.js中添加一个fixTabBar()方法,代码如下:

$api.fixTabBar = function(el){ 
    if(!$api.isElement(el)){ 
        console.warn('$api.fixTabBar Function need el param, el param must be DOM Element'); 
        return 0; 
    } 
    el.style.paddingBottom = api.safeArea.bottom + 'px'; 
    return el.offsetHeight; 
} 

//调用的时候使用: 
$api.fixTabBar(element)

这样就可以适配iPhone X了,如图2-8所示。

图2-7

图2-8

注意

 

现在新建立的项目中$api.fixStatusBar()$api.fixIos7Bar()$api.fixTabBar()函数已经适配了iPhone X。如果开发者使用较早创建的项目可按照前面讲到的方法进行适配,也可以参考api.js中沉浸式效果的适配原理,编写符合自己开发习惯的代码进行适配。

由于Webkit内核自身的实现机制,DOM元素标准的onclick事件存在300 ms的响应延迟,导致移动端HTML页面在处理点击事件的时候会有300 ms的延迟。为了解决这个问题,提供快速的点击响应,需要在点击发生的元素上添加tapmode属性。例如:

<div tapmode onclick="goBack()">返回</div>

如果动态创建了包含tapmode的元素,之后需要调用下面的代码使之生效:

api.parseTapmode()

tapmode属性是APICloud定义的私有属性,用于消除DOM元素的点击延迟。另外,tapmode属性支持赋值CSS样式及动态改变元素样式,实现Native的点击效果。例如:

<div class="btn" tapmode="btn-press" onclick="goBack()">返回</div>

当“返回”按钮被用户点击、处于按下状态时,此DIV元素将叠加使用“btn-press”样式进行渲染;当用户手指离开设备屏幕后,此DIV元素的样式将恢复至默认,即移除“btn-press”样式。

在进行静态页面布局时建议遵循如下布局方法。

使用弹性盒子(flexbox)布局则推荐用兼容性写法,代码如下:

display: -webkit-box 
display: -webkit-flex 
display: flex 

-- 

-webkit-box-orient: vertical 
-webkit-flex-flow: column 
flex-flow: column 

-- 

-webkit-blox-orient: horizontal 
-webkit-flex-flow: row 
flex-flow: row 

-- 

-webkit-box-flex: 1 
-webkit-flex: 1 
flex: 1

本节将带领读者创建App的整体框架并学习如何进行静态页面的开发。

首先请利用第1章学到的内容创建本书的示例App,并将它检出到开发环境中(这里使用APICloud Studio 2),名称和说明可随意填写。

从结构上来看,首页显示在一个Window中,这个Window包含顶端的标题栏(左侧的城市选择框,中间的logo,右侧的个人信息图标)与Tab标签组(“水果”“食材”“零食”“牛奶”和“蔬菜”),中间是具体的Tab页显示区域,页面的左下角有一个悬浮的购物车信息栏,如图2-9所示。

图2-9

顶端的标题栏和Tab标签组属于当前Window。中间的Tab页内容放在Frame中,这里需要5个Frame来实现滑动切换的效果,这个功能可以使用FrameGroup(一种Layout)完成。悬浮的购物车信息栏是一个单独的Frame。

因为config.xml中配置了默认启动页面是根目录下的index.html,所以修改这个index.html。将<style/>标签中的样式与<body/>标签中的元素删除,再将JavaScript代码apiready函数中的内容删除。之后将html文件夹下的main.html文件删除,右击html文件夹,选择“新建 APICloud 模板文件”,在html文件夹下建立一个新的main.html。这样就拥有一个空白的App框架了。

现在使用在第1章中学到的内容,在手机或模拟器上建立调试环境,以便完成接下来的开发。

将本书开源仓库中第一部分\示例项目\切图中image文件夹下的文件全部复制到项目根目录下的image文件夹中,以后会用到这些图片进行开发。

App启动后展示的第一个界面就是main.html,需要将html/main.html用作首页而不是根目录下的index.html。下面操作会实现这个功能。

在index.html的apiready函数中添加以下代码:

api.openWin({ 
  name: 'main', 
  url: './html/main.html', 
  slidBackEnabled: false 
});

在html/main.html中的<body/>标签之间添加“启动完成”以便测试。

运行测试后看到页面显示“启动完成”,说明一切正常,如图2-10所示。

图2-10

之后将“html/main.html”中的<body>标签再次清空。接着在“html/main.html”中完成header部分。编辑这个文件,在<body/>标签中插入以下代码:

<header id="header"> 
  <div class="left"> 
    <div class="arrow" id="arrow"></div> 
    <div class="city" id="city">北京市</div> 
  </div> 
  <div class="center"></div> 
  <div class="right"></div> 
</header>

<style/>标签中插入以下代码:

header { 
  width: 100%; 
  height: 50px; 
  background-color: #e1017e; 
} 

header .left { 
  position: absolute; 
  bottom: 0; 
  left: 0; 
  width: 100px; 
  height: 50px; 
} 

header .left .arrow { 
  position: absolute; 
  bottom: 21px; 
  left: 11px; 
  width: 13px; 
  height: 8px; 
  background: url(../image/arrow_down.png); 
  background-size: 13px 8px; 
  background-position: center center; 
  background-repeat: no-repeat; 
  -webkit-transition: 200ms; 
  transition: 200ms; 
} 

header .left .arrow.active { 
  -webkit-transform: rotate(180deg); 
  transform: rotate(180deg); 
} 

header .left .city { 
  position: relative; 
  z-index: 2; 
  width: 100%; 
  height: 50px; 
  padding-left: 27px; 
  line-height: 50px; 
  font-size: 14px; 
  color: #fff; 
} 

header .center { 
  width: 100%; 
  height: 50px; 
  background: url(../image/home_title.png); 
  background-size: 74px 19px; 
  background-position: center center; 
  background-repeat: no-repeat; 
} 

header .right { 
  position: absolute; 
  bottom: 0; 
  right: 0; 
  width: 40px; 
  height: 50px; 
  background: url(../image/home_membercenter.png); 
  background-size: 30px 30px; 
  background-position: center center; 
  background-repeat: no-repeat; 
}

此时可以在测试环境中看到需要实现的header部分了,这里在设置元素尺寸时使用了效果图尺寸除以2的算法,如图2-11所示。

图2-11

注意header.left.arrow.active这个样式,在城市列表打开状态时,只要给箭头图标套用active类就可以实现旋转动画了。

接下来实现Tab标签组,在<body/>标签内<header/>标签的下方添加以下代码:

<nav id="nav"> 
  <div class="menu selected">水果</div> 
  <div class="menu">食材</div> 
  <div class="menu">零食</div> 
  <div class="menu">牛奶</div> 
  <div class="menu">蔬菜</div> 
</nav>

<style/>标签中继续添加以下代码:

nav { 
  display: -webkit-box; 
  display: -webkit-flex; 
  display: flex; 
  -webkit-box-orient: horizontal; 
  -webkit-flex-flow: row; 
  flex-flow: row; 
  position: relative; 
  height: 40px; 
  background-color: #e1017e; 
} 

nav .menu { 
  -webkit-box-flex: 1; 
  -webkit-flex: 1; 
  flex: 1; 
  height: 40px; 
  line-height: 40px; 
  font-size: 13px; 
  color: #f973b8; 
  text-align: center; 
} 

nav .menu.selected { 
  font-size: 14px; 
  color: #fff; 
  font-weight: bolder; 
}

此时,Tab标签组就可以正常显示了,如图2-12所示。

图2-12

这里要注意nav .menu.selected这个样式,当某个标签被激活时它会被套用到相应的标签,实现选中的效果。

观察调试效果,可以看到页面的header部分和系统状态栏重合了,因为沉浸式效果被默认开启了,我们需要更新header的位置,防止它被系统状态栏遮挡。在这个页面的apiready函数中加入以下代码:

$api.fixStatusBar( 
  $api.byId("header") 
);

这里首先通过$api.byId()方法获取了header元素,然后通过$api.fixStatusBar()为它设置padding-top,空出了状态栏的位置。

接下来制作Tab页面,这里有5个Tab页面,但是这5个页面的内容都是相同的格式,只是加载的商品种类不同,因此只需要制作一个HTML模板。

创建html/main_frame.html模板。在这个文件的<body/>元素中输入in frame,用于测试这个页面是否正常显示。

接下来在html/main.html文件中,添加JavaScript代码:

var frames = []; 
for (var i = 0; i < 5; i++) { 
  frames.push({ 
    name: 'main_frame_' + i, 
    url: './main_frame.html', 
    pageParam: { 
      wareTypeIndex: i 
      } 
    }); 
} 

var header = $api.byId("header"); 
var nav = $api.byId("nav"); 
var headerH = $api.offset(header).h; 
var navH = $api.offset(nav).h; 

api.openFrameGroup({ 
  name: 'mainFrameGroup', 
  scrollEnabled: true,     // 支持手势滑动切换 
  rect: { 
    x: 0, 
    y: headerH + navH, 
    w: 'auto',             // 自动填充所在Window的宽度 
    h: 'auto'              // 自动填充所在Window的高度 
  }, 
  index: 0,                // 默认显示第一个Frame 
  frames: frames, 
  preload: frames.length   // 预加载所有Frame 
}, function(ret, err) { 

});

调试时可以左右滑动Tab区域查看切换效果,此时还不能点击上方的5个标签实现切换。

首先观察api.openFrameGroup(),这里提供了name作为这个Layout的名称,允许手势滑动,rect中设置了显示的区域(y坐标空出了header和nav的高度),frames是这个Layout里面装载的全部frame,这里的数据在之前的循环中进行了创建。

那么使用了相同HTML模板的Tab页如何区分自己要显示哪一类的商品呢?这里可以给同一模板的5个实例传递不同的参数加以区分,注意pageParam这部分代码,这就是要传送给Frame(也就是Tab页)的数据对象。

html/main_frame.html中可以获取这个对象,在apiready中输入:

  var param = $api.jsonToStr(api.pageParam); 
  $api.html($api.dom("body"),param);//将传入的数据赋值给页面的body元素

这里通过api.pageParam获取到传入的数据,通过$api.jsonToStr()将JSON对象转换为字符串,然后将它显示到body元素中。

下面来实现滑动Tab页面时激活对应标签的功能,注意api.openFrameGroup()的第二个参数是一个回调函数,每当Tab页切换完毕后会调用这个函数并以被激活页面的信息作为传入的参数。

因此在这个回调函数中插入:

var menus = $api.domAll($api.byId("nav"),".menu"); 
for(var i = 0;i < menus.length; i++){ 
  $api.removeCls(menus[i], 'selected'); 
} 
$api.addCls(menus[ret.index], 'selected');

每当一个Tab页被跳转后,都会执行这段代码。首先获得所有Tab标签,然后把它们的“selected”样式全部移除,最后找到被跳转到的标签添加“selected”样式即可。这样就实现了Tab页跳转和激活标签的效果。

下面实现点击Tab标签跳转到对应的Tab页的功能,通过对想要实现点击的标签注册onclick事件,将对应标签的下标传入,然后使用对应的API跳转即可。

修改<body/>标签中的<nav/>标签部分,为其注册onclick事件:

<nav id="nav"> 
  <div class="menu selected" tapmode onclick="fnSetNavMenuIndex(0);">水果</div> 
  <div class="menu" tapmode onclick="fnSetNavMenuIndex(1);">食材</div> 
  <div class="menu" tapmode onclick="fnSetNavMenuIndex(2);">零食</div> 
  <div class="menu" tapmode onclick="fnSetNavMenuIndex(3);">牛奶</div> 
  <div class="menu" tapmode onclick="fnSetNavMenuIndex(4);">蔬菜</div> 
</nav>

<script/>标签中添加函数:

function fnSetNavMenuIndex(index_) { 
  var menus = $api.domAll($api.byId("nav"), ".menu"); 
  $api.addCls(menus[index_], 'selected'); 
  api.setFrameGroupIndex({ 
    name: 'mainFrameGroup', 
    index: index_, 
    scroll: true 
  }); 
}

html代码中的tapmode移除了html页面的点击延迟,使体验更接近原生,读者可以删除tapmode属性并点击标签以体验区别。

JavaScript代码中使用了api.setFrameGroupIndex()来激活Tab页面,name参数是之前创建FrameGroup时设置的名称,index参数是被激活页面的下标,scroll参数表示frame切换过程中是否有平滑滚动效果。

下面来实现具体Tab页的内容。

清空“html/main_frame.html”中<body/>标签和apiready函数中的内容,然后在<body/>标签中插入:

<header id="header"> 
  <img id="banner" class="banner" src="../image/default_rect.png"> 
</header> 
<section id="list"> 
  <div class="ware"> 
    <div class="content"> 
      <img class="thumbnail" src="../image/default_square.png"> 
      <div class="info"> 
        <div class="name">name</div> 
        <div class="description">description</div> 
        <div class="price-tag"> 
          <span class="price">¥100</span> 
          <span class="unit">/kg</span> 
              </div> 
        <div class="origin-price">超市: 
          <del>¥110</del> 
        </div> 
      </div> 
      <div class="control"> 
        <img class="add" src="../image/add.png"> 
      </div> 
    </div> 
  </div> 
</section> 
<div class="push-status" id="pushStatus">上拉显示更多</div>

<style/>标签中插入:

header { 
  width: 100%; 
  height: 130px; 
  box-sizing: border-box; 
  padding: 4px 10px; 
} 

header .banner { 
  width: 100%; 
  height: 100%; 
} 

section { 
  position: relative; 
  width: 100%; 
  height: auto; 
  box-sizing: border-box; 
  padding: 0 8px; 
} 

.content { 
  width: 100%; 
  height: 100%; 
} 

.ware { 
  position: relative; 
  width: 100%; 
  height: 145px; 
  box-sizing: border-box; 
  padding-top: 15px; 
  padding-bottom: 15px; 
  border-bottom: 1px solid #d1d1d1; 
} 

.ware .thumbnail { 
  position: absolute; 
  top: 20px; 
  left: 0px; 
  height: 100px; 
  width: 100px; 
} 

.ware .info { 
  width: 100%; 
  height: 114px; 
  box-sizing: border-box; 
  padding-left: 112px; 
  padding-right: 28px; 
} 

.ware .info .name { 
  width: 100%; 
  height: 15px; 
  color: #555555; 
  margin-top: 14px; 
  font-size: 15px; 
} 

.ware .info .description { 
  margin-top: 10px; 
  width: 100%; 
  height: 13px; 
  font-size: 13px; 
  color: #9d9d9d; 
} 

.ware .info .price-tag { 
  margin-top: 10px; 
  width: 100%; 
  height: 12px; 
  font-size: 12px; 
  vertical-align: top; 
} 

.ware .info .price-tag .price { 
  color: #e3007f; 
} 

.ware .info .price-tag .unit { 
  font-size: 8px; 
  color: #cbcbcb; 
} 

.ware .info .origin-price { 
  margin-top: 5px; 
  width: 100%; 
  height: 10px; 
  font-size: 10px; 
  color: #d3d3d3; 
} 

.ware .control { 
  position: absolute; 
  width: 110px; 
  height: 23px; 
  right: 8px; 
  top: 90px; 
} 

.ware .control .add { 
  position: absolute; 
  top: 0; 
  right: 0; 
  width: 23px; 
  height: 23px; 
  z-index: 2; 
} 

.push-status { 
  width: 100%; 
  height: 40px; 
  font-size: 16px; 
  color: #888; 
  line-height: 40px; 
  text-align: center; 
  background-color: #fff; 
} 

.active { 
  opacity: 0.7; 
}

这里使用常用的Web技术即可实现,不再赘述。此时页面是静态的,没有加载实际数据,后面会学习如何通过网络通信为其加入真实数据。显示效果如图2-13所示。

图2-13

下面实现悬浮的购物车信息Frame,建立html/minicart_frame.html文件,清空<style/>标签、<body/>标签和apiready函数的内容。在<body/>标签中插入以下代码:

<section> 
  <span class="prefix">¥</span> 
  <span id="amount" class="amount">0</span> 
  <span id="count" class="count"></span> 
</section>

<style/>标签中插入以下代码:

html,body { 
  height: 100%; 
  background-color: transparent; 
} 

section { 
  display: inline-block; 
  box-sizing: border-box; 
  padding: 4px; 
  width: auto; 
  height: 33px; 
  min-width: 35px; 
  line-height: 25px; 
  color: #fff; 
  font-size: 12px; 
  background-image: url(../image/minicart.png); 
  background-repeat: no-repeat; 
  background-size: auto 33px; 
  background-position: right center; 
} 

.count { 
  display: none; 
  box-sizing: border-box; 
  padding-left: 4px; 
  padding-right: 4px; 
  width: auto; 
  min-width: 25px; 
  height: 25px; 
  border-radius: 13px; 
  background-color: #fff; 
  text-align: center; 
  color: #e3007f; 
}

<body/>标签中插入以下代码:

<section> 
  <span class="prefix">¥</span> 
  <span id="amount" class="amount">0</span> 
  <span id="count" class="count"></span> 
</section>

打开“html/main.html”,在apiready函数中插入:

api.openFrame({ 
  name: 'minicart_frame', 
  url: './minicart_frame.html', 
  rect: { 
    x: 0, 
    y: api.winHeight - 55, 
    w: 150, 
    h: 34 
  }, 
  bounces: false     // 关闭弹动 
}); 
api.bringFrameToFront({ 
  from: 'minicart_frame' 
});

这里首先通过api.openFrame()将购物车信息Frame打开,显示在指定位置,且显示的位置和大小通过rect参数指定。之后通过api.bringFrameToFront()将这个Frame移动到最前端。因为这个Frame是以固定位置的方式定位在Window中的,它会悬浮在Window的最上层,并且当Tab页上下滚动时也不会随着移动。效果如图2-14所示。

图2-14

本App涉及的其他静态页面读者可以尝试自己完成,包括首页的城市选择页面,也可以在本节起始处的资源列表中找到已经写好的全部页面直接粘贴到html目录中。

下面将介绍如何跳转到登录页面。

找到已完成的静态页面资源中的html/login.html和html/login_frame.html,将它们复制到项目的html目录下。在html/login.html页面的apiready函数中插入以下代码:

var header = $api.dom("#header"); 
$api.fixStatusBar(header); 
var headerH = $api.offset(header).h; 
api.openFrame({ 
  name: 'loginFrame', 
  url: './login_frame.html', 
  rect: { 
    x: 0, 
    y: headerH, 
    w: "auto", 
    h: "auto" 
  }, 
  bgColor: 'rgba(0,0,0,0)', 
});

在html/main.html页面中,为个人中心图标(右上角)注册点击事件,代码如下:

<div class="right" tapmode onclick="fnOpenPersonalCenterWin()"></div>

<script/>标签中插入以下代码:

function fnOpenPersonalCenterWin(){ 
  api.openWin({ 
    name: 'personalcenter', 
    url: './login.html' 
  } 
);

这里通过api.openWin()打开个人中心页面,个人中心页面暂时显示为登录页面。在html/login.html页面中,为返回按钮(左上角)注册点击事件,代码如下:

<div class="back" tapmode onclick="api.closeWin()"></div>

这里直接在点击事件中调用api.closeWin()关闭当前Window。效果如图2-15所示。

图2-15

下面完成城市选择菜单,建立html/cityselector_frame.html文件,在<body/>标签中插入以下代码:

<header> 
  <div class="title">选择所需服务的地区</div> 
</header> 
<section id="list"> 
  <div class="city">北京</div> 
  <div class="city">天津</div> 
  <div class="city">西安</div> 
</section>

<style/>标签中插入以下代码:

html,body { 
 height: 100%; 
 background-color: rgba(0,0,0,0.7); 
} 

header { 
  width: 100%; 
  height: 96px; 
} 

header .title { 
  box-sizing: border-box; 
  width: auto; 
  height: 96px; 
  margin: 0 32px; 
  padding-top: 64px; 
  padding-bottom: 16px; 
  border-bottom: 2px solid #c8026f; 
  color: #fff; 
  font-size: 14px; 
  text-align: center; 
} 

section { 
  width: 100%; 
  height: auto; 
} 

.city { 
  width: 100%; 
  height: 55px; 
  line-height: 55px; 
  text-align: center; 
  font-size: 22px; 
  color: #fff; 
} 

.highlight { 
  opacity: 0.7; 
}

修改html/main.html,为城市选择按钮的div添加点击事件,代码如下:

<div class="left" tapmode onclick="fnOpenCitySelectorFrame()"> 
  <div class="arrow" id="arrow"></div> 
  <div class="city" id="city">北京市</div> 
</div>

<script/>标签中添加代码:

function fnOpenCitySelectorFrame(){ 
  var header = $api.byId("header"); 
  var headerH = $api.offset(header).h; 
  api.openFrame({ 
    name: 'citySelectorFrame', 
    url: './cityselector_frame.html', 
    rect: { 
      x: 0, 
      y: headerH, 
      w: 'auto', 
      h: 'auto' 
    }, 
    bgColor: 'rgba(0,0,0,0.8)' 
  }); 
  $api.addCls($api.byId("arrow"),"active"); 
}

这里通过api.openFrame()bgColor参数设置了Frame背景色和透明度。

下面实现城市选择和关闭城市选择的Frame,打开html/cityselector_frame.html,为城市div添加点击事件,代码如下:

<div class="city" tapmode onclick="selectCity(0)">北京</div> 
<div class="city" tapmode onclick="selectCity(1)">天津</div> 
<div class="city" tapmode onclick="selectCity(2)">西安</div>

<script/>标签中插入:

function selectCity(index_){ 
  var cities = $api.domAll(".city"); 
  var cityName = $api.html(cities[index_]); 
  api.sendEvent({ 
    name: 'citySelected', 
    extra: { 
      cityName:cityName 
    } 
  }); 
}

这里在点击某个城市div时,获取当前div内的城市名称,并向引擎发送事件。事件名是citySelected,附加信息是所选择的城市的名称。

打开html/main.html,在apiready函数中添加以下代码:

api.addEventListener({ 
  name: 'citySelected' 
}, function(ret, err){ 
  $api.removeCls($api.byId("arrow"), 'active'); 
  $api.html($api.byId("city"), ret.value.cityName); 
  api.closeFrame({ 
    name: 'citySelectorFrame' 
  }); 
}); 
     'active' 
     ); 
  $api.html( 
    $api.byId("city"), 
    ret.value.cityName 
    ) 
});

这里监听了事件citySelected,在监听到之后触发后面的回调函数,关闭城市选择Frame,之后修改箭头的指向并且更新城市名称。效果如图2-16所示。

图2-16

本章搭建了示例App的整体UI架构,实现了界面之间的跳转,通过首页的静态页的编写,学习了一些实用的静态页面开发技术。


相关图书

树莓派开发实战(第3版)
树莓派开发实战(第3版)
React Native移动开发实战 第3版
React Native移动开发实战 第3版
深入浅出React Native
深入浅出React Native
Flutter App开发:从入门到实战
Flutter App开发:从入门到实战
React Native移动开发实战 第2版
React Native移动开发实战 第2版
App自动化测试与框架实战
App自动化测试与框架实战

相关文章

相关课程