Tag: 移动应用开发

A / B测试移动应用

什么是A / B测试? 是一项实验,您将两个版本的服务提供给不同的人群,并评估每个变体的性能。 这很简单,例如更改网站上按钮的颜色并衡量哪个按钮获得了更多点击。 A / B测试的其他名称是存储桶测试和拆分运行测试。 我为什么要在乎? A / B测试提供了一种科学的,没有偏见的方法来改善您提供的服务。 您可以制定假设,与真实用户进行检验,并根据真实数据制定业务决策,而不受HiPPO(最高薪人士的意见)的驱动。 该技术的强大之处在于,当您发现违反直觉的结果时,如果不使用科学方法很难找到该结果。 谁在使用它? 几乎每个科技公司都以某种方式使用它。 一些著名的例子是Google,Facebook和Spotify。 您很可能已经在不知不觉中参加了实验,例如,在Facebook中,您看到的UI不同于朋友。 如何实施? 以最简单的方式,A / B只需要两件事,一种是创建统一的变体,另一种是测量结果。 例如,我们可以有一个标志,当用户首次启动应用程序时,它会随机决定用户是在A组还是B组上,然后根据此标志更改行为。 当用户与应用程序进行交互时,我们会评估其行为,并使用分析将结果与用户所在的组一起发送。 但是,如果您使用商业平台从小处着手,则可能会有一些优势并简化您的工作。 在这篇博客文章中,我们将探讨如何使用Taplytics完成A / B测试。 集成SDK是一个非常标准的过程,一旦您在Taplytics中注册,便可以遵循。 之后,您可以使用“实验”标签开始创建A / B测试。 我们设计的实验称为“表情符号或图片”,以了解我们的用户是否更喜欢使用表情符号或图片的界面。 我们最初的用户界面是: 我们想测试通过用表情符号替换图像是否可以增加应用程序的整体使用率。 我们可以衡量的一项测试和一项指标。 该服务的可视化编辑器可让您点击应用中的任何内容,并为实验进行编辑,而无需编写代码。 这个功能虽然很有希望,但并未按预期工作,将UI中的错误图片关联了起来。 即使给视图提供不同的标签和IBOutlets也不会改变情况。 我们联系了Taplytics团队以更好地了解问题。 因此,我们使用布尔变量来控制UI并将其更改为用表情符号替换图像。 然后,我们可以创建实验目标: 然后,您可以创建暴露测试的用户细分,并按特定参数进行过滤: 您甚至可以选择要公开实验的用户百分比和要进行首次展示的用户百分比: 开始实验后,您可以获取摘要和结果以衡量假设。 一段时间后,您可以声明Winning变体并将该版本部署到所有用户。 样例项目 我们的示例项目可在我们的GitHub上找到。 注意:不要忘记更改帐户的API密钥和URL方案。 更多工具和服务 其他工具和服务的列表在此处提供。 例如Optimizely,Apptimize,Lifecycle,Leanplum和Localytics。

简介:AwayGame 1.0

快到了! AwayGame的第一个版本即将结束开发,我们很高兴能尽快将其交付您! 尽管我们计划为即将发布的版本提供许多惊人的功能,但第一个公开版本将充满初始选项和功能,可为您提供理想的运动旅行体验。 第一次,让我们逐步浏览AwayGame应用程序,以检查使用1.0版可以执行的所有操作。 借助AwayGame的第一个发行版中的所有这些功能,您将能够确切地告诉我们您想做什么,并且您可以相信我们专有的排序方式,可以放心您的行程是完美的。 请尽快关注App Store中的AwayGame应用程序,并将其用于以后的所有旅行! 在Facebook,Instagram和Twitter上关注我们,并在AwayGame.co上在线访问我们。

MVVM —您做错了

应用程序体系结构是移动开发中的热门话题,并且有一个原因–每个应用程序都需要某种逻辑形式的结构化代码以保持可靠,可扩展和可维护。 iOS应用程序没有什么不同。 最受欢迎的体系结构之一是Model-View-ViewModel,其中视图控制器和视图属于“视图”部分,而视图模型是负责应用程序业务逻辑的单元。 我本人一直在使用此体系结构,还曾见过其他人的多种实现,但是它们似乎都不令人满意,它们显然错过了一些东西。 这些根组件都不适合执行导航或创建控制器。 在控制器负责这些任务的情况下以MVVM方式执行操作感觉很错误,但是我们必须这样做吗? 在MVVM领域中,用于处理路由的一种可能的解决方案是,视图模型公开一个接口,该接口告诉视图控制器何时何地应该路由到何处。 但是,此解决方案远非理想–它使视图控制器意识到其在应用程序中的位置,从而降低了我们以后重用它的能力。 解决此问题的更好方法是引入一个附加组件,这是经典MVVM所缺少的。 有两个常用的对象–路由器和协调器。 两者都是有效的解决方案,它们使单元测试的某些部分非常简单,但是,有一个关键的区别–路由器从视图控制器的单个实例管理路由,而协调器则负责整个流程。 哪一个更好? 与往常一样-没有适合所有应用程序的灵丹妙药解决方案。 如果您的应用程序有很多独立的屏幕,可以在不同的上下文中显示-您可能应该使用路由器,如果它的屏幕可以分为几个控制器-长流程,则协调器可能是更好的解决方案。 我现在正在处理的应用程序属于第一类,因此我一直在使用路由器。 让我解释一下为什么它们比没有它们的路由有这么大的改进。 请记住,以下大多数属性都是与协调员共享的。 路由器的界面不需要了解UIKit,它所使用的控制器很可能只是暴露了push , present和dismiss等基本方法的协议,因此,路由器易于测试,并且可以在不考虑平台的情况下使用或设备。 路由器的导航界面是唯一的界面。 如果使用View Controller执行路由,则可能要处理甚至可能不感兴趣的大量方法–同时,路由器的接口仍然很小,非常简单并且可以完全测试。 尽管您不一定需要测试路由器,但是这种简单性可以使视图模型测试更加简洁,因为对路由器的调用通常是复杂的视图模型逻辑的结果。 为了充分利用路由器,我们需要将它们注入到我们的视图模型中。 我们通过为每个路由器使用协议来实现这一点,并且可以解锁更多令人惊奇的特性: 几乎在每个屏幕上都会执行一些与UI相关的常见操作,例如活动指示器的显示和错误/成功消息的显示-这些可以放置在所有路由器的某些根协议中,例如RouterType,因此我们可以避免很多操作不必要的代码重复。 通用路由器功能可以使用默认实现封装在协议中并组成。 例如,我们可能希望我们的路由器能够向SafariController提供一些URL –这不是所有路由器都需要做的,但是我们可能在一些地方使用它。 我们要做的就是创建一个具有默认实现的协议,并且可以与其他协议(例如ImagePickerRoutable或DocumentBrowserRoutable)进一步组合。 路由器的使用还有一个很大的属性-它使提取与导航相关的通用逻辑变得非常容易。 假设您有很多警报,操作表或弹出窗口,需要用户执行某些操作,然后执行一些任务并关闭。 如果随后应执行某些UI动作(例如活动指示器或其他控制器的表示),则视图模型通常会将其通知给视图控制器。 现在,如果需要在多个应用程序中处理相同的动作,我们可以轻松地将逻辑提取到单个可重用的单元中。 但是如何处理那些与导航相关的动作呢? 如果由控制器处理它们,那么所有的人都需要这样做-这可能是大量的代码重复,而且浪费时间。 对于路由器,这个问题根本不存在-我们可以将其与一些常见的处理程序一起重用。 我还要在这里提一些与视图模型相关的实践: 视图模型不应该是数据源,而应该公开单元配置所需的数据-这对于测试复杂的tableViews和collectionViews特别有用。 您还应该将数据源创建为单独的对象-将来可以轻松重用它们,并且立即进行操作不会有任何危害。 用于填充特定视图(例如UserTableViewCell)的数据应包装为单个结构,例如UserCellConfiguration。 这种结构只是实际数据与其转换之间的薄薄一层,用于填充所有标签,imageViews等。 它使实际模型和视图之间的区别更加容易。 使用依赖注入–可以在单元测试中使用模拟对象,使其易于编写。 视图模型不应导入UIKit-这不是至关重要的事情,但是如果您牢记这一点,它将有助于您保持UI与逻辑层之间的分离。 除了介绍路由器之外,我还在应用程序中使用了另一个组件– ControllersBuilder。 ControllersBuilder只是一个简单的结构,能够在整个应用程序中创建所有控制器。 每个构建方法都遵循相同的方案: 初始化路由器并自行注入,因此此类路由器可以请求创建另一个控制器 初始化视图模型,注入所需的依赖关系,初始数据和路由器 初始化视图控制器并注入视图模型 将视图控制器分配给路由器的弱属性 这里要注意的重要事情–最好让构建器方法返回普通的UIViewControllers,而不是返回特定子类的实例。 […]

为iOS创建自定义键盘

每个开发人员都希望在创建产品时尽最大努力。 通常,它需要超越自然设计的新颖感。 幸运的是,应用程序扩展允许开发人员在常规应用程序的边界之外添加自定义功能。 此扩展名的类型很少,其中一种是自定义键盘。 从iOS 8开始,开发人员可以使用此功能扩展其移动应用程序。 系统键盘很棒,很舒适,而且功能齐全,但是在某些情况下,第三方键盘可以通过滑动或预测用户意图等功能来加快文本输入速度(这是一种什么样的法术?)。 引入它时,我的第一个想法是创建一个简单的密码管理器。 在小型非物理键盘上输入复杂的密码从未如此简单。 从理论上讲,我只需要构建自己的自定义键盘并从此过上幸福的生活。 但是,后来我了解到某些并发症,例如… 自定义键盘限制 这种局限性可以用一句话来概括:不允许自定义键盘访问标准应用程序通常可以使用的许多功能。 首先,关于我的密码管理器,Apple担心用户隐私。 这就是为什么我们在与安全字段进行交互时不能使用自定义键盘的原因,因此无法创建带有魔术按钮的键盘来为我们完成所有这些密码键入操作。 此外,您不能在普通键盘框架上绘制任何元素。 真可惜,但是它与Apple的人机界面设计规则很好地结合在一起,就是这样。 除此之外:我们无法通过“自定义键盘”访问麦克风和摄像头,这使得听写输入变为不可能。 正如您所期望的那样,该列表还在不断增加。 您可以在《人机界面指南》中阅读有关限制和良好实践的更多信息 ……和必备 必须提供一个按钮以切换到其他键盘或返回普通键盘。 在系统键盘中,是那个神秘的地球仪图标按钮。 为了不干扰用户的期望,习惯和根深蒂固的行为,我建议保持这种状态。 我们需要做的就是将带有所有事件的addTarget添加到我们的键盘UIInputViewController到方法advanceToNextInputMode()中(用户可以点击此按钮以快速切换到下一个按钮,或者点击更长的时间以查看可用键盘的列表)。 要使用Internet连接,用户必须允许完全访问自定义键盘。 它允许键盘与包含的应用程序共享数据。 因此,该应用程序可能成为键盘的管理器应用程序。 因此,它可用于同步用户词典或调整并保留用户首选项。 但是,键盘必须在没有完全访问权限的情况下始终可用,因此也需要没有互联网连接。 实施技巧 只是一些代码片段 我不想逐步介绍您,因为我确定您知道如何创建xcode项目,添加视图等。要开始,您需要添加一个新目标(文件->新建->目标->自定义键盘扩展名)到现有项目。 您将获得InputViewController子类,它是键盘的起点-您可以在此处添加控件。 让我们跳到很酷的东西。 例子在Obj-c中,但是基本上它们没有任何特定于语言的怪癖,如果您使用Swift编写,翻译它们会非常容易。 我还建议阅读Krzysztof Pelczar文章中的更多实施技巧。 处理回车键类型和键盘类型 如果要创建可用作主键盘的应用程序,则需要准备不同的文本输入方案。 为了方便用户,您可以在用户输入电子邮件地址时添加“ @”按钮而不是其他按钮,或者在编辑仅允许数字的字段时仅显示数字键盘。 您可以通过在InputViewController中调用来获取当前的键盘上下文(UIKeyboardType): 我不建议使用可视界面构建器来放置按钮,因为完成该过程将花费更长的时间,并且从长远来看将变得很难维护。 通常,在我们的项目中,我们使用具有布局约束(可视格式语言-FTW!)的代码创建视图。 但是这次我决定计算每个键盘按钮的帧将是更好的解决方案。 它只会被计算一次,不需要在相邻视图之间保持约束,并且可以非常快速地调整大小。 一段代码只是为了展示它是如何完成的: 处理长按按键重复 当用户点击删除按钮时,他希望它将删除文本,直到他抬起手指。 这就是它在本机键盘上的工作方式,这也是根深蒂固的用户行为之一。 但是有一个缺陷。 据我所知,没有手势识别器会在每个给定的时间间隔被调用。 但是我们可以使用UILongPressGestureRecognizer和NSTimer做一个简单的技巧。 结果,当用户将手指放在删除按钮上时,我们每150毫秒接收一次事件。 […]

Swift 5和ABI稳定性-最佳迁移时间

Swift是一种快速,安全且有趣的语言,具有充分的堆栈潜力和强大的社区支持,可以进行编码。 据Apple称,它比Objective-C快2.6倍,但是,一些研究表明,两者之间的差异并不大。 Swift代码更容易维护,因为没有单独的接口和实现文件,语法较短,并且该语言支持动态框架。 该语言已显着发展,并已被众多开发人员采用。 根据StackOverflow开发人员调查2018,它是第六受欢迎的语言 。对于仅在2014年发布的一种语言,采用率是惊人的。 这些是Swift的一些优点,现在让我们从开发人员的角度来看这些缺点。 Swift仍不成熟,就像一个移动的目标,每个新发行版都引入了重大更改。 许多开发人员指出的关键问题之一是缺乏与较旧语言版本的向后兼容性以及版本锁定,这意味着整个项目及其外部依赖项中只能有一个Swift版本。 因此,如果开发人员想要切换到最新的Swift版本并更新其外部依赖关系,则被迫完全重写其项目。 对于开发框架的开发人员,他们必须为每个新的Swift版本更新其框架,并且不能将其作为二进制预编译框架进行分发。 幸运的是,Swift团队和开放源代码社区正在努力解决此问题,并有望在Swift的下一个主要版本(即Swift 5.0)中解决此问题,自Swift 3.0以来,Swift已向前推进。 ABI稳定宣言指出,他们的目标是: 源代码兼容性,这意味着较新的编译器可以编译用较早版本的Swift编写的代码。 这将删除Swift中当前的版本锁定。 二进制框架和运行时兼容性,从而可以以二进制形式分发框架,该框架可在多个Swift版本中使用。 二进制框架兼容性将通过稳定模块文件的模块格式稳定性来实现,该模块文件格式是编译器对框架公共接口的表示,而ABI稳定性使应用程序和使用不同Swift版本编译的库之间具有二进制兼容性。 在运行时,Swift程序二进制文件与其他库和组件进行交互。 应用程序二进制接口是独立编译的二进制实体必须遵循的规范,才能链接在一起并执行。 这些二进制实体必须在许多底层细节上达成共识,例如如何调用函数,内存中的数据表示,甚至它们的元数据在哪里以及如何访问它。 ABI稳定性意味着将ABI锁定到将来的编译器版本可以生成符合稳定ABI的二进制文件的程度。 一旦ABI稳定下来,它就会在平台的整个生命周期中持续存在。 ABI稳定性仅影响外部可见的公共接口和符号的不变性。 例如,只要保留公共接口,以后的编译器就可以自由更改内部函数调用的调用约定。 类型(例如结构和类)必须具有针对该类型实例的已定义内存中布局,并共享相同的布局约定。 类型元数据被Swift程序广泛使用。 此元数据必须具有定义的内存布局,或者必须具有一组定义的API来查询类型的元数据。 库中的每个导出或外部符号都需要一个唯一的名称,二进制实体可以同意该名称。 Swift提供了函数重载和上下文名称空间(例如模块和类型),这意味着源代码中的任何名称都可能不是全局唯一的。 唯一名称是通过称为名称修饰的技术产生的。 函数必须遵守调用约定,这涉及诸如调用堆栈的布局,保留哪些寄存器以及所有权约定之类的事情。 Swift附带一个运行时库,该库处理诸如动态转换,引用计数,反射等操作。编译的Swift程序对该运行时进行外部调用。 因此,Swift运行时API是Swift ABI。 Swift随附一个标准库,该库定义了许多常见的类型,结构和操作。 为了使出厂的标准库能够与用不同版本的Swift编写的应用程序一起使用,它必须公开一个稳定的API。 因此,Swift标准库API是Swift ABI,以及它定义的许多类型的布局。 所有这些任务已由Swift核心团队完成,但尚未在GitHub上发布。 通过查看任务的状态,我们可以放心地期望Swift的下一个主要版本是ABI稳定的。 因此,一旦宣布Swift是ABI稳定的,此后编写的代码将与该语言的新版本兼容,并且开发人员在迁移到新版本的Java时不必更新项目的所有外部依赖项。迅速。 一旦实现了模块格式的稳定性,库作者就可以将其框架作为二进制框架提供。 由于可以在操作系统内合并稳定的Swift运行时,因此应用程序包的大小将减小。 语言将不断发展,但从那时起对ABI的更改将是可加的。 当最低目标Swift版本支持它们时,可以利用ABI附加更改,因为ABI稳定性仅锁定外部可见的公共接口和符号。 较新的编译器可以进行内部更改,以提高效率。 Swift显然是Apple生态系统中发展的未来,一旦稳定了ABI和模块格式,该语言将摆脱最大的劣势。 请仔细阅读本文,以了解2019年Swift和Objective-C之间的详细比较。 如果您希望将Objective-C代码库转换为Swift,那么现在是开始的最佳时间。 我写了一篇文章,内容涵盖了从SVProgressHUD到IHProgressHUD的转换,该文章完全是用Swift编写的,具有线程安全性,并且具有与使用Swiftify for Xcode的SVProgressHUD相同的API设计。 https://github.com/apple/swift/blob/master/docs/ABIStabilityManifesto.md […]

我见过天堂。 它是用JavaScript编写的。

为什么React Native是未来 我有一种怪异的软件描述方式。 而且您要么知道我的意思,要么您不知道。 有点奇怪,但是软件界面感觉很重 。 使用界面时,它可能会感到沉重,或者感觉到光线较轻。 两者都不比另一个更好。 这只是取决于。 铬很轻。 Safari感觉较重。 Firefox感觉最重。 可能是胡说八道,但这就是我的感觉。 在我的软件开发生涯中,最重的感觉之一就是在Xcode中使用Swift。 哦,好痛。 延时。 Kanye-West编译器永远不会让您完成。 过去几年,我一直生活在这个笨拙的世界中,以我所知道的唯一方式来构建应用程序:原始,手动,单平台代码。 本地化! 对? 当我了解React Native时,我感到怀疑。 一次用JavaScript编写代码,然后在iOS和Android上部署本机应用程序? -这很烂。 所以我忽略了它。 相反,最终写了两个单独的本机应用程序,一个在iOS的Swift中,另一个在Java / Kotlin的Android中。 这是用JavaScript编写的Web应用程序和基于Electron的桌面应用程序的补充。 (该应用程序是一个加密的跨平台笔记应用程序,因此每个平台上的可用性都是关键。) 这在一段时间内效果很好,但是有困难。 我可以编写Web应用程序和iOS应用程序,但是我对Android毫无经验。 实际上,我一生中从未使用过Android设备超过一个小时。 幸运的是,社区贡献者很乐于帮助构建基础知识,这使我放弃了从头开始编写应用程序的工作,而只是通过增量更改来维护它。 每当需要进行更改或添加功能时,我就需要进入三种不同的代码库,并用三种不同的语言编写相同的代码。 作为一个人,这并不总是很有效。 即使是最简单的跨平台更改,也可能需要一周的时间。 结果是应用程序永远无法拥有美好的事物。 例如,几个用户要求向应用程序添加密码和指纹锁定的功能,这是对具有安全意识的Notes应用程序的非常合理的要求。 但这的实现并非易事:首先,除了输入接口外,还需要密码设置接口。 然后,使用密码对离线用户数据进行加密。 然后,在移动设备上,指定何时应要求输入密码或指纹(立即或退出应用程序时)。 用Swift编写所有这些代码,然后是Java,然后是JavaScript的想法是一场噩梦。 我无法自己去做。 一定有更好的方法。 输入React Native 我必须描述为应用程序维护单独的代码库后的上下文和情感,以便您了解当我开始使用React Native时的愉悦感。 在用Atom (!)编写本机应用程序的第一周,我不屑一顾。 我简直不敢相信这是多么容易。 没有Xcode,没有Swift,可以立即重新加载更改,使用易于使用的JavaScript编写代码-我当时就在天堂。 在编写代码时,我会并排放置iOS模拟器和Android模拟器,并花了一半的时间完全无法相信一切正常。 我从来没有想过, […]

私人iOS Beta 0发行说明(2016年4月24日)

这些是NE SDK的第一个私有beta版本的发行说明。 这是我们使用NE SDK的旅程的开始。 它肯定还远未投入生产,它缺少一些功能,其发布的唯一目的是让您对我们的方法发表意见,并尽可能地将您(包括开发人员)包括在开发循环中。 第一个私人Beta版邀请已经发出,但我们邀请更多开发人员在每个发行版中尝试Beta。 前往这里注册您的兴趣并请求邀请。 项目状态 NEContextSDK还处于早期阶段,这是面向小型公众的第一个发行版。 对您来说,这意味着: API肯定会发生变化。 事情有时会崩溃。 请在邮件列表中报告这些内容,以便我们进行修复。 上下文的准确性不是很高,但是可以总体上了解我们的发展方向,并且可以很好地适应某些应用。 它尚未投入生产。 您的反馈意见可以帮助我们使SDK朝着对您有用的方向发展。 我们支持iOS 9.3。 您的应用程序必须至少定位iOS 9.3,否则将无法使用SDK。 已知的问题 一般 SDK代表您的应用请求位置和其他内容的许可。 我们发布的二进制文件是调试版本,这意味着它具有调试指令,因此比正常大小大。 记录和Info.plist 我们记录有关如何使用SDK以及产生什么输出的信息。 这些日志是匿名的,无法追溯到最终用户。 我们使用它们来提高上下文推断的准确性,了解开发人员如何使用SDK并查找错误和其他问题。 日志会定期上传到Amazon S3,因此您需要做一些额外的配置。 在Info.plist文件中,确保在某处具有以下设置: NSAppTransportSecurity NSAllowsArbitraryLoads NSExceptionDomains akamaihd.net NSIncludesSubdomains NSThirdPartyExceptionRequiresForwardSecrecy amazonaws.com.cn NSIncludesSubdomains NSThirdPartyExceptionMinimumTLSVersion TLSv1.0 NSThirdPartyExceptionRequiresForwardSecrecy amazonaws.com NSIncludesSubdomains NSThirdPartyExceptionMinimumTLSVersion TLSv1.0 NSThirdPartyExceptionRequiresForwardSecrecy XCode的屏幕截图: 基于位置的服务 SDK当前需要后台位置许可。 将来会有所变化,并且可以配置为您不希望SDK甚至不寻求许可的级别。 如果您未收到NEPlace,NEWeather或NEActivity的任何上下文更新,请确保以下内容: 在应用程序的Info.plist文件中,提供以下键: “ NSLocationWhenInUseUsageDescription”或“ […]

在Swift中的UITableView(客户端和服务器端)中加载更多

调用Rest API并在UITableView中滚动时检索大量数据 介绍 我一直想知道移动应用程序如何通过在需要时以便捷的方式加载向下滚动来加载更多数据,从而管理UITableView和UICollectionView显示的数据。 我还试图从服务器端以及客户端对这个问题找出一个全面的观点。 好吧,所以我们在这里尝试承担这个常见问题的负担,并以这种方便的方式简化答案。 我们走吧。 👶 场景: 我们将使用PHP Laravel框架(服务器端)实现Rest API,它将在每次调用中返回最新的feed作为大量数据(20项)。 迅速的代码可以使用API​​向下滚动以加载更多数据。 服务器端 : 该API将返回大量数据,例如ex。 每个呼叫分别以降序排列20个订阅源。 这样,第一个呼叫的最新20个提要,第二个呼叫的最近20个提要之前的下一个..依此类推。 take(20) :将查询返回的结果数限制为20。 skip(0) :跳过查询中给定数量的结果。 这样,在第一个调用中, skip(0)不会跳过任何提要,而在第二个调用中, skip(20)会跳过前20个提要,并检索最近的2o个提要之前的下一个提要,依此类推…… skip(40),跳过(60) …等等。 公共函数 getData($ bulk_no) { return Feed :: orderBy ( ‘created_at’ , ‘desc’ )-> skip($ bulk_no)-> take(20)-> get(); } 客户端 : 嗯,有许多基于swift的库用于执行HTTP请求。 其中最好的之一是Alamofire。 由于其简单性并减轻了网络任务的负担,并提供了用户友好的请求/响应方法。 ViewController将实现UITableView,在cellForRowAt委托方法将如下所示: var bulk_no = 0 […]

在Swift 4中关于JSON解析的简短思考

首先,将Codable定义为typealias Codable = Decodable&Encodable,我们采用两种必需的协议: 可解码 :解析JSON(获取响应) –通过解码JSONData,我们将接收/读取数据 2. Encodable :生成JSON(响应后) –要将可编码 类型转换为Data 。 它适用于基本类型(Int,String和Float等),某些基础类型(数据,URL,日期等)以及数组,字典和可选参数(枚举)。 – NSData – NSString – NSNumber – UInt – Int – Float – Double – Bool – NSDate – NSArray – NSDictionary 为什么? 在我们的数据管理器中简化依赖关系 将数据结构转换为JSON数据从未如此简单(hmmmm ..),允许开发人员将JSON数据存储到磁盘或将其编码为URLRequest的httpBody :)。 您可以编写一个使用外部来源的JSON或通过存根进行测试的应用。 这里的开始问题是您在应用程序中建模的概念的结构与JSON生产者建模的概念之间的不一致。 在您的应用中更改和使用JSON结构的一些示例: 使用CodingKey更改名称属性 2.通过手动编码和解码简化复杂的结构 3.使用嵌套数据(数组JSON内的数组) 对于1.,即使我们不必解析JSON表示形式的每个元素,我们也需要创建与JSONData中名称相同的属性,或者使用CodingKey重命名它们以直接存储基本示例。 到目前为止很简单!🤠🤠 struct SurfBoard:可编码{ var品牌:字符串 var size:大小 枚举CodingKeys:字符串,CodingKey […]

Swift 3中的错误处理:尝试,尝试?和尝试!

某些人可能已经熟悉使用关键字try来处理Swift中的错误。 对于那些不知道try是什么的人, try只是一种处理任何给定函数中可能出现的错误的方法。 通常,我们具有“抛出”功能,这意味着它们具有抛出错误的能力,而try是一个简洁的关键字,它使我们能够处理那些错误的可能性。 在构建我们的应用程序时,可以使用三种try形式。 尝试 尝试? 尝试! 如果您对这些变体感到恐惧,那就不要! 而且,如果您不确定要使用哪一个,请不要担心,我已为您覆盖。 正如我之前提到的, try通常与throw函数结合使用,因此我们将讨论一下throw函数,并在实际中使用try关键字。 假设我们正在尝试通过一些JSON进行解析,以便可以将这些数据带入我们的应用程序。 此数据可能由于互联网中断而无法到达我们的应用程序,或者您尝试提取的数据不再存在! 这些都是在我们尝试从API检索数据时可能出现错误的情况。 但是Swift的JSONSerialization方法具有内置函数,默认情况下throws 。 Swift知道我们检索数据的尝试可能会带来一些错误,并创建了一个函数,该函数使我们能够在发生错误的情况下解决该情况。 使用try ,我们的throw函数必须包装在do-catch语句中。 这使我们能够自定义错误处理并根据错误执行特定的操作。 下面我们将使用try来优雅地捕获任何错误。 做{ 让responseJSON =试试JSONSerialization.jsonObject(with:data,options:[])as! [[String:Any]] 完成(responseJSON) } { 打印(“嗯,这里出了点问题。请尝试连接到wifi。”) } 作为开发人员,将try与do-catch语句一起使用可使我们检查有意义的错误,以样式处理它们,并避免用户感到沮丧。 考虑一下,我们是否真的希望我们的应用程序在用户没有任何互联网连接时崩溃,还是我们要让他们知道该应用程序一旦连接到wifi就会继续运行? 在这种情况下,通知会更有帮助,而我们的do-catch语句使我们可以做到这一点。 另一方面,我们也可以使用try?处理错误try? 。 如果您有使用可选控件的任何经验,那么您很快就会意识到该try? 就是这样。 try? 让我们忽略我们的错误,并在我们的函数将其抛出时让它们变为nil。 因此,我们不必将代码包装在do-catch语句中。 但是,如果要分配try?我们是否必须解开变量try? 有价值。 让responseJSON =试试吗? JSONSerialization.jsonObject(with:data,options:[])as! [[String:Any]] 如果让responseJSON = responseJSON { print(“是的!我们刚刚包装了responseJSON!” } 上面的代码为responseJSON分配了一个可选值,并在调用的函数引发任何错误时将其设置为nil。 使用try? […]