(这不是教程) DeviceCheck是iOS 11引入的,它使开发人员可以检查用户是否处于四个自定义状态之一。 所有状态均由开发人员决定。 引入DeviceCheck是为了允许开发人员在所有开发人员的应用程序中正确识别和分类其用户,而无论用户是否删除了他们的任何应用程序。 有许多用途,但通常与货币化和社交有关。 如果您提供应用内新用户交易并希望确保用户无法删除,重新下载和再次访问该交易,则DeviceCheck是您的解决方案。 如果您提供社交应用程序,并且想要确保违反您条款的用户无法长时间访问您的服务(直到他们获得新手机),DeviceCheck是您的解决方案。 在DeviceCheck之前甚至今天,开发人员将在Apple的视野中实施一般或高度可斥责的识别用户的方法,其中最大的例子是Uber直到2017年左右。 一般的解决方案之一是为每个用户使用唯一的,但不是永久的,有时甚至是不存在的广告标识符。 另外,一些开发人员会将信息存储在钥匙串中,但是一旦删除该应用程序,该信息就会被删除。 高度谴责实际上涉及访问每部电话的唯一IMEI /序列。 DeviceCheck已成为各方的完美答案。 它为开发人员提供了永久性,但确保了隐私,使Apple和用户都感到高兴。 开发人员在实施它时遇到的问题。 DeviceCheck要求与Apple的服务器通信,这意味着您必须拥有一台服务器才能完全实现它。 对于在大型公司以外工作的开发人员,花时间了解实施情况可能没有吸引力。 实际上,实施可以非常简单,并且无服务器。 对于我自己的项目(社交),我之所以坚持不懈,是因为用户的质量对于应用程序的成功是不可商议的。 所需的只是Firebase Cloud Functions,Firebase数据库和Node.js。 实施DeviceCheck所花费的大量时间涉及熟悉JavaScript,请求承诺和Apple的错误代码。 因为不仅在服务器之间,而且在数据库之间都会有很多来回回响,所以逻辑确实不是那么简单。 但是,一旦完成,这无疑会让您感到无比的成就。
React native是一个很棒的工具,但是使用React-Native开始一个新项目根本就不那么出色。 考虑所有需要安装的工具可能会让您头疼。 典型的最佳实践RN应用程序包括redux , react-navigation , r18n 。 还有一些更专业的库,例如redux-saga 。 首先,您必须安装它们并使它们协同工作。 这需要时间并且需要努力。 如果您对此感到厌烦,请见面, 点燃 ! 如上所述,根据您要启动的项目,开始一个新项目可能要花费一些时间。如果我告诉您可以将其减少到几分钟并将剩余的时间用于实际编码,该怎么办。 它比您想象的要简单。 让我解释一下该hack会被点燃,它实际上是做什么的? Ignite是React Native的生成器,带有样板,插件等。 Ignite团队已发布了第二个版本,称为Ignite CLI 。在第一个版本中,您可以选择一个-Infinite Red的样板-现在,您可以从许多样板中进行选择,还可以根据需要添加独立的插件。 让我们使用Ignite进行第一个React-native应用程序。 Ignite有一个非常简单的CLI,但是首先我们必须安装它。 只需在您的终端中输入即可。 npm install -g ignite-cli 提醒:Ignite CLI必需的纱线已安装在系统上。 安装ignite之后,我们可以创建第一个应用程序。 ignite new MyNewAppName 在创建过程中它将询问您一些问题。 您可以选择是否要安装它们。 等待几分钟,然后您应该会看到类似这样的信息 ———————————————- ()( )\)((/()\)*) (()/()\))(())(()/(`)/(( /(_))(()/((((_)\ /(_))()(_)))\ (_))/(__))_ __((_)(_))(_(_())((_) | _ _ | (_))__ | […]
最近,我有机会为客户构建了一个iOS 聊天机器人应用程序。 该客户是一家汽车制造商,希望以一种“友好和对话的方式来获取有关您的新车的信息并排除故障。”原因很简单:在当今时代,人们很少在手套箱中寻找那种笨重的汽车手册。找出仪表板上红色闪烁的灯是什么意思。 相反,他们去了谷歌,或者他们给认识汽车的朋友发了短信。 它更快,更简单。 那么,如果汽车配备了具有所有答案的应用程序怎么办? 一个应用程序,您可以直接问“我如何打开巡航控制系统?”之类的问题,它仅向您显示如何执行此操作,直接来自汽车制造商本身而不是外部来源。 不幸的是,我只参与了该应用程序的前端。 所以我对后端感到好奇……这个机器人谁在发送所有这些JSON好东西? 事实证明,在当今时代,我们有很多选择(一些开源甚至有些免费)来构建机器人和AI,这可能是一个非常简单的任务。 因此,让我们构建一个可以处理人类基本互动的聊天机器人。 在本教程中,我们将在前端使用Swift 3,在后端使用Node和Express,并在AI中使用Wit。 威特 首先,我们需要注册机智:https://wit.ai/ 机智需要使用Facebook或Github帐户进行注册。 登录后,Wit会自动为您设置一个应用程序MyFirstApp 。 您可以转到设置并将其名称更改为任意名称。 您还可以在此处更改默认时区和语言。 机智有一个“快速入门”教程,其中向您展示了如何创建“故事”,这基本上是与您的机器人进行对话的一个示例。 在他们的快速入门教程中,他们向您展示了如何创建一个可以使用node js客户端发出天气预报的机器人。 对于我们的机器人,让我们从更简单的内容开始。 点击“创建故事”,并将其命名为“你好”。 在“用户说…”字段中键入Hello 。 对于“意图”字段,输入“值” greeting 。 接下来,点击“自动发送”,然后输入您希望机器人响应的消息。 我们将机器人命名为Lucas ,因此我们将使用: Hi, my name is Lucas. What should I call you? Hi, my name is Lucas. What should I call you? 作为漫游器响应,因为我们希望Lucas 知道与之交互的用户的名称。 […]
这是我第一次以代码风格接触社区,与此同时,我感到有些紧张和兴奋。 我知道我的代码不是完美的,但我也知道为了增长,无论如何,有时您有时需要处于不舒服的情况下。 而且,老实说,只要存在iOS / Swift,我也不知道要进入哪里,我觉得自己的方向是正确的。 当我发现自己从事iOS项目时,有时会遇到从服务器获取一些数据的情况,只有立即获得这些数据后,我才需要点击另一个端点来获取其他东西。 因此,这意味着我必须调用异步函数并在其完成闭包内部,然后才必须嵌套另一个异步调用,是的,我知道那里不存在某些东西。 在我之前的工作中,我曾经作为Node.JS后端开发人员工作,所以我知道嵌套异步调用是一种不好的做法,即使JavaScript世界上的人也将其称为回调地狱。 而且有一个很棒的库叫做async,可以使用它来防止Node.JS / JavaScript中的这种不良做法(当然,这不是唯一的选择,它们有Promise,Generators等)。 但是我不在JavaScript世界中,而是在令人惊叹的iOS世界中! 因此,我几乎没有考虑过如何在Swift中处理这种情况,我发现有一些很棒的框架(如RxSwift或FutureKit)可以帮助我解决问题,但是感觉它们对于我的简单问题来说太高级了。 这就是为什么我创建此博客文章,试图为我的简单问题提供简单的解决方案。 而且我不得不说我的解决方案有偏见,并且与异步是如此相同,只要我的问题得以解决,就可以了吗? 我当时处在不断将我的解决方案复制到其他项目的情况,这就是为什么我决定将其作为图书馆(如Github)提供。 这就是我最终创建这个名为Ax的库的初衷,其最初目的是使我的解决方案可用于其他项目,但我怀疑我不是唯一可以解决Swift中嵌套异步调用问题的人。 如果您对Ax库中的协作感兴趣,请随时与我联系,我计划实现更多功能。 因此,我想谈一谈我如何在Github中创建/上载我的库并使它在cocoapods中可用的过程,但这可能是另一篇文章,如果您有兴趣,请告诉我,我想分享一下。 感谢您的阅读。
Location Tracker应用程序的目标是向Swift开发人员展示使用Cloudant跟踪,存储和查询位置有多么简单,同时启用脱机优先设计并提供架构指导以扩展解决方案以支持数百万用户。 在本教程中,我们将向您展示如何构建应用程序以及为实现目标所采用的策略。 我们将向您展示如何将Cloudant Sync用于离线支持和数据同步。 我们将向您展示如何使用Cloudant Geo来执行和可视化地理空间查询。 最后,我们将介绍在以后的教程中将使用的替代体系结构和方法,以向您展示如何扩展应用程序以支持数百万用户。 总览 Location Tracker应用程序是在Swift中开发的iOS应用程序,可跟踪用户位置并将这些位置存储在Cloudant中。 当用户移动并记录新位置时,该应用会查询服务器以获取用户位置附近的兴趣点。 以下是“位置跟踪器”应用的屏幕截图。 蓝色图钉标记应用程序记录的每个位置。 在用户行进的路径上绘制了一条蓝线。 每当Location Tracker应用程序记录新位置时,都会在Cloudant中执行基于半径的地理查询,以查找附近的兴趣点(在应用程序中称为“地点”)。 半径由绿色圆圈表示。 位置显示为绿色图钉: 要求 为了帮助实现我们的目标,我们创建了5个关键要求: 跟踪前台和后台的位置:当应用程序在前台或后台运行时,该应用程序应该能够跟踪用户的位置。 使用地理空间查询来查找指定半径内的兴趣点:该应用程序应向用户展示如何使用Cloudant Geo执行地理空间查询。 脱机运行:该应用程序应能够在脱机时跟踪用户位置,并在网络连接可用时将这些位置同步到Cloudant。 将用户位置信息保密:用户不应有权访问其他用户的位置信息。 提供整合和分析所有位置的能力:后端工程师或数据科学家在不影响第4条要求的情况下,在所有位置执行分析应该很简单。 建筑 为了满足要求4(用户隐私),使用每个用户的数据库设计模式实现了位置跟踪器。 为只有该用户有权访问的每个用户创建一个专用数据库。 运作方式如下: 当用户注册时,Location Tracker应用程序会将用户信息发布到我们的Node.js服务器。 Node.js服务器在“用户”数据库中创建一个新用户。 Node.js服务器创建一个特定于用户的数据库来跟踪用户的位置。 Node.js服务器将数据库名称和身份验证信息返回到应用程序。 该应用程序直接连接到Cloudant以同步位置信息。 稍后我们将详细讨论。 这是系统架构的高级示意图: 除了创建相邻架构图中所示的特定于用户的数据库之外,服务器还为每个特定于用户的数据库配置连续复制到统一数据库( 所有位置 )中。 通过为我们提供一个位置来查询和分析所有用户记录的所有位置,同时又不损害用户安全性和隐私性(没有向用户提供直接访问统一数据库的权限),这满足了要求#5(位置合并和分析)。 注意: “每用户数据库”设计模式使您可以轻松地在iOS应用程序和Cloudant之间同步位置信息,同时确保信息保密。 对于中小型应用程序来说,这是一个很好的解决方案。 在下一个教程中,我们将向您展示复制用户隔离的数据的替代方法,以及如何扩展应用程序以支持数百万个用户。 服务器 Location Tracker Server是一个Node.js应用程序,它提供RESTful API,用于使用Cloudant Geo注册新用户和查询位置。 安装Location Tracker […]
大家都知道,您可以使用JWT(JSON Web令牌)对Zendesk Mobile SDK的用户进行身份验证。 此外,还有很多HOWTO-s,它们显示了针对许多不同编程语言的JWT实现。 在本教程中,我将向您展示如何使用Google Cloud Functions,NodeJS和其他一些npm附加功能来为Zendesk Mobile SDK创建完全可扩展且完全免费的无服务器JWT身份验证后端。 为什么选择Google? 当然,您可以使用AWS Lambda函数来实现类似的解决方案,但是我个人认为,使用单个产品(Google Firebase)进行iOS后端操作要容易得多,然后再使用AWS的几个服务。 因此,主要原因是Firebase。 同时,Google为您的所有服务提供了出色的日志记录解决方案,因此您无需实施任何特殊的操作并重新发明轮子。 只需对您的所有服务使用单一解决方案。 第三个是API。 我个人认为,Google的API是我见过的最好的API。 只有Google为您提供大多数错误的详细说明,并为您提供指向其控制台的直接URL链接,例如,启用所需的服务。 什么是无服务器,云功能和Lambda? 可以将其视为基于容器技术的轻量级PaaS托管,但存在一些局限性,这使得该技术超级快速且可扩展。 此托管存储您的代码段,这些代码段可以独立启动以解决一个简单的问题(例如,调用Web服务的另一功能,将某些内容保存到数据库或发送电子邮件),这些代码可以在一个时间短。 每当其他云服务触发它或像传统Web服务一样通过HTTP / HTTPS协议直接调用它时,您的代码段就会在容器内启动。 为什么使用无服务器(AWS Lambda或CloudFunctions)? 我们仍然不会不花心思地使用每种解决方案所需的资源。 我们仍然使用一半负载的VM来支持较长的基础架构扩展时间或具有在Kubernetes集群中启动其他容器的能力。 在云的情况下,我们要为这些未使用的资源付费。 不了解您,但我不想这样做。 云功能的使用使我们更加节俭地使用可用资源,同时,它使我们能够比使用VM甚至容器的情况下更快地进行扩展。 因此,借助CloudFunctions,我们可以使用云的本质而无需考虑我们的Web服务可伸缩性。 当然,所有云提供商都支持无服务器技术,因此,您无需考虑诸如供应商锁定之类的事情。 您可以随时轻松切换云提供商。 无服务器后端 首先,我假设您已经拥有: Google Firebase帐户(如果您不使用Firebase,也可以使用传统的Google Cloud)并在其中创建了Project。 您已经安装了Firebase SDK for Cloud Functions,并为您的云功能创建了初始项目结构。 您已阅读有关编写HTTP云功能的信息 之后,您将可以轻松在Node.js上编写类似的代码。将以下代码添加到index.js文件中,以创建名为jwt_auth的云函数: “使用严格”; const functions = require(’firebase-functions’); const admin […]
页面出现时,单击“创建平台应用程序”: 接下来,您需要为您的应用程序创建一个名称,为您的Push通知平台选择Apple生产或Apple开发,然后从您已经创建的证书中上传信息(请参阅先决条件)。 在查找器中选择您的证书,如果使用一个证书将其导出,请输入密码,然后单击“从文件加载凭据”。 您的证书和私钥应该自动填充。 单击创建平台应用程序。 创建应用程序后,记下应用程序ARN(Amazon资源名称)。 我们将在步骤3中使用它。 2.创建SNS主题: 导航到左侧导航菜单中的主题,单击创建新主题。 填写主题名称和显示名称。 就我而言,我只想创建一个推送通知,该通知将发送给整个用户群,因此我创建了一个名为all_app_users的主题。 创建主题后,请记下ARN。 我们将在步骤3中使用它。 3.配置程序访问 在我们的node.js代码中,我们将需要配置一个具有适当权限的用户aws-sdk,以创建SNS终结点并订阅我们的all_app_users主题。 返回AWS控制台,导航至IAM,然后单击Users。 创建一个新用户,选择一个名称,然后选中“访问类型”的“编程访问”,然后单击“下一步”:权限: 在权限屏幕上,单击附加现有策略,然后单击创建策略: 在弹出的IAM屏幕上,选择“策略生成器”。 然后在Edit Permissions中,选择适用于AWS Service的Amazon SNS,在Actions字段下检查CreatePlatformEndpoint,然后从步骤1插入应用程序ARN: 单击“添加语句”,然后重复上述步骤以创建允许该用户创建all_app_users主题的订阅的all_app_users 。 再次为AWS服务选择Amazon SNS,为“操作”选择“订阅”,然后从步骤2插入SNS主题ARN。单击下一步,将策略名称更改为sns-programmatic-access,然后单击创建策略。 返回创建用户的窗口,搜索sns-programmatic-access(您可能需要单击刷新按钮),然后单击其旁边的复选框以将其选中。 单击“下一步:查看”,然后单击按钮以完成创建用户。 在下一个屏幕上,将显示您的访问密钥ID和秘密访问密钥。 现在记下这些凭据,因为您将无法再次访问密钥*。 我们会将这些凭证插入到我们的node.js代码中,以配置我们的AWS客户端。 *如果您最终丢失了密钥,则可以通过IAM管理控制台创建新密钥。 4.向平台注册用户: 这部分取决于您当前如何处理设备令牌的注册。 在本例中,我们当前正在将设备令牌发送到服务器,以将它们存储在数据库中。 为了实现SNS,我们将需要在包含该设备令牌的SNS应用程序上创建一个平台终结点,然后将该设备预订到我们的all_app_users主题。 为此,我们将需要aws-sdk npm模块: npm install -save aws-sdk 在我们的代码中,让我们使用在上一步中创建的凭证来配置我们的AWS客户端: 在“配置触发器”屏幕上,单击“下一步”。 我们将在确认该功能正常工作后再设置触发器。 在“配置功能”屏幕上,我们需要在all_app_users主题上设置具有SNS:Publish权限的角色。 向下滚动到Lambda函数处理程序和角色部分。 在角色下,选择创建自定义角色: 在打开的IAM窗口中,将“角色名称”更改为所需的名称(我使用notificationsRole)。 然后单击允许。 现在,您的Lambda角色应设置为刚创建的角色。 最后,单击下一步,然后完成创建函数。 现在,我们只需要使用策略生成器添加SNS:Publish权限。 导航到IAM管理控制台,在左侧导航菜单中单击“角色”,然后选择我们刚刚创建的角色(如果使用该名称,则为“ […]
最近我一直不安。 通常,我一直在寻找一种途径来传播我的创造力。 因此,在过去的几周中,我一直在思考我可以创建的应用程序的想法。 我希望这段旅程能帮助我提高编程技能。 我将在博客中记录我的进展,希望可以与其他志趣相投的开发人员建立联系。 工具类 Xcode 9和Swift 4用于前端开发 MindNode集思广益 Evernote做笔记 Todoist用于任务跟踪 后端的Node.js 数据库仍然是一个问号 用于后端开发的Atom GitHub用于源代码控制 对我而言,开始使用Node.js非常容易。 虽然学习曲线绝对是选择技术时要考虑的重要方面,但我担心我最终会被JavaScript的泥潭所困扰。 (#sorrynotsorry) 第一步 第一步是让我在Node.js上运行API,并将其连接到我的客户端应用程序。 在获得了选择了正确技术的概念证明之后,我将开始手工进行一些接线。 想帮忙吗? 该应用程序将围绕目标设定。 我希望收集有关人们为自己设定的目标的信息。 请留下您自己设定的目标类型的评论。
我最近有机会涉嫌添加Apple Pay以在应用程序内接受付款。 请务必注意Apple Pay的含义: –购买实物产品(例如T恤) –付费服务(例如乘坐出租车) 另一方面,Apple Pay不适用于应用内购买: –服务订阅(例如记笔记应用程序) –数字资源(例如宝石或数字音乐) 在这个最低限度的教程中,我将向您展示如何使用Stripe在您的应用程序中接受Apple Pay,而没有任何多余的装饰,以便您可以取出代码并在自己的应用程序中使用它。 请注意,这不会从您的信用卡中扣除费用,因此不必担心测试此代码。 首先,让我们创建一个单视图项目。 2.添加项目设置。 3.添加Apple Pay功能。 4.添加商家ID。 点按我圈出的加号按钮。 Xcode将在您的开发人员帐户中自动创建此商家ID。 关于Xcode的新版本的妙处在于,您无需去developer.apple.com或itunesconnect.apple.com来进行一些晦涩的设置。 许多事情会自动为您完成。 Apple Pay的目的是授权开发人员并向其提供令牌,以便向用户收费。 您需要一项服务才能实际执行收费。 我们将使用Stripe,因为它非常容易设置和使用。 5.在www.stripe.com上创建一个Stripe帐户。 6.为Stripe创建证书以能够处理付款。 转到Stripe中的仪表板,选择“付款”,然后选择“ Apple Pay”。 点击添加新应用程序,然后按照提示进行操作。 它们非常详细,并包含指向开发人员门户中生成证书并上传到条带中所需去的链接。 7.从Stripe获取API密钥,因为稍后将使用它们。 8.我们将使用cocoapods将Stripe SDK包含到项目中。 9.现在,我们终于可以开始编码了! 在您的AppDelegate中,导入Stripe并更新您的applicationDidLaunch代码。 您需要添加在Stripe的步骤8中获得的可发布密钥,您会在其中看到“您的可发布密钥”: 12.现在,我们可以添加代码以实际显示Apple Pay对话框。 为此,我们使用PKPaymentAuthorizationViewController。 我们添加了PKPaymentAuthorizationViewControllerDelegate,以便能够在用户与Apple Pay UI交互时处理事件。 14.如果单击“使用密码付款”按钮,则可以完成交易,但实际上不会从用户的信用卡中扣款。 为此,我们需要向应用程序添加一个后端。 在本教程中,我将使用node.js Express服务器。 (您可以使用所需的任何类型的后端服务器来执行此操作。您只需要公开一个供我们调用的API即可。您可以通过此处安装节点。安装节点后,您可以创建一个文件夹,运行“ npm init ”,然后按照提示进行操作。 15.我们将需要安装三个软件包才能启动快速服务器。 为此,您可以运行“ […]
我创建了一个库,可让您使用JavaScript创建快捷方式。 您可以在npm上以@ joshfarrant / shortcuts-js找到它,并在GitHub上找到文档。 注意:这篇文章中的某些图像仅将快捷方式js称为库,但是实际上可以在 @ joshfarrant / shortcuts-js中 找到该库 。 自从今年早些时候与iOS 12一起发布Shortcuts以来,我一直在花很多时间玩Shortcuts应用程序。 我很喜欢创建快捷方式来执行诸如在家中的控制设备之类的事情,将我的睡眠记录到Health应用程序中,并自动记录我的通勤周期并在上班时设置我的Slack状态。 快捷方式应用程序使您可以轻松地直接进入并开始构建功能强大的工作流程来帮助自动化您最常做的事情,但这并不完美。 使用“快捷方式”应用程序几周后,我开始看到“快捷方式”构建界面在哪里崩溃了。 大型快捷键的修改或重构变得很麻烦,尤其是在iPhone上,因为将十几个动作从一个点拖到另一个位置既费时又容易出错。 而且,没有简单的方法可以复制动作块或批量修改它们。 最后,这可能只是因为我正在测试中,所以可能会有一些错误。 作为开发人员,这开始让我感到沮丧。 在我的脑海中,“快捷方式”应用程序中的动作等同于代码行,因此,我渴望能够将常用的动作块组合为更大的功能,并在参数稍有不同的地方重用它们。 这些挫败感使我开始思考。 “快捷方式”应用程序只是一个旨在简化编写代码过程的界面,所以为什么我不能只掏出中间人自己编写代码? 我开始考虑在“快捷方式”应用程序中进行挖掘,以试图弄清快捷方式的结构,以及如何开始在“快捷方式”应用程序之外生成它们。 为什么我不能直接切开中间人并自己编写代码? 我想看的第一处是iCloud Shortcut共享服务。 我希望用来共享快捷方式的URL可能实际上包含一些编码的数据,然后在应用程序导入时将其解码。 不幸的是,很快,URL中的字符串只是一个标识符,而与快捷方式的内容毫无关系,因此我需要在其他地方查找。 几天过去了,当我滚动浏览“快捷方式”列表时,我注意到几周前我下载了一份快捷方式。 通过此快捷方式,您可以将快捷方式备份到iCloud,如果应用程序的数据库遭到损坏,这可能会很有用。 您将备份“快捷方式”,如果发生最坏的情况,则可以将这些文件重新导入“快捷方式”应用程序,一切都会恢复正常。 当然,这些文件必须包含构建快捷方式所需的所有信息。 我运行了备份,在文本编辑器中打开了一个快捷方式,这就是我的初衷。 可读性不强,但是我越来越近了! 首先,我们可以看到从WF开始有许多对属性的引用,自从应用程序作为Workflow出现以来,这些引用就没有明显变化。 另外,从第一行我们可以看到这实际上是一个bplist文件,这是一个二进制属性列表,在Apple生态系统中非常常见。 我将文件扩展名从.shortcut更改为.bplist,然后再次尝试在XCode中打开文件。 🎉 这就是构成快捷方式的所有信息! 我们可以看到用于设置图标的属性,快捷方式接受的输入以及(最重要的是)快捷方式的操作。 为了使内容更具可读性,我使用bplist-parser将bplist转换为JSON。 在这里,我们有一系列非常简单易懂的动作。 每个动作都有一个字符串标识符WFWorkflowActionIdentifier ,以及一个对象/参数字典WFWorkflowActionParameters 。 这些属性是到目前为止我所见过的所有“快捷方式”操作所共有的,并且是定义操作所需的唯一属性。 从这里开始,只需探索其他动作的属性,以及如何处理更复杂的交互(例如在动作中使用变量,以及将动作嵌套在If和Repeat等块内)就可以了。 现在,我已经有了一个用于快捷方式的基本模板,我可以开始编写一些代码来为我生成这些模板。 我从简单开始,编写了一个快速的Node脚本以生成将两个数字加在一起的快捷方式。 经过一些工作,这就是完整的生成的快捷方式的样子。 将这个JSON转换为bplist后,我将它空投到了iPhone上,很高兴看到它可以工作! 现在我有了概念证明,我可以开始构建库了。 我决定选择TypeScript,因为它为像这样的非常结构化的库提供了完美的类型安全性。 […]