添加对可编码类型的支持 更新,2018年10月14日: 自撰写本文以来,这些博客文章中描述的概念已被分为两个开源框架,可以在这里找到: ka-ching-as / FireSwift-Database Firebase实时数据库的扩展,可以使用“ Codable” Swift类型。 … github.com ka-ching-as / RxFireSwift-Database Firebase实时数据库的RxSwift扩展— ka-ching-as / RxFireSwift-Database github.com 背景 Firebase实时数据库是构建应用程序的绝佳工具。 有很多文章介绍了使用Firebase的一些优点,因此,本篇文章不会对此进行详细介绍,而是假定您已经对该技术有一定的了解。 Firebase的iOS API当前是用Objective-C编写的,尽管这些API在Swift中表现得很好,但这确实意味着我们无法利用Codable支持之类的仅Swift功能。 这篇文章(以及随后的几篇文章)将探讨向Realtime Database API添加漂亮和“ Swifty”扩展的可能性。 总览 以下是有关这些帖子的概述: (本文)增加了对Codable类型的支持。 向数据库中的数据添加类型安全的路径 (尚未发布)添加RxSwift扩展以将数据提供为Observables 动机 第一篇文章的动机是使您可以将存储在Realtime数据库中的数据视为模型对象,而不是纯数据。 在第二篇文章中,我们将摆脱容易出错的String路径到数据的使用。 第三篇文章的动机是这样的事实,即在如何通过Rx眼镜感知世界以及如何使用实时数据库API方面存在很大的重叠。 即,数据在两个概念中都被视为随时间变化的值。 让我们通过结合概念来利用这一点。 TL; DR 这篇文章的目标是能够将可Codable模型类型与Firebase Realtime Database API一起使用,如下所示:
例如,大多数使用云服务的在线应用程序都需要为开发,Beta测试和生产阶段的不同服务使用不同的环境。 开发人员使用不同的策略,例如使用Plist文件在简单的布尔值或PCH文件中的常量(在Objective-C应用程序上)中的开发或生产之间进行切换。 当我开始从事大型金融应用程序项目时,我注意到与以前从事的大多数项目相比,处理这类事情要复杂一些。 除了诸如开发,认证和生产等原始环境外,后端开发人员团队还创建了一些不同的开发点,以在某些罕见的情况下进行连接以满足特定需求。 这些点可以具有不同的URL和端口,因此移动开发团队需要一种可配置的列表。 使用Plist解决方案似乎是使事情顺利进行的好方法,除了一个非常令人不舒服的原因:在这样的大项目上进行构建可能需要长达10分钟的时间。 如果您只想更改环境,则必须等待很多时间。 我研究了一种新的解决方案,在这里我想分享一种简单而优雅的方法。 它使用“设置捆绑包”机制,使您可以通过iOS设置访问属性并更改首选项,而无需再次运行该应用程序。 该解决方案消除了在编译应用程序以发送到TestFlight或App Store时访问它的可能性。 在此处找到创建的示例项目。 Allanalves /环境管理器-iOS Environment-Manager-iOS –使用“设置捆绑包”简化管理环境的解决方案。 github.com 创建Settings.bundle文件 设置捆绑包文件用于添加UI元素,这些元素用于配置应用程序使用的首选项。 创建项目后,在“资源”部分的“设置捆绑”类型的项目中添加一个新文件。 您可以使用默认名称。 在项目导航器上,展开Settings.bundle文件以查看其文件。 “ en.lproj”文件夹用于本地化字符串,因此您可以完全本地化它。 “ Root.plist”(您可以在此处找到示例文件)包含所有首选项。 在Root.plist文件中,找到标题为“服务器”的组。 有一个多值类型的项目。 在其中,我们可以添加将标题放置在Titles数组中的项目,并且对于Values数组,对于Titles的每个项目,应在Values数组中存在一个具有相应索引的项目。 在这种情况下,我添加了4个项目:生产,认证,开发和自定义。 我们将使用这些值来标识代码中选择的选项。 为URL添加Service.plist文件 有了值列表,我们可以创建一个Plist文件来存储链接到Root.plist上使用的相同值的所有URL。 分开它们可以使修改URL时更干净,更安全(避免输入错误)。 服务助手 使用帮助程序,我们可以识别在首选项上选择的选项,以获取其URL并获取该选项的URL。 从任何类中,您都可以获取首选类型: 隐藏它以释放 启动到App Store时,这种首选项屏幕不太适合使其可见。 为了避免这种情况,您可以使用Shell脚本,添加类型为“运行脚本”的新构建阶段,并粘贴以下代码: Shell脚本,避免在启动存储时显示环境首选项。 该脚本标识当前构建配置是否为Release,以删除Settings.bundle文件。 另一个应用 首选项机制可以通过多种方式促进和加快例行开发和测试,例如自动记录日志或显示测试帐户(当应用程序使用帐户列表进行选择时使用)。
TL; DR:NSString已替换为String和Character 跳到Swift之后,您会很快发现与Objective-C一起使用的许多常见类型和类都非常不同。 对于任何一种编程语言,所有类型中最重要的一种就是去代表一个字符串。 字符串的基本结构是字符数组。 这些数组只是简单的整数值,并以ASCII字符代码排列。 小写字母将有26个字符,大写字母将有26个字符,空格和标点符号为几个,这就是您所需要的。 ASCII表总共由255个字符组成。 它非常紧凑,只需要7位即可表示所有字符。 最终需要更多的字符。 初始字符集包括非英语字符,以支持某些语言,但不支持所有语言。 在80年代末和90年代初,关于unicode标准的工作开始定义unicode字符表,该表将ASCII的7位字符表示的大小增加到16位。 不再可能用短整数表示字符,并且字符串也必须更改。 最近,现代计算机和移动设备上受支持的字符集已扩展为支持表情符号,更多的表情符号被定义为大型集合的一部分。 当电子邮件和短信成为主流时,人们只是发明了表情符号来传达一种简单的情感或缩写,如LOL或LMAO 。 现在很明显,大多数人喜欢将表情符号用于同一目的,而且个性更多。 通常,除非有必要使用字符串深入研究细节,否则我们不必考虑它。 作为一种现代语言,Swift支持unicode和emojis作为该语言的自然组成部分。 离开NSString可能很难适应新的构造。 Swift字符串中的各个字符可以用双向链接的节点列表遍历,而不是简单的数字查找代码数组。 每个节点都与可用于访问字符的索引相关联。 这似乎很复杂。 一个简单的例子可以说明它是如何工作的。 看来,Swift使字符串变得更加复杂,但实际上所做的是包括对以不同方式表示的字符的支持。 下面的要点更详细地显示了String和Character类在Swift中的工作方式有多么大的不同。 对于ASCII字符,它仍然很简单,但是使用表情符号,您会发现单个“字符”实际上是由一系列整数值表示的。 将以下代码放入Swift Playground中,并亲自查看输出。 当您在Playground中试验代码时,您会发现有处理字符串和字符的新技术,它们与NSString和C字符串完全不同。 下一页:无财产
关于如何 创建 此实验项目的 虚构说明 。 3月15日。 从总部收到备忘录。 他们想在React Native中看到一些东西。 Swift和Java是合格的。 他们正在出路。 我们需要新的热点。 反应本机。 您编写了一些JavaScript和繁荣。 您将获得一个iOS和一个Android应用程序。 您可以立即重新加载代码。 您会得到一个由强大的枪支支持的狂热的开源社区。 脸书 爱彼迎。 乌克兰有人。 大枪。 因此,拉起一些教程,复制并粘贴一些示例代码,然后开始构建一些东西。 随便啦 我是一位本机应用程序开发人员,在Objective-C,Swift,Java甚至Android NDK的多平台C ++代码方面都有丰富的经验。 当HTML5尽其所能地进入应用程序游戏时,我大笑并嘲笑了它徒劳的尝试。 但是React Native引起了一些严重的轰动-我的意思是,乌克兰的一个家伙-而且大佬们想要一些东西。 随便啦 哦,我给你点东西。 3月16日。 我什么都没有 3月17日。 设法使React Native的Hello World应用程序等效于在iOS模拟器和Android模拟器上加载。 但是,这几乎不像按Xcode中的“播放”按钮那样简单。 必须在项目目录的根目录中打开命令行,并为iOS输入一条运行指令,为Android输入一条单独的指令(要求已打开仿真器)。 说到IDE,我决定使用Atom,而Nuclide在其之上。 让我想起了Eclipse时代的Android插件。 那些日子我不想被提醒。 但是,直到发布某种React Native Studio为止,它都必须做。 还安装了Yarn软件包管理器来替换npm,仅因为我认为“ yarn add”和“ yarn remove”是安装第三方React Native组件时要记住的简单易懂的命令。 事实证明,纱线初始化和安装也明显比npm更快。 这绝对至关重要,因为星期五。 npm命令 npm […]
最近,一系列文章—在Swift中构建声明性动画框架引起了我的注意。 John指出了在iOS中实现动画的问题,这是我们在动画中添加的步骤越多,代码就变得越复杂和难读。 因此,他创建了一种声明性的方式来处理动画,这确实使我们的代码更加简洁易读。 如果您还没有阅读那些文章,我强烈建议您访问它。 为什么要进行声明式编程 作为开发人员,我们不仅致力于实现可行的功能,而且还尝试增加代码的维护性。 为了保持代码的健壮性,至关重要的是在编程过程中保持高水平的表现力。 据说声明式编程可用于实现我们的目标,因为它的基本概念之一是描述开发人员的意图。 此外,如果我们以声明性的方式编写代码,那么我们将获得真正的关注点分离,因此将带来可测试性。 总体而言,声明式编程是一个有用的想法,值得一试。 实作 在本文中,我想演示一个声明式编程的简单示例,该示例可以在UIView实例中创建不同的形状。 此外,我利用CAShapeLayer的优势来实现矩形,椭圆形,三角形和直线等形状。 首先,让我们集中精力创建矩形并编写CAShapeLayer的扩展,如下所示。 extension CAShapeLayer { static func rectangle(roundedRect: CGRect, cornorRadius: CGFloat, color: UIColor) -> CAShapeLayer { let path = UIBezierPath(roundedRect: roundedRect, cornerRadius: cornorRadius) let shape = CAShapeLayer() shape.path = path.cgPath shape.fillColor = color.cgColor return shape } } 其次,为了在UIView实例中显示矩形,有必要编写UIView的另一个扩展。 extension UIView { func draw(_ […]
当最初的iPhone推出时,就像大多数人一样,我对它的多点触摸界面着迷。 像滚动和缩小缩放这样的手势立刻变得有意义,不仅如此,它们还消除了使用应用程序的某种程度的间接性,而该应用程序是到目前为止所有计算机交互的一部分。 您现在不用触摸鼠标来移动光标,而是直接触摸该应用程序并与之交互。 尽管这可能看起来很小,但对可用性的影响实际上却很深远。 像通过多点触控界面平移和缩放地图或照片一样,这没有什么比。 感觉就像是一种自然的互动。 多点触摸对软件创建过程也产生了有趣的影响。 UI设计始终存在一个方面,通常被描述为“工艺”或“良好设计”,这代表着质量。 但是,触摸界面改变了它的含义,因为它真正成为了制作界面的方法,创造了一种可触摸的,几乎是(甚至不是实际上)有形的东西。 任何发现自己正在玩UI动画的人都会理解这一点的重要性。 在iOS主屏幕上向下拉几下,以模糊处理并显示聚光灯搜索字段,类似于在精心设计的物理对象上玩按钮。 软件变得有触觉。 同样,Swift游乐场-以及它们之前的iPython笔记本电脑-等同于编程的多点触控。 以相同的方式,iPhone通过删除(或隐藏)了构建步骤,从而改变了我们与应用程序交互的方式,从而使编程更加直接。 它们消除了间接的影响,使您的算法并存或与结果并存。 看起来有些小的变化实际上对您的代码使用方式,建模方式,调整方式(触摸方式)产生了深远的影响。 我最近在设计iOS组件以显示火车上的占用情况时遇到了这种情况。 在运行周期中,我没有使用PaintCode等工具或传统的构建工具,而是创建了一个Swift Playground并在此处组装了零件,并为乘客提供了一个小图形: (实际的绘制代码非常简单,为简洁起见,仅将其隐藏在屏幕截图中。) 这项练习是一个愉快而有趣的过程,并鼓励我继续前进。 我需要一个小徽章来显示滑架编号,并用一种颜色指示它有多忙,这是滑架上的覆盖物: 就像乐高玩具一样,但是有代码! 让我们仅将其中几辆车粘贴在火车上即可: 在Swift Playground中设计这种视图既令人高兴又轻而易举,但不仅仅是效果很好。 您可能已经注意到,徽章与汽车的线性比例并不线性。 对于较小的尺寸,它们成比例地较大,因此数量仍然清晰可辨。 我为此使用了S型函数,很容易显示它的外观并在操场上对其进行调整: 我在Swift游乐场旁边提到了iPython笔记本,因为它们已经存在了很长时间,并且我使用它们的效果与Swift Playgrounds类似。 但是,我怀疑Swift游乐场会远远超过它们,原因有二: 苹果公司对Swift的支持及其开放源代码项目引起的极大兴趣,意味着它是一种前景非常广阔的语言,很可能会比Python广泛采用。 iPad上的Swift Playgrounds以及在macOS上更专业的Xcode的可用性,使它们面向了全新的受众。 与现在许多没有鼠标和硬件键盘作为主要输入设备的人一样,我相信会有一代开发人员编写的代码与传统的编辑,编译,运行周期大不相同。 目前让Swift Playgrounds退缩的一件事是它们对macOS或iOS的限制。 尽管Linux上提供了Swift,但Swift Playgrounds却没有。 两全其美的是Jupyter笔记本电脑使用的Swift内核,实际上使Swift Playgrounds可以在任何可以运行支持Swift的开源堆栈的平台上使用。 那不是一个有趣的项目!
今天,我们将讨论代理模式。 在这种模式下,代理是一个对象,可以帮助我们访问另一个对象。 它只是将实际工作委托给该对象或更改其行为。 下图描述了角色及其关系。 从代理模式开始— Wikipedia 代理模式在Cocoa中广泛使用,它甚至具有特定的NSProxy类。 另一个示例是UIApperance协议和其他相关类型。 我们将继续使用我们的汽车系统。 protocol Car { func drive () } class Sedan : Car { func drive () { print (“drive a sedan”) } } 自动驾驶汽车现在是热门话题。 因此,让我们构建自己的。 实际上,它不是从头开始构建的,而是通过自动驾驶系统增强了我们当前的汽车。 因此,它具有内部汽车实例,并将驾驶委托给汽车。 但是作为自动驾驶汽车,它会自动控制汽车。 委托和变更是代理在此模式下的工作。 class AutonomousCar : Car { var car: Car init (car: Car ) { self. car = car } […]
简介:在iOS开发中,我们每天都使用Array。创建数组的方法有很多。我认为了解Array是什么以及为什么我们可以通过多种方式创建它更重要。在本文中,我将解释什么是array和我们如何通过许多方法创建它以及修改数组中的更新和删除元素。 什么是数组: swift中常见类型的数组。数组可以是Int,String,bool,Class或struct之类的任何时间,也可以是任何类型类似于data type的数据。 示例:如果我们需要存储我们日常购物的5个名称,我们将使用Array来存储以下内容: 这是5个可以这样存储的项目名称。所有通过其索引.index短接的项目都从零到项目数减一。 数组可以是任何类型的元素,例如Int,String,Class,Struct以及Any 数组是Swift中常见的遗传结构类型,用于存储相同类型数据的集合 阵列可变性: 数组可以像var和let一样是可变的或不可变的。如果它的var我们可以更改,则可以更改它。 那么我们如何创建数组: 有很多方法可以创建数组,例如使用默认的初始化程序,带有空元素等。但是Swift是类型安全的语言,在创建数组时我们必须分配类型。将类型提供给swift编译器的两种方法是隐式或显式的。我们将发现所有办法 。 创建空数组: //隐式定义的空数组 let arrayOne = Array ()//隐式定义的空数组 let arrayTwo:Array = Array()//空数组 让arrayThree:[Double] = [] //短于 let arrayFour = [Double]()//短于 我们在这里看到,需要指定类型,因为Array结构是泛型类型: struct Array :RandomAccessCollection,MutableCollection { //确认所有协议方法 //初始化器 //方法 //下标 } 因此,这就是为什么我们需要向Swift Compiler指定什么是Element。 使用初始化程序创建数组: //带有初始化程序的数组 1.let arrayFive = Array([1,3,4,5,6]) //使用数组文字 2.let arraySix = Array(arrayLiteral:1,2,3,4,5) […]
您可能已经在某些Apple的默认应用程序中或在iOS上编辑文本时看到了此工具提示控件。 该工具提示实际上有一个名称UIMenuController ,并且可以自定义并在您自己的应用程序中使用,尽管该API可能很难理解。 成为FirstResponder() 与应用程序具有源自UIWindow的UIView层次结构类似,它也具有UIResponder链,因为视图本质上是响应者。 为了在自定义视图上使用UIMenuController ,该视图必须首先成为应用程序的第一响应者。 在应用程序中,首先接收多种事件的响应者对象称为第一响应者。 它接收关键事件,动作事件和动作消息等。 这并不需要花哨的东西,但是在处理多个UIResponder子类时,了解响应者的层次结构很重要。 尽管UIView基类继承了UIResponder接口,但它不会自动赋予UIView实例成为第一响应者的能力,这就是为什么您只能在UIView子类上调用.becomeFirstResponder() 。 默认情况下,某些iOS控件(如UITextField可以成为第一响应者,但是对于自定义视图,您需要覆盖canBecomeFirstResponder变量。 现在, ResponsiveView任何实例都可以调用.becomeFirstResponder()并成为其超级窗口的第一个响应者,并且由于UIView基类默认将其UIResponder变量canResignFirstResponder为true,因此我们也可以在ResponsiveView上调用.resignFirstResponder() 。 。 UIMenuController 现在我们有了一个自定义视图,可以将其设置为应用程序的第一响应者,让我们在其上显示一个工具提示! UIMenuController具有一个单例实例,您可以在您的应用程序中使用它来轻松地使用多个视图-这样可确保您不会一次显示多个菜单。 请注意,在显示菜单之前,我们必须指定responsiveView View的框架。 这是因为UIMenuController使用此信息将自身适当地放置在窗口中的适当位置。 默认情况下,菜单将显示在第一响应者上方,其箭头指向下方。 您当然可以通过设置箭头方向,指定与第一响应者不同的帧,甚至为目标矩形计算指定不同的超级视图来自定义此行为。 UIMenuItem 在显示菜单之前,我们想要设置一些选项以使其首先显示在菜单中。 例 这是上面的代码示例。 我更喜欢使用minimumPressDuration为0.3的UIMenuController来触发UIMenuController ,因为它模仿了iOS中的默认行为。 如果您对Twitter @sdrzn有任何疑问或想法,请告诉我!
您的iOS应用需要后端。 有了Parse关闭店,现在该怎么办? 寻找解析替代品还是建立自己的后端? 我坚定地处于“学习构建自己的”后端阵营中。 许多开发人员建议不要构建自己的后端。 BaaS关闭后,这些开发人员争先恐后地寻找下一个替代BaaS。 然后他们会尝试说服您也使用替代BaaS。 但是我们都知道不可避免的事情会再次发生。 有一天,您会收到来自BaaS提供商的一封意外电子邮件,通知您他们即将在新应用程序版本发布期间关闭。 我记得发生在我身上的时间-我依赖于关闭的BaaS。 当我第一次看到关闭的电子邮件时,我感到很习惯。 我感到被出卖了。 然后我感到生气。 当我陷入螺旋式下降时,我孤立了自己。 我在冰淇淋上喝了些什么,然后在淋浴中抽泣时听了席琳·迪翁的歌。 我应该已经看到它的来临,但是我对服务所提供的便利性和稳定性的幻想着迷。 但是,仅此而已-一种幻觉。 那么,为什么夜以继日的BaaS提供程序会不断出现并向我们所有人贫穷的移动开发人员这样做呢? 建立自己的后端的想法似乎不可行。 学习有关构建后端的一切都是很多工作。 这就是为什么一开始BaaS似乎是一个不错的选择。 但是,如果您想摆脱对BaaS的依赖,而是构建自己的后端,那么这就是窍门:不要尝试学习有关后端的所有知识! 从小开始。 当您构建第一个iOS“应用”时,您可能并没有专注于使其具有可扩展性和可维护性。 第一次回收这些UITableview单元并显示错误的数据时,您并不会花费太多精力。 您可能并不担心您的应用程序应该遵循MVC还是MVVM还是MMVCM(我最后讲了)。 我敢打赌,您的第一个应用程序可能甚至从未通过模拟器。 我建议使用相同的方法来构建后端:从小处着手。 不管有多小,都首先要工作。 然后在此基础上。 后端后端方法 您无需将自己埋藏在有关Python或Ruby的书中,也无需学习有关服务器的所有知识,即可启动并运行后端。 设计整个API,进行部署和扩展-所有这些事情都可能在以后出现。 首先执行以下操作: 编写一个iOS函数,即使在构建后端之前也可以调用您的后端 这是一个例子。 假设您决定第一个函数将进行API调用以检索特定用户的消息。 以下用Swift编写的函数向尚不存在(但很快会出现)的本地服务器上的“ / get_messages”发出POST请求。 让我们看一下该函数的代码: func printMessagesForUser()->无效{ 让json = [“ user”:“ larry”] 做{ 让jsonData =尝试NSJSONSerialization.dataWithJSONObject(json,选项:.PrettyPrinted) 让url = NSURL(string:“ http://127.0.0.1:5000/api/get_messages”)! […]