ios react_与现有的本机应用ios第一部分进行本机React

ios react

介绍 (Introduction)

Recently I had an opportunity to integrate React Native to an already existing app (both for Android and iOS). This article briefly covers the things I had encountered. While this article only focuses on iOS I’ll be writing a followup article repeating the same steps over on Android side as well.

最近,我有机会将React Native集成到一个已经存在的应用程序(适用于Android和iOS)。 本文简要介绍了我所遇到的事情。 尽管本文仅关注iOS,但我将写一篇后续文章,在Android方面也重复相同的步骤。

This article will guide you through integrating React Native into an existing iOS application. These documentations assumes you already know a fair bit about the respective.

本文将指导您将React Native集成到现有的iOS应用程序中。 这些文档假定您已经对各自有一定的了解。

You can clone the project while you are reading to get things in order after you are finished with this and want to try it out first hand.

你可以克隆 完成阅读并希望第一手尝试后,在阅读时可以使项目井井有条。

This is the first of a two part series for iOS.

这是iOS的两部分系列的第一个。

本机模块 (Native Modules)

The aim of the project is to reuse some existing Objective-C/Swift without having to reimplement it in JavaScript. This can further be divided into two different usecases.

该项目的目的是重用一些现有的Objective-C / Swift,而不必在JavaScript中重新实现。 这可以进一步分为两个不同的用例。

JavaScript的调用方法 (Calling method from JavaScript)

This guide will use the Unread Message Count example. Let’s say you would like to display the no of unread messages in your React Native code and the logic for this already exists on the Native side. So we would simply like to call this method from JavaScript.

本指南将使用“未读邮件计数”示例。 假设您想在React Native代码中显示未读消息的数量,并且其逻辑已经在Native端存在。 因此,我们只想从JavaScript调用此方法。

We start by creating a Native Module. A native module is a class that usually extends the RCTBridgeModule and implements the functionality required by JavaScript. Our goal here is to be able to write Message.getUnreadCount(); from JavaScript to display this count on the screen.

我们首先创建一个本机模块 。 本机模块是通常扩展RCTBridgeModule并实现JavaScript所需功能的类。 我们的目标是能够编写Message.getUnreadCount(); 从JavaScript显示在屏幕上。

Before implementing any type of communication, lets first visualize the flow in which we would access the data

在实现任何类型的通信之前,首先让我们可视化访问数据的流程

Image for post
This signifies that item on the right exposes the methods to the item on the left with the help of the above protocols.
这表示在上述协议的帮助下,右侧的项目向左侧的项目公开了方法。

建立 (Setup)

If you already have a React Native project, you can skip this step.

如果您已经有一个React Native项目,则可以跳过此步骤。

If you don’t have a project yet, you should create one. Please follow the official guide, which covers what we will be discussing here but from an Objective-C perspective.

如果您还没有项目,则应创建一个。 请遵循官方指南 ,该指南涵盖了我们将从Objective-C角度讨论的内容。

After this the main steps required for the implementation include:

在此之后,实现所需的主要步骤包括:

  • Expose a Swift class to JS

    将Swift类公开给JS
  • Expose static Swift data

    公开静态Swift数据
  • Expose a Swift method

    公开一种Swift方法
  • Expose a method with a callback

    公开带有回调的方法
  • Expose a method as a Promise

    将方法公开为承诺

配置Objective-C桥接头 (Configure the Objective-C Bridging Header)

Let’s add one of the headers we will need right away:

让我们立即添加我们需要的标题之一:

宣告Swift类 (Declare a Swift class)

To begin with, let’s just create an empty class called Message. It should be inherited from NSObject so that it can be exposed to Obj-C:

首先,让我们创建一个名为Message的空类。 应该从NSObject继承它,以便可以将它公开给Obj-C:

如何向JS公开Swift类 (How to expose a Swift class to JS)

Next, we have to expose our Swift class to React Native. To do this, we need to use some Obj-C Macros available in React Native. Create a new Obj-C file and register our Message module.

接下来,我们必须将Swift类公开给React Native。 为此,我们需要使用React Native中可用的一些Obj-C宏。 创建一个新的Obj-C文件并注册我们的Message模块。

We also have to import RCTBridgeModule, so that we can use the Macros to bridge the native code. We’ll use the RCT_EXTERN_MODULE Macro to expose our Message class to JS:

我们还必须导入RCTBridgeModule ,以便我们可以使用宏来桥接本机代码。 我们将使用RCT_EXTERN_MODULE宏将我们的Message类公开给JS:

  • the first argument is the name of our Swift class;

    第一个参数是Swift类的名称;
  • the second is its superclass;

    第二个是它的超类;

从JS访问我们的模块 (Access our module from JS)

Everything should be set up on the native side. Now let’s move on to the JavaScript side. In our React Native project, import NativeModules from 'react-native' and let’s see if we can access our Message module:

一切都应在本机端进行设置。 现在让我们进入JavaScript方面。 在我们的React Native项目中, import NativeModules from 'react-native' ,让我们看看是否可以访问Message模块:

Any module exposed to React Native should be available as a property on the NativeModules object.

暴露给React Native的任何模块都应该可以作为NativeModules对象上的属性使用。

如何公开静态Swift数据 (How to expose static Swift data)

The most simple thing we can expose is static data. All we need to do is implement a special method, called constantsToExport, that returns a dictionary:

我们可以公开的最简单的方法是静态数据。 我们需要做的就是实现一个特殊的方法,称为constantsToExport ,该方法返回一个字典:

Important: we need to use the @objc directive on each method / property that needs to be called or accessed from Obj-C.

重要:我们需要在需要从Obj-C调用或访问的每个方法/属性上使用@objc指令。

主队列设置警告 (Main queue setup warning)

We might get a warning telling us that we didn’t implement the requiresMainQueueSetup method. This happens when we use constantsToExport or have implemented an init() method for UIKit components in React Native v0.49+.

我们可能会收到一条警告,告诉我们我们没有实现requiresMainQueueSetup方法。 当我们使用constantsToExport或在React Native v0.49 +中为UIKit组件实现init()方法时,就会发生这种情况。

To suppress this warning, we simply have to implement the specified method, and return a Boolean:

为了消除此警告,我们只需实现指定的方法,然后返回一个布尔值:

  • true if we need this class initialized on the main thread

    如果需要在主线程上初始化的类,则为true

  • false if the class can be initialized on a background thread

    如果可以在后台线程上初始化类,则返回false

如何公开Swift方法 (How to expose a Swift method)

Let’s see how we can call Swift code from JS by adding a printUnread method that simply prints Hello World.

让我们看看如何通过添加只打印Hello WorldprintUnread方法从JS调用Swift代码。

Important: we need to use the @objc directive on each method / property that needs to be called or accessed from Obj-C.

重要:我们需要在需要从Obj-C调用或访问的每个方法/属性上使用@objc指令。

Next we have to expose the method to React Native’s bridge, from our Obj-C file, using the RCT_EXTERN_METHOD Macro and passing the method name:

接下来,我们必须使用RCT_EXTERN_METHOD宏并传递方法名称,从Obj-C文件中将方法公开到React Native的桥。

Now, if we call our Swift method from JS, it should print Hello World in our Xcode output panel:

现在,如果我们从JS调用Swift方法,它应该在Xcode输出面板中打印Hello World

如何使用回调公开Swift方法 (How to expose a Swift method with a callback)

So far, we can call, from JS, some Swift methods that run native code. Next, let’s see how to get some data from Swift. Let’s create a new method that returns the unread count value:

到目前为止,我们可以从JS调用一些运行本机代码的Swift方法。 接下来,让我们看看如何从Swift中获取一些数据。 让我们创建一个返回未读计数值的新方法:

Important: we need to pass an Array to our callback.

重要提示:我们需要将Array传递给回调函数。

Next, expose getUnreadCount to React Native’s bridge:

接下来,将getUnreadCount暴露给React Native的网桥:

And, finally, call it in our JS file, by passing a callback function:

最后,通过传递一个回调函数在我们的JS文件中调用它:

This should print Unread Count: 10, but this time in our JS console:

这应该显示Unread Count: 10 ,但这一次在我们的JS控制台中:

如何实现Swift承诺 (How to expose a Swift promise)

Well, there are no built-in Promises in Swift, but we can expose a method that we can call from JS just like a Promise. Let’s change the getUnreadCount method that:

好的,在Swift中没有内置的Promises,但是我们可以公开一个可以像Promise一样从JS调用的方法。 让我们将getUnreadCount方法更改为:

  • resolves when we successfully get the count

    resolves我们何时成功获得计数

  • rejects otherwise.

    否则rejects

Note I also added a delay so as to simulate fetching data from a remote server.

注意我还添加了一个延迟,以便模拟从远程服务器获取数据。

We have to use React Native’s types RCTPromiseResolveBlock and RCTPromiseRejectBlock and call the internal methods resolve() & reject() similarly to a JS Promise.

我们必须使用React Native的RCTPromiseResolveBlockRCTPromiseRejectBlock类型,并类似于JS Promise一样调用内部方法resolve()和reject()。

The resolve method has only 1 argument: the data that we want to resolve the Promise with.

resolve方法只有1个参数:我们用来解析Promise的数据。

The reject method has 3 arguments:

reject方法有3个参数:

  • an error code: something specific to our domain logic;

    错误代码:特定于我们域逻辑的内容;
  • an error message: the rejection reason;

    错误消息:拒绝原因;
  • a NSError object: this is usually the error object we we when a network request fails;

    NSError对象:通常是网络请求失败时我们所遇到的错误对象;

Next, we need to expose this method to React Native’s bridge:

接下来,我们需要将此方法公开给React Native的网桥:

Finally, we can use it in our JS file by creating a function that wraps the Promise call and error handling:

最后,我们可以通过创建包装Promise调用和错误处理的函数,在JS文件中使用它:

The above code would either return us Unread Count: 10 or error out Error: count not fetch from server depending on the random number generation.

上面的代码将返回“ Unread Count: 10或错误输出。 Error: count not fetch from server具体取决于生成的随机数。

参数类型 (Argument Types)

RCT_EXPORT_METHOD supports all standard JSON object types, such as:

RCT_EXPORT_METHOD支持所有标准JSON对象类型,例如:

  • string (NSString)

    字符串(NSString)
  • number (NSInteger, float, double, CGFloat, NSNumber)

    数字(NSInteger,float,double,CGFloat,NSNumber)
  • boolean (BOOL, NSNumber)

    布尔值(BOOL,NSNumber)
  • array (NSArray) of any types from this list

    此列表中任何类型的数组(NSArray)
  • object (NSDictionary) with string keys and values of any type from this list

    具有字符串键和此列表中任何类型的值的对象(NSDictionary)
  • function (RCTResponseSenderBlock)

    功能(RCTResponseSenderBlock)

But it also works with any type that is supported by the RCTConvert class (see RCTConvert for details). The RCTConvert helper functions all accept a JSON value as input and map it to a native Objective-C type or class.

但它也可以与RCTConvert类支持的任何类型RCTConvert (有关详细信息,请参见RCTConvert )。 RCTConvert帮助器函数均接受JSON值作为输入,并将其映射到本机的Objective-C类型或类。

结束 (The End)

Thanks for reading this article. Hope you enjoyed it. You can find the source code for those examples in this github repository.

感谢您阅读本文。 希望你喜欢。 您可以在此github存储库中找到这些示例的源代码。

There’s a lot more that we will cover in the next article linked below.

在下面链接的下一篇文章中,我们将介绍更多内容。

资源资源 (Resources)

翻译自: https://medium.com/swlh/react-native-with-existing-native-app-ios-part-i-3095488f2f

ios react

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值