我们为基于React Native的移动应用程序建立了一个iMessage扩展,现在你也可以做到:

我将为基于React Native的移动应用程序编写一个桥梁,向你展示我们如何构建iMessage扩展。团队探索这个方法大约花了两周时间,如果你也想构建,遵循我们的方法会节省大量时间。

在我们最初用React Native为Lisk Mobile构建iMessage扩展时,就遇到了一个挑战。事实证明,第三方应用程序苹果,喜欢开发者按照自己的规则行事。如果一家公司想获得苹果的操作系统和丰富的用户群,开发者需要使用苹果自己的工具和编程语言。苹果的iMessage就是这样麻烦。自2016年发布以来,iMessage大获成功。在头6个月里,iMessage有了数千个创新性的即时通讯扩展,包括AirbnbDropbox创建的扩展。2018年末,马克·扎克伯格承认,这项功能是Facebook目前最大的竞争之一。“自从2018年10月在柏林会议期间发布Lisk Mobile以来,我们的团队一直在实现人脸ID认证等功能,以及开发区块链专门方案。确定了为用户扩展iMessage后,我们着手于自己的集成。

iMessage扩展包含在2019年2月发布的Lisk Mobile 0.10.0中。Lisk用户现在可以直接从基于iOS的messenger请求和发送LSK代币,而无需打开我们的应用程序。实现这一功能并非易事——Lisk Mobile用JavaScript编写,使用React Native,而iMessage需要在本地iOS中开发。我们研究发现只有少数资源可以帮助React Native构建iOS扩展。经过深思熟虑,我们决定尝试不同的方法,建立自己的桥梁实现。以这种方式开发这个功能对团队来说是一个非常具有教育和激励意义的过程。我们将向你展示如何将解决方案分解为Native并对React Native2部分,以及如何绑定这些分离的部件。

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

最终产品的模样

内容:

1.问题

2. 解决方案

3.创建一个React Native项目

4. 添加iMessage扩展对象

5. 在React Native端创建iMessage根

6. 将iMessage组件与本机端连接

7. 创建桥模块

8. 在React Native上使用本机模块

9. 其他

10. 结论

如果你想要先了解关于Lisk的更多信息,请查看这个简短的解释器剪辑,LIsk的产品页面文档

问题:没有使用React Native创建iMessage扩展的新文档。

在深入研究解决方案之前,我们先来看看实际问题。为了与整个Lisk平台的编程语言保持一致,我们使用React Native。自2018年4月以来,我们一直在开发手机钱包区块链。这意味着我们已经通过实用功能增强了可视化组件和业务逻辑,用于加密操作并与Lisk Core的API进行通信,Lisk Core是一个包含与我们交互所有所需信息的平台。区块链,包括安全性,共识算法等等。由模块化JavaScript库Lisk Elements提供通信。

第一个选择是寻找现有的React Native组件和指导材料。不幸的是,由于React Native和Native iOS开发的快速变化,我们无法找到官方文档或最新材料。

第二个选择是在Lisk Mobile代码库中尝试iOS本地开发。这种方法的有点是苹果提供的项目会议演讲信息示例。但在代码库中引入大量Swift或ObjectiveC不可取。由于我们要重写大部分现有的业务逻辑和UI组件,这样的操作将导致代码大量重复。

解决方案:我们编写了自己的桥实现并记录了流程。

于是我们采用另一种方法:编写自己的桥实现。在下文,我们将解释我们如何做到的。如果你想直接看代码,我们还在GitHub上创建了这个简便的演示项目

1.创建一个React Native项目

先做重要的事!先创建一个全新的React Native应用程序。由于我们将使用本机功能,因此最好遵循官方文档中建议使用response nativecli的相关部分。

如果没有安装,可以通过运行以下来完成:

$ npm install -g react-native-cli

创建一个名为AwesomeProject的项目

$ react-native init AwesomeProject

 

2.添加一个iMessage扩展对象

下一步是为覆盖iMessage扩展的Xcode项目添加一个对象。

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

用Xcode打开iOS项目

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

通过File> New >Target菜单导航向项目添加新对象

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

选择iMessage扩展

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

起个有创意的名字

3.在React Native端创建一个iMessage根目录

有了iMessage扩展的Xcode对象,开始在React Native端创建根组件蓝图吧。

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

在React Native端,iMessage扩展的入口点

我们需要注册该组件,以便在以下步骤中方便地访问它。现在在项目根目录中创建另一个文件,类似于为主应用程序而创建的React Native文件。

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

App Registry(应用程序注册)是React Native端iMessage扩展的一部分

4.将iMessage组件与本机端连接

需更新iMessage对象,使其在本机应用程序中呈现React Native应用程序。首先是一些手动工作。在常规的React Native应用程序中,这一步实际上由来自React  Native cli的样板文件自动处理。如果你觉得缺少什么,可以将iMessage扩展对象的配置和结构与主应用程序进行比较。

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

构建主应用程序的阶段配置

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

构建iMessage扩展对象的阶段配置

4.1连结数据库

我们将链接React相关数据库来启动配置。它是一个简单的应用程序,所以我们添加的库只是目前需要的核心库。如果你在主应用程序上使用一些第三方模块,并且在你的iMessage扩展中也需要这些模块,请它们链接到这里!

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

用iMessage扩展的数据库配置链接二进制文件/打包编译

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

用iMessage扩展的数据库配置链接二进制文件/打包编译

4.2为Swift创建桥头部文件

既然已为本机部分提供了数据库,现在创建一个桥接头文件,使Swift编译器可识别这些数据库。背后原因是我们在前面步骤中链接的库用ObjectiveC编写。自从苹果引入Swift作为iOS平台的新语言以来,这已经成为一种常见的方法,可以点击此处获得更加深入的知识。

先在AwesomeProjectMessageExtension文件夹中创建一个名为BridgeHeader.h的新头部文件。

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

Xcode >File>New

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

新配置的桥接头

接下来,选择Build Settings / Swift Compiler – Xcode的General(通用)配置,选择该文件作为ObjectiveC桥接头。

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

Build Setting/ Swift CompilerXcode的通用配置

4.3更新项目和构建配置

先更新Info.plist(信息),这是每个iOS项目中都有的配置文件。为了使React Native包在开发模式中可访问,我们需要启用从本地服务器加载内容。

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

更新Info.plist以确保从本地主机加载React Native包

接下来为iMessage扩展添加一个构建阶段(Build Phase),以确保在运行扩展时触发React Native的构建脚本。

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

向iMessage扩展的构建阶段添加一个新的运行脚本

最后一步更新项目的模式。应用程序中的每个对象都有一个模式,该模式定义Xcode语境中可用的操作配置,比如Build、Run和Analyze。

我们更新了主应用程序和iMessage扩展的模式,以确保在发布应用程序时拥有所有必需内容。

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

导航到Xcode的Edit Scheme菜单

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

在主应用程序的构建对象中添加消息扩展(Message Extension)

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

向iMessage扩展的构建对象添加React

4.4 RCTBridge和初始呈现

目前已基本完成配置,现在开始构建结构来呈现我们在Create iMessage Root on React Native部分注册的应用程序。

首先,快速浏览一下iMessage扩展的结构。每个iMessage扩展都有一个名为MSMessagesAppViewController的入口点,它从UIKit扩展为UIViewController,并包含iMessage扩展实例的生命周期方法和属性。这类似于我们的iOS主应用程序中的AppDelegate功能,但不具备它的所有功能。

我们集中在找到一种合适的方法来创建RCTRootView (React Native公开的一个UIView子类,可以嵌入到本机应用程序的任何部位中),并将与iMessage相关的代码作为包加载到React Native端。

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

MessagesViewController.swift的初始结构

首先,我们从修改MessagesViewController.swift开始,创建RCTBridge、RCTRootView并在该视图中呈现注册的AwesomeProjectMessageExtension模块。

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

presentReactNativeView的初始状态

因为我们想在打开iMessage扩展之前和之后清除屏幕上的所有内容,所以我们还创建了一个小助手模块,它为我们完成了清理任务!

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

我们已经添加了removeAllChildViewControllers实用程序,以便在需要时清除视图层次结构:在呈现React Native视图和清除应用程序之前

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

初始运行!

5创建桥接模块

本节,我们将在Swift端创建助手和模块,以便公开与React Native端通信所需的方法和事件。

5.1为Swift -JS通信创建映射器

因为我们要将数据从Swift发送到React Native,所以最好创建一个mapper实用程序来正确格式化数据。

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

映射器实用工具

5.2.为MessagesViewController创建一个管理器

现在创建一个名为MessagesManager的模块,该模块连接我们的主MessagesViewController,并将帮助我们从React Native端进行交互。

根据官方文档的指导,我们需要访问activeConversion对象、显现式样以及修改方法。

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

MessagesManager.swift的初始结构

由于我们使用Swift创建自定义类,所以还需要提供接口文件,以确保React Native将其识别为本机模块。

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

MessagesManager.m文件包含React Native接口声明

5.3为MessagesViewController创建一个EventEmitter

除了上一节提供的助手方法之外,现在我们将根据官方React Native文档中的EventEmitter指南创建另一个。

MessagesEventEmitter将在iMessage语境发生更改时通知JavaScript端。这些更改可以作为用户进行交互的结果而应用于 (比如更新演示风格、在对话中选择消息),或者从远程参与者接收新消息。

首先更新MessagesViewController来定义一个由MessagesEventEmitter轻松实现的协议,从而减少我们的工作(并鼓励关注点分离),以便遵循基于事件的设计模式。

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

为了使用协议模式,我们更新了MessagesViewController文件

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

MessagesEventEmitter的初始结构

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

MessagesEventEmitter.m文件包含React Native接口声明

5.4 自定义模块初始器

如果你按照基本流程创建一个带有React Native的本机模块,则最终将得到在初始化桥步骤期间创建的预实例化对象。如果这个对象是一个常规iOS应用,我们可以用UIApplication的共享属性与根视图控制器通信,但这不是我们想要的。

考虑到我们的本机模块需要有状态才能与MessagesAppViewController实例通信,我们最终创建了一个自定义模块初始化器,方法源自React Native文档上的依赖项注入指南。

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

自定义ModuleInitializer,允许我们在MessagesManager和MessagesEventEmitter模块的初始化步骤中使用附件植入模式

然后更新MessagesViewController的presentReactNative方法,以使用该自定义模块初始化器。

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

更新MessagesViewController的相关部分,以使用自定义模块初始化器

6.使用React Native上的本机模块

现已从本机模块中涵盖了几乎所有需要的部件,可以开始在React Native端使用它们。

6.1更新演示风格

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

在React Native端使用getPresentationStyle和updatePresentationStyle方法

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

onTogglePresentationStyle方法演示

到目前为止感觉还不错吧?但我们落下了一些东西。让我们看看下面的录音,试着找出遗漏的部分。

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

由于我们未设置收听与本机UI触发的演示样式更改相关的事件,因此不断循环地打开工作表,因此在更新工作表之后,我们没有正确的presentationStyle值。为了解决这个问题,我们将使用MessagesEventEmitter模块。

这将允许工作表从本地Swift环境(当用户手动关闭工作表时)和React Native应用程序中接收状态更新。

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

使用MessagesEventEmitter侦听presentationStyle上的更改

现在,应用程序可以对代码库中的2个触发器做出响应,用户可以手动关闭或打开工作表。

6.2 编写消息

现在离目标很近了,从React Native端创建一个iMessage!

让我们从初始化蓝图开始,通过MessagesManager模块创建消息对象的数据。

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

使用MessagesManager的composeMessage方法创建测试消息

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

测试消息的结果

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

使用URL字段更新App.iMessage.js

6.3使用URL字段共享数据

现在我们已能够编写和发送消息,创建一个极简示例来演示URL字段的用法。

将一个时间戳和发送者的身份标识放到URL字段中,并将其显示在屏幕上。我们还将使用MessagesManager公开的getActiveConversation方法,以及MessagesEvents模块中的didreceiemessage和didSelectMessage事件。

现在,如果我们以Kate的身份发送消息给John(或者反过来),我们可以观察时间戳和发送者id的变化。

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

以Kate的身份给John发信息,Kate的发送者ID是CD8FBE2CD25F468385f5669C6E42DDF8

 

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

以John的身份打开并回复Kate的信息,John的发送者ID是721FA6A5CC6F42FDA8404B846E634E62

如果希望共享更多数据并处理复杂逻辑,我们建议使用第三方数据库来简化URL构造和解析逻辑。为了获得更好的示例,你可以查看我们Lisk Mobile应用程序的iMessage部分。

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

本节摘要

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

7. 其他

7.1未解决的问题

模拟器崩溃之谜

从Xcode运行应用程序时,当我们从message detail屏幕返回列表屏幕后,立即发生崩溃。我们还未找到这个问题的症结所在,但可以通过苹果官方文档中的示例项目来重现它。

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

模拟器崩溃之谜🤔

针对崩溃,我们的方案是在运行完所有程序后立即关闭Xcode

iOS 10崩溃

iMessage扩展无法在一个拥有iOS 10的模拟器中成功运行。当从iOS 10迁移到11时,iMessage扩展的接口已经更新。这可能与更新有关,但没有足够的信息来跟踪问题,所以我们最终选择iOS 11作为iMessage扩展的部署对象。

不确定是漏洞还是功能:模拟器刷新参与者ID

在模拟器中运行iMessage扩展时,每次编写消息时,Kate和John的activeConversation对象的参与者身份标识都会更改。问题源于漏洞还是功能还有待观察,但是我们必须在测试设备上运行应用程序,以确保参与者身份标识逻辑正常工作。

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

7.2 性能和可伸缩性

远程调试器和重新加载开发菜单

目前我们所做的设置迫使每次在更新JavaScript部分之后,要看到应用程序的最新版本时,都必须重新运行Xcode中的iMessage扩展。

在上一节中也提到的模拟器崩溃之谜,对于热加载与时间旅行(the hot reloading with time travel)领域的开发人员来说,整个体验有点痛苦。为改善开发人员的体验,我们使用React Native提供的DevSettings模块实现了一个小程序。

并将其导入我们的App.iMessage.js组件,如下所示:

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

根iMessage组件与DevMenu组件

由于DevSettings模块无法获取liveReload和remotede漏洞标志值,所以我们需要双击DevMenu组件中的按钮来确保正确地同步了它们的状态。

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

DevMenu演示!

深度链接器(Deep Link Opener

在Lisk Mobile应用程序中,我们还需要一个实用程序来打开主应用程序并将用户重定向到特定的深度链接。我们通过增强MessagesManager解决了这个问题。

在按照官方React Native文档的指导设置主应用程序来处理深度链接之后,接下来是更新MessagesManager,以提供打开深度链接的实用程序。

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

我们在MessagesManager中添加了openURL

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

还更新了MessagesManager的接口文件,以包含openURL

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

openURL在React Native端的使用

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

 

openURL演示!

在初始加载期间显示加载视图

iMessag扩展的自然行为是在初始加载期间显示在资产部分上传的应用程序徽标,如下所示。

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

启动屏幕的默认行为

在本例中,我们还在等待加载React Native包,直到在屏幕上出现要交互的内容。幸运的是,RCTRootView有一个名为loadingView的属性,允许我们在加载包时显示临时视图。

为了增强这种体验,以活动指示器创建一个视图,并将其分配给RCTRootView的loadingView属性。

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

Xcode >文件>新建>查看

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

使用storyboard设置LoadingView的布局

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

更新MessagesViewController的presentReactNative,以确保RCTRootView实例使用LoadingView

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

本节的最终结果是:在加载React Native包之前,将显示加载视图。

React Native端控制加载视图

现在有了显示加载视图的蓝图,我们还可以使其从React Native端可控。

如果你需要延迟初始呈现(例如:从服务器获取数据),并且不想为这样的任务创建另一个覆盖全屏的加载视图,那么这将非常方便。

首先,MessagesViewController的presentReactNativeView需要重构如下:

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

presentReactNative初始化并在RCTRootView的顶部显示加载视图,而不是使用RCTRootView.loadingView财产。

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

为了控制加载视图的存在,我们向MessagesManager添加了两个方法

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

更新MessagesManager的接口文件,包含控制加载视图的方法。

现在在React Native端利用这些新添加的方法。我们要做的是在componentDidMount中伪造一个异步任务,并延迟内容的初始呈现,直到该任务完成。我们还将向示例集添加一个附加按钮,以再次切换加载屏幕。

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

利用React Native端加载视图的相关方法

8.结论

在孤立的软件环境(如苹果的环境)中,开发面向用户的应用程序需要创新的解决方案。虽然苹果确实提供了全面的文档,旨在帮助开发人员使用原生iOS编写代码,但将现有部分连接到Native生态系统则完全是另一回事。在决定为基于React Native的Lisk Mobile实现iMessage扩展之后,我们亲身解决这个障碍。而且在React Native和基于iOS的应用程序之间搭建桥是一种激动人心的教育体验。我们希望本教程也能为你节省实现React Native应用程序类似功能的时间!

怎样基于React Native的移动应用程序构建iMessage扩展-LISK应用链

原文链接:https://blog.lisk.io/we-built-an-imessage-extension-for-our-react-native-based-mobile-app-now-you-can-too-495beb8e6047