它只是从Cocoanetics的一个简单Tweet开始: 有没有更好的办法使带有相关值的枚举相等? 大多数回答都是纯技术性的(但有效的)答案。 简而言之:“ 您应该使用开关,但仍然需要比较所有情况 ”。 好。 但是上面的代码对我来说仍然是错误的,因为他试图使两个不同的情况相等,只是因为它们具有相同的关联值。 在这种情况下, .afterID(42) == .beforeID(42)为true ,这可能很危险。 也许不是立即,而是将来,这种特殊性将被忘记,并且开发人员将依赖于常规的Equatable实现,而这两种情况不可能相等。 我们如何通过这两个要求来改进此代码: •两种不同的情况不能相等。 • .afterID(_)和.beforeID(_)相等的标识符必须易于检查。 一个简单的第一步可能是对案例执行严格的相等性检查,并使用identifier属性比较检查标识符是否相等: 它看起来很棒: QF.afterID(42)== QF.beforeID(42)//否 QF.afterID(42).identifier == QF.beforeID(42).identifier // true \ o / 但是问题在于它可能导致奇怪的结果: QF.noFilter.identifier == QF.offset(42).identifier //是 那么,如何在没有这种奇怪行为的情况下做到这一点呢?
这篇文章假定您在计算机上安装了Postgres,并且已经创建了一个数据库。 步骤1 创建一个新的蒸气项目并生成一个xcode项目。 蒸气新的dbsetup 蒸气Xcode 第2步 将Postgresql-provider存储库添加到Package.swift文件中的依赖项数组。 包(URL:“ https://github.com/vapor/postgresql-provider.git”,majorVersion:2,minor,0) 第三步 打开Config / fluent.json并将所有现有代码替换为下面的代码段。 { “驱动程序”:“ postgresql” } 步骤4 使用以下json在Config / secrets / postgresql.json中创建一个新文件。 不要忘记更新您的用户名和数据库名称。 { “主机名”:“ 127.0.0.1”, “ user”:“ $ PUT_USERNAME_HERE”, “ password”:“”, “数据库”:“ $ PUT_DBNAME_HERE”, “端口”:5432 } 第5步 在App / Config + Setup.swift文件中, import PostgreSQLProvider并将以下行添加到setupProviders函数中: 尝试addProvider(PostgreSQLProvider.Provider.self) 第6步 让我们验证一切是否正常。 运行以下命令以更新xcode项目: 蒸气Xcode 选择“运行”方案并定位“我的Mac”并运行项目。 该项目应生成并运行,并且控制台将记录“数据库已准备好”。 您可以使用psql检查发布表是否已创建。 如果遇到任何问题,请尝试在此处使用示例项目: […]
平等。 字符串,双精度字,字符串和双精度整数,操作员binario == queharáel trabajo requerido。 Ejemplo: 佩罗·奎·帕萨(Pero¿) 请参见“ 编译器必填项: 二进制运算符’==’不能应用于两个’Cliente’操作数 ”。 德阿库多:是的! 没有幻想,迷惑不解。 符合基本协议的协议。 啊! 否否客户端1 ==客户端2,则没有问题(客户端!),请不要在客户端上使用sapro。 不能完全扩展的功能 。 客户可以在“任何客户使用”上查看“客户身份”,“客户身份”和“客户身份” 。 重要事项:协议的可食用性,等价的海,等价物,反射性的cumpla con laspropiedade,simetría和transivividad。 从整体上了解客户的需求。 Reflexibidad :cliente_ A == cliente_ A Simetría 。 cliente_ A == cliente_ B 隐含 cliente_ B == cliente_ A Transitividad 。 cliente_ A == cliente_ B && clienteB == […]
多单元转换可能是使用大型视图控制器的最大原因。 我已经在互联网上进行了广泛的搜索,发现的并不是一个庞大的视图控制器。 我敢肯定我们都看过这样的东西👇👇👇👇👇 不,我不会谈论MVVM。 我们可以做得更好! 第一个解决方案将是Swift 4.2,然后是Swift 4.1 30号线 UserTableViewControler符合CellDelegate 可能不是分配委托的最佳方法。 但这是避免多细胞铸造的关键。 您还可以避免对多个单元格进行检查,从而使tapped()成为可选选项,但是我很累,因此我将让您弄清楚这一点。 1号线 参数类型T提供了更大的灵活性,并避免了针对不同数据类型的多种协议。 由于CaseIterable在swift 4.1上不可用,因此枚举的RawValue类型为Int,标识符变量返回单元格标识符。 而已! 其他一切都保持不变。 在GitHub上下载完整的解决方案。 Swift 4.2 https://github.com/ErickApps/ProtocolCellsSwift4.2 Swift 4.1 https://github.com/ErickApps/ProtocolCellSwift4.1 确保跟随这些家伙 保罗·哈德森 推特:@seanallen_dev 推特:@buildthatapp 雷·温德利希 结论 不是MVVM解决方案🤪 减少键入和调试。 不再施力👇👇👇👇👇👇 批评总是受到欢迎。 在Twitter上让我知道:@ pitjits u
作为程序员,我们花费大量时间编写程序来解决问题,自动化任务,收集数据,分析数据以及制定希望使我们的用户生活更加轻松的决策。 我们的大多数白天编程本质上都是实用的,因为世界是建立在截止日期和预算以及用户故事和冲刺之上的。 只有当孩子们开始入睡并且白天的烦恼逐渐消失在背景中时,我们才能编写夜间程序,探索程序,学习程序,存在性程序。 我因此编程! 不,这不是一个存在的类型,只是一个me脚的笑话。 临时多态性 在这样一个探索的夜晚,我想尝试Swift的即席多态性。 临时多态性听起来很有趣,但是每所小学都理解并使用它。 1 +1 = 2 1.0 + 1.0 = 2.0 加法运算符使我们可以将整数相加,将浮点数相加,将玩具熊甚至是Elsa娃娃相加。 小学孩子们知道加法不限于事物的一个特定子集。 当然,编程语言从来都不是那么直观的,通常来说,我们使用的语言很少支持即席多态。 例如,在OCaml中,我们有一个不同的运算符来添加整数和浮点数。 1 +1 = 2 1.0 +。 1.0 = 2.0 Java和.Net都不是更好,因为它们都不允许我们将相同的函数应用于不同的类型。 但是,Swift的精神是使专业人员和学龄儿童都可以访问编程,并且由于学童们了解临时的多态性,也许职业程序员也应该这样做。 协议编号{ 关联类型A 静态函数Add(x:A,y:A)-> A } 扩展名Int:Num { 静态函数Add(x:Int,y:Int)-> Int {return x + y} } 扩展名Double:Num { 静态函数Add(x:Double,y:Double)-> Double {return x + y} } […]
Ich alsselbstständigerApp Entwickler mus immer schauen,是Ball zu bleiben。 Einen neuen Trend的趋势来自kürzesterZeit kein Geld mehr verdiene中的dassich。 不愿透露姓名的人是Flash Entwickler,我的名字是meinten,而dass Flash的名字是DASGROßEDING bleiben wird。 在德国的时代与历史上的Viele haben sich,在Leben lang das Geld mit der der Schubkarre上的Hause fahren。 Leider weit gefehlt和ich kenne nun schon einige Beispiele,在eine finanzielle Notlage gerutscht中丧命。 Ich muss mirnatürlich和darüberGedanken机械师。 Android和iOS上的Native Native App Entwicklung中的Meine Kernkompetenzen liegen。 Allein damit bin ich […]
欢迎来到一系列致力于学习设计模式的文章。 尽管许多想法与代码无关,但我们的目标是向您展示如何在Swift中实现它们(在撰写本文时为Swift 3.0)。 每个帖子彼此独立,所有项目代码都可以 在Git上找到 。 传统上,工厂模式是面向对象语言中使用最多的模式之一。 Factory模式的作用是在运行时使用多态为对象分配一个类。 当客户端不知道所需的确切类时使用它。 所有可能的类都从相同的超类扩展(或实现相同的接口),从而为我们提供了许多可供选择的类。 神奇宝贝就是一个容易证明的例子。 入门级神奇宝贝(Bulbasaur,Squirtle和Charmander)都属于神奇宝贝。 他们有共同的特征。 例如,它们必须具有名称,并且必须具有类型。 但是,尽管它们需要名称和类型,但每个神奇宝贝的名称和类型都不同且有所不同。 这在代码中意味着什么,就是我们有一个神奇宝贝超类。 该超类将包含对名称和类型的引用。 然后使用继承,我们继承了共同的特征,并针对我们想要的神奇宝贝专门对其进行了操纵。 我们将构建一个程序,询问用户他们希望他们的入门神奇宝贝是什么,然后将正确的选定数据返回给用户。 以下是UML图中的外观: 码 首先,在Xcode中创建一个新项目。 我们不会在UIKit中碰任何东西,因此创建一个macOS Terminal项目。 首先,我们将创建所有神奇宝贝都将继承的神奇宝贝超类。 它看起来像这样: 接下来,我们将创建每个单独的神奇宝贝。 这些类非常简单。 它们只需要初始化,在初始化期间,我们将设置名称和类型。 这些看起来像这样: 现在我们需要创建实际的工厂类。 这是上演魔术的课。 它将包含一种方法。 我们将为其提供一个字符串,作为回报,它将基于该字符串为我们提供一个神奇宝贝对象。 它看起来像这样: 请注意,由于神奇宝贝可能为nil ,我们需要使用问号将其设置为可选。 将它们放到我们的主类中将如下所示: 我们要求用户选择一个神奇宝贝。 如果存在,则返回正确的神奇宝贝,如果不存在,则向用户显示一条消息。 运行程序。 这是一个示例,如果您为Bulbasaur选择“ B”,您将在终端中看到以下内容: 选择您的首发口袋妖怪(B =鼠尾草/ C = man火鸡/ S =松鼠) 乙 您选择了Bulbasaur。 这是草宝可梦 程序以退出代码结束:0 多数民众赞成在工厂模式完成! […]
Swift已经引入了称为Optional的新型变量。 这些用于迅速保持零值。 由于存在这些变量,因此有关变量的初始化有一些更改。 这是相同的详细信息: 1.如果使用非可选属性,则必须快速启动初始化程序。 2.您需要先解开可选变量,然后再使用它们: 3.如果Property可以为nil,则使用? 属性之后,设置任何值之前: 4.如果在声明时解开属性,则可以直接使用它。 请注意,这不被认为是一种好的做法,因为它可能会在运行时导致崩溃。 5.在Swift新版本中,如果使用init方法,则需要实现initWithCoder方法。 6.在访问自身属性(例如视图)之前,必须在init和initWithCoder期间调用超类方法 。 7.您可以在调用超级方法之前创建对象,之后可以为该对象分配值: 8.您可以创建惰性属性,在惰性属性中,您可以在声明时分配值,但是只要我们使用该属性,就会执行Assign语句。 请注意,Lazy属性应始终使用var而不是let,因为常量在初始化之前必须具有值。 9.您可以使用Closure在惰性属性中添加任何逻辑。 您甚至可以在惰性属性中调用类OR实例方法 10.如果定义了任何自定义初始化程序,Swift会将它们区分为便捷初始化程序。 必须从便捷初始化程序调用任何默认的初始化程序(指定的初始化程序)。 需要修复如下:
在xib文件中,创建自定义视图通常最容易,您可以在其中可视化,布局和编辑要构建的外观。 从xib将这些视图获取到应用程序的屏幕要比看起来应该复杂得多,要比在iOS开发中这种模式有多普遍。 以下是一个非常简单的教程,说明了整个过程: 创建一个新的单视图应用程序项目 2. 创建一个xib文件 右键单击屏幕上项目文件所在的部分(视图控制器,情节提要等),然后选择“新文件”。 Xcode会提示您要创建哪种文件类型。 在“用户界面”菜单下选择“查看”选项。 在接下来的弹出窗口中,系统将提示您命名xib,我们将其命名为“ TestView”。 3.在Interface Builder中设计视图 我们插入了一个UILabel并将其约束到屏幕的中央。 您可能需要更多的参与。 我们还将背景颜色设置为粉红色,以便在最终运行应用程序时更容易看到。 您可能需要做出其他设计决策……。 如果要更改xib的形状,请单击右上角的“属性检查器”,并将大小更改为“自由形式”。这将允许您单击视图并根据需要更改形状。 正如您在本教程结束时将看到的那样,选择的形状实际上并不重要,但是您可能希望使xib大致上与您在应用程序中使用的形状相同,以帮助布局您的xib。元素。 4.创建一个自定义的UIView文件 现在我们有了xib,我们需要创建将控制它的定制UIView类。 右键单击所有文件所在的位置,然后再次选择“新文件”,但这一次在“源”菜单下选择“可可接触类”。 当提示您命名新文件时,请确保将其设置为“ UIView”的子类。 Xcode可能默认为另一个Cocoa类。 在本教程中,我们还将这个文件命名为“ TestView”,因为它将与我们刚创建的TestView xib相关联。 5. 覆盖两个UIView初始化程序 这是有些棘手的地方。 可以通过两种方式创建UIView:在界面构建器(即情节提要或xib)中或直接在代码中。 对于每种创建方法,它们都有一个初始化程序,我们需要用我们自己的自定义初始化程序覆盖这两个方法。 当您创建自定义UIView时,您将看到一个空文件,其中有一些Apple添加的注释,暗示我们将要做的事情: 删除注释,然后键入以下内容: 我们只是覆盖了两个UIView初始化程序,并调用了名为commonInit的初始化程序(您可以随意调用它)。 不幸的是,我们的初始化程序还没有做任何事情。 别担心! 我们很快就会到达那里… 6. 添加UIView作为Xib文件的所有者 我们快到了–我们现在有了一个xib文件和一个自定义UIView,我们只需要连接两者即可。 单击回到您的xib文件,然后单击占位符部分下的“文件所有者”选项。 然后,在屏幕的右侧,在“身份检查器”中,将UIView文件的名称(TestView)作为类。 这应该是自动完成的,如果没有完成,则可能是您做错了什么。 7. 将整个视图作为IB出口添加到UIView文件中。 现在,您已经将自定义UIView添加为文件的所有者,您应该可以点击右上角的助手编辑器按钮,并将视图与xib并排加载。 按住Ctrl键并拖动整个视图作为视图文件的出口。 您可以随意命名,但是将其命名为“ contentView”是一个很好的模式 您也可以将其他任何元素拖入IB出口。 在这种情况下,我们所拥有的只是我们的标签,因此我们也将其拖入其中。 现在,我们的视图文件如下所示: 8. […]
在这篇文章中,我将讨论在我正在努力使IOS应用程序开发更强大的项目中使用的其他可重用类。 我最近需要导航路由器来处理网络请求中不同类型的URL,处理一堆.GET,.POST,.PUT。 删除HTTP请求类型等 使用单独的类来处理网络任务是一个好主意。 因此,使用自定义路由器。 它当然是基于Alamofire。 什么是路由器? 路由器是一种处理API /微服务url的面向协议的方法,但将自身用作枚举是一个更好的主意。 通过从枚举案例中生成URL请求,这将无缝地在发出请求时帮助统一和简化网络路由。 因此,另一种方法启发了我一些概念,您可以阅读LittleBitesOfCocoa中的博客文章。 公平地说,它更轻巧,但不能满足我的要求。 #93:为Alamofire创建路由器🔀🔥 Alamofire 3.0(https://github.com/Alamofire/Alamofire/blob/master/Documentation/Alamofire%203.0%20Migration%20Guide.md…littlebitesofcocoa.com 创建路由器协议 首先,创建一个协议RouterProtocol来处理四种方法,以使REST兼容(获取,发布,更新,销毁),以处理常见的API请求(我刚刚声明了自己的ApiType来获取API URL的路径/路由,因此不是)在上下文中,则省略。) 接下来要做的就是创建一个路由器枚举 ,这个实现为什么呢? 我会解释。 首先,我们需要遵循RouterProtocol才能使用我们的功能。 Router枚举必须为通用类型,必须接受具有RouterProtocol一致性的任何类型的结构。 它接收四个动词(.GET,.POST.PUT,.DELETE等),因此可以为其声明方法,路径和路由属性。 将URLRequest属性创建为NSMutableURLRequest,因此添加常用配置,例如方法,默认标头,OAuth令牌(如果可用)等。 最后,使用Alamofire的参数编码可以执行所需的编码。 用法 使用路由器非常简单,只需在ApiManager中声明一个方法(我将在另一篇文章中介绍我的ApiManager版本) 在我的示例中,getAccounts方法将AccountsRequest作为输入 ,response作为AccountsResponse作为输出,此类仅是结构,您可以自己滚动 (仅供参考:在另一篇文章中,我将向您介绍基于“请求/响应”结构的方法) 您的经理(当然,它封装了Alamofire实例)会执行请求(可到达性和微调器内容不在上下文中。我会在此处发布有关可到达性的信息,您可以在此处阅读) Alamofire管理器将Router枚举作为输入,并具有我们的RouterProtocol,我们说这是一个.GET请求,所以我确实将诸如accountRequest.accountId的值作为String传递,因为在协议中。GET匹配请求具有“ case get(T,String) ” 如果我们需要说这是一个.POST请求,则协议.POST可以将 [ String:AnyObject])作为参数,因此,这一次我必须将我的accountRequest输入传递为cast到Dictionary()? [String:AnyObject])等 简单! 例如; Router.get(AccountsRouter(),accountRequest.accountId!)。URLRequest 现在,您可以看到为任何种类的Api创建任何种类的Router都具有表现力。 它始终严格定义,可理解且干净。 这篇文章中的代码,托管在Github中 seyhunak /路由器 在Swift github.com中使用路由器为IOS应用程序更好地路由 感谢您的阅读,希望您喜欢。