BT

你的观点很重要! 快来参与InfoQ调研吧!

用React Native开发第一个iOS应用

| 作者 Tom Tang 关注 0 他的粉丝 ,译者 刘振涛 关注 12 他的粉丝 发布于 2016年3月5日. 估计阅读时间: 11 分钟 | ArchSummit社交架构图谱:Facebook、Snapchat、Tumblr等背后的核心技术

A note to our readers: As per your request we have developed a set of features that allow you to reduce the noise, while not losing sight of anything that is important. Get email and web notifications by choosing the topics you are interested in.

我们想为用户设计一款移动端的应用,却不知从何下手,我们只知道每一个人都希望做一款又酷又好玩儿体验又十分顺滑的应用,然而团队里没人有移动端的经验。

于是,我们最终只好选择React Native作为我们的开发工具。结果证明,这是一个非常明智的选择,我们从开始到现在的所思所感,全都总结如下:

为什么要用React Native

我们是一群Web开发者,而不是iOS开发者。我曾参加过几个在纽约举办的有关Swift和Objective-C的线下聚会,但最后我依然认为编写Ruby和JavaScript代码最令我愉悦。我们团队在2015年初开始使用Facebook的React框架并取得了初步成效,React Native面世后,我们一度怀疑像这样的交叉设备平台会有很多潜在的问题。但是随着我们的研究深入,我们越发喜欢它了:

  1. 一次学习,随处可用 交叉设备平台通常品相不佳,而且只支持不同设备间相同的功能。而React Native虽然基于React.js框架,但为Android和iOS两个平台编写的项目代码却不尽相同,它们之间只共享一部分代码。因此这些代码在每个平台上都能调用所有原生组件,发挥其最大的效用。

  2. 声明式的视图 当初我们在Web平台用React编写代码的时候就已经爱上了这种声明式的视图,用React Native在iOS平台开发延续了这一传统,如此一来,我们的代码就变得可预测且bug更少。
    请阅读:响应式编程

  3. 为移动平台设计的Flexbox(弹性盒模型) 我们不了解iOS布局约束求解器的工作原理,但幸运的是,React Native引入了大部分浏览器都支持的Flexbox以使布局的过程变得更直观。
    请阅读:Flexbox指南

    iOS约束器(Constraints)

    Flexbox

  4. 用JavaScript编写代码 构建移动应用完全是我们未知的领域,显而易见,如果我们用已掌握的语言来编写代码会节省非常多的时间。况且,我们曾经痴迷于CoffeeScript优雅的语法,而现在React Native已经默认支持了ES6,这让我们激动不已,因为我们可以很轻松地过渡到新的语法体系中。
    请阅读:用ES6代替CoffeeScript

不用React Native的几个保留意见

我们深知节省下来的时间再多也抵不过捉襟见肘的可定制性和有限可用的React Native组件。我们也曾犹豫过是否一定要是用React Native,毕竟以下几条理由确实值得仔细琢磨:

  1. React Native生态系统的限制性 2015年9月,我们刚开始研究React Native,彼时非常多的iOS原生组件已经被实现出来,而且还有更多的功能正紧锣密鼓地开发当中。然而,我们还是会担心React Native最终不支持某些我们非常需要的组件,如此一来我们就只能在React Native桥接器的基础上构建其它相关的SDK了(例如提供对AWS和Mixpanel的支持)。

  2. 太前沿 React Native更新非常快,支持老版本的代码有可能(极少数情况下)在新版本中就被废除。我们在过往的开发周期中遇到过几次这类问题,最后我们不得不作出这样的决定:当且只当亟需某些经过严格测试的新特性时才会主动升级。

  3. Google搜索到的资料少之又少 为一个新系统编写代码意味着很有可能遇到前人没经历过的错误,这些无法通过搜索得到解决方案的问题远比我们编写Ruby on Rails代码的时候要多。想要找到这些问题的解决方案需要足够多的韧劲儿:在文档中定位问题,在源代码中挖掘可能的漏洞。不管怎样,对于React Native团队和它的生态系统而言,只有更多地解决此类问题,多发布一些常规修订才能给他们带来更好的信誉。

React Native的包管理

事实证明,支持React Native的组件简直多到爆炸。无论是ActivityIndicator(加载中指示器)、Alert(警告框)还是Slide(轮播),这些组件与JavaScript中的同类组件并无二异。我无法用语言描述在不了解Objective C和Swift的前提下开发原生iOS应用有多么省心。此外,npm上每天都会出现许多新的代码包,以下这些我们都很喜欢(排名不分先后):

  • react-native-simple-store 我们刚开始用的是AsyncStorage,但却不得不一遍又一遍地重复构建相同的save和get函数。Simple Store是一个基于AsyncStorage的解决方案,它十分出色,可以分分钟连接到设备的存储区。
Store.get('user').then((user)=> {
  // 一些代码
}).catch((error) => {
  console.warn(error)
}).done()
  • react-native-vector-icons 这是我们已知的最好的向量图标包,我们同时使用FontAwesome和EvilIcons,它们可以完美地结合。MaterialIcons、IonIcons和其它图标库均可直接通过这个包获取到。
<Icon name='trophy' />
<EvilIcon name='check' />
  • tcomb-form-native 通过这个包可以轻松地创建表单。你可以既可以使用其默认的Input组件,也可以自定义Input类型,键盘和自动纠正等功能。
var Person = t.struct({
  name: t.String,              // 必填,字符串格式
  surname: t.maybe(t.String),  // 可选,字符串格式
  age: t.Number,               // 必填,数字格式
  rememberMe: t.Boolean        // 布尔值
});
  • react-native-router-flux 合理的路由设计可以简化业务流程,通过一行简单的代码你就可以将定义好的路由置入视图层。
Actions.dashboard()

怪异的地方

作为Web开发人员,我们遇到了一些令人感到十分头疼的问题:

  • 样式 在React Native中可以使用样式表,但只能使用非级联的行内样式,用这种方式定义的样式非常难理解。我们可以通过行内越权的方式定义多级样式来解决这一问题。

Styles.js

module.exports = StyleSheet.create({
  title: {
    fontSize: 23,
    textAlign: 'center',
    color: blueText,
    fontFamily: 'Avenir',
    fontWeight: '700',
  },
  header: {
    padding: 20,
    paddingTop: 30,
    backgroundColor: '#fff',
    borderBottomWidth: 1,
    borderBottomColor: '#ccc',
  },
})
Component.js
...
<Text style={[Styles.header, {color: 'white'}]}>
  一些文字
</Text>
...

标准样式如下所示:

style={Styles.header}

自定义行内样式如下所示:

style={{color: 'white'}}

我们将二者进行了整合:

style={[Styles.header, {color: 'white'}]}

这种hack的方式让人很不爽……可能有更好的方法可以解决此类问题,但是当时我们想到这个方案的时候压根儿不了解。

  • 循环调用/导航器

你很可能在使用NavigatorIOS的时候遇到此类问题,这是很糟糕的选择(除递归外的大多数循环都很糟糕)。Web路由是单一过程的,你可以获取到当前位置及历史位置的所有信息。而在iOS中,你需要将视图置入栈或从中取出相应视图,如果置入一个已存在于栈中的组件将会触发错误。如果调用组件时将当前组件置入到栈中可能会引发调用循环的问题,从而导致程序中断执行。react-native-router-flux可以帮我们解决这个问题,它能用一种可伸缩的方式推导出我们使用的历史路径。

最后的话

React Native是一个优秀的框架,用它来构建移动应用是非常好的选择。由于我们不了解Swift和Objective C,很难将纯原生与React Native两种实现进行比较,单就使用体验而言,它已经可以满足绝大多数的使用场景。我们乐于见到React Native带给我们的首个移动应用,它也持续发展力图变得更加完善。最后我始终认为,对于我们这样一支敏捷灵活的开发团队而言,这项技术帮我们快速地从Web环境切换到移动应用开发领域,非常感谢!

在后续的几篇文章中,我将继续深入剖析我们解决某些特定问题的思路。

  • 登录和认证
  • API和回调
  • 整合iOS SDKs与React Native桥接器

作者简介

Tom Tang,目前任职于HireArt,负责移动开发业务

查看英文原文:http://code.hireart.com/2016/02/24/react-native-ios-app/

评价本文

专业度
风格

您好,朋友!

您需要 注册一个InfoQ账号 或者 才能进行评论。在您完成注册后还需要进行一些设置。

获得来自InfoQ的更多体验。

告诉我们您的想法

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

感谢楼主的无私的精神 by wang peng

写了那么多的干货,帮助了很多人,我也受益匪浅,这种大无畏的精神值得学习,谢谢!

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

1 讨论

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT