Tag: Swift 5

如何在可编码协议中使用Swift 5结果

我已经写过有关Alamofire API管理器的文章,但是有了新的Swift 5 Result功能,我想对其进行一些升级。 我们将它与Codable协议一起使用,使我们的生活更加轻松。 如果您不是Alamofire粉丝,则可以将其删除。 但是,结合Codable和Result的原理,您应该尝试在网络处理程序中实现。 这个想法是建立一个可重用和直接的API管理器。 我们必须使用单一职责原则创建一些帮助程序类-ErrorObject,EndpointType,EndpointItem,NetworkEnvironment。 我现在不会解决这些问题,因为您在这里。 API管理器 我们的APIManager使用EndpointItem对象创建URL请求。 同样,它解析数据。 使用Codable时,解析是一项简单的任务。 因此,代表数据模型的所有结构和类都应实现Decodable和Encodable协议。 我们使用通用参数T,其中T是可编码的。 T通知APIManager我们正在获取哪种数据以及希望管理器返回哪种类型的对象。 T可以是实现“可解码”和“可编码”协议的任何对象或对象数组。 处理程序需要Result类型。 因此,Result的第一个参数是通用参数T,第二个是错误对象。 我们使用Swift.Result表示法,因为Alamofire也有其Result对象,并且我们需要指定要使用的对象。 APIManager —带有Swift 5结果的通用方法 收到响应后,APIManager尝试解码数据。 如果成功,他将退还。 在其他情况下,它将返回AlertMessage对象。 值得一提的是,Result对象的第二个参数必须符合Error协议。 我们需要扩展AlertMessage对象。 AlertMessage —错误对象 在APIDemoViewModel中,我们使用API​​Manager的方法。 在这里,我们指定要获取的结构,以便将数据解码为适当的对象。 APIDemoViewModel-实现的APIManager通用方法 好处 如果将APIManager与Results和没有结果进行比较,则主要优点是我们不再具有可选参数,并且可以使用强类型引用。 这意味着我们的代码更直接,更容易读写。 结果错误也很重要,因为它们是强类型的,我们可以创建自定义错误,使它们适合我们的项目。 只是不要忘记它需要符合Swift的Error类型。 现在我们确定我们将获得成功或失败,不可能两者皆有或两者皆有。 没有Swift 5结果的APIManager旧版本 结论 我们将Swift 5结果和Codable协议结合在一起,使我们的代码更清洁,更高效。 这是一个简单的代码示例。 如果您有任何问题或建议,请随时发表评论。 资源资源 示范项目 Alamofire Api Manager-原始帖子

如何使用Swift 5在iOS中实现内联日期选择器

我们已经了解了iOS默认的日历应用及其外观。 让我们看看如何像日历应用一样从头开始实现内联日期选择器。 这是典型日历应用程序中的添加事件屏幕的外观。 我希望阅读此博客的开发人员具备使用Xcode创建新项目的能力。 因此,让我们深入研究实际的实现。 我创建了一个分组表视图,并使用setupTableView()方法设置了它的数据源和委托,如下所示。 func setupTableView(){ta​​bleView = UITableView(frame:CGRect(x:0,y:0,width:view.bounds.size.width,height:view.bounds.size.height),style:.grouped) view.addSubview(tableView)tableView.register(UINib(nibName:DateTableViewCell.nibName(),bundle:nil),forCellReuseIdentifier:DateTableViewCell.reuseIdentifier())tableView.register(UINib(nibName:DatePickerTableViewCell.nibName(),bundle:nil ),forCellReuseIdentifier:DatePickerTableViewCell.reuseIdentifier())tableView.dataSource = selftableView.delegate = self} 我们已经声明了两个主要变量。 一个,我们声明了一个字符串数组,其中包含要添加的日期选择器标题文本的数量。 我们有datePickerIndexPath,它包含表视图中当前显示的日期选择器的indexPath。 var inputTexts:[String] = [“开始日期”,“结束日期”,“另一个日期”] var datePickerIndexPath:IndexPath? 现在我们来看主体部分,数据源和委托方法。 在行数方法中,当未显示日期选择器时,我们返回inputTexts数组的计数。 如果日期选择器当前可见,我们为此添加一个额外的单元格。 func tableView(_ tableView:UITableView,numberOfRowsInSection部分:Int)-> Int {//如果datePicker已经存在,如果datePickerIndexPath!= nil {return inputTexts.count + 1}否则,我们为此添加一个额外的单元格。{返回inputTexts。 count}} func tableView(_ tableView:UITableView,cellForRowAt indexPath:IndexPath)-> UITableViewCell {if datePickerIndexPath == indexPath {让datePickerCell = tableView.dequeueReusableCell(withIdentifier:DatePickerTableViewCell.reuseIdentifier())为! DatePickerTableViewCell datePickerCell.updateCell(date:inputDates [indexPath.row-1],indexPath:indexPath)datePickerCell.delegate =自返回datePickerCell}否则{让dateCell […]

教程设计模式-OOP的力量(第1部分)

先决条件—本博客系列需要具有面向对象编程的中级专业知识。 您应该具有有关类,对象,构造函数,继承,值和引用类型的基本知识。 通过从头到尾阅读本系列文章,中级者将获得知识,专家将增强其知识。 设计模式用于表示经验丰富的面向对象的软件开发人员社区所采用的最佳实践。 生成器设计模式可帮助我们以更简单易读的方式构建对象。 生成器设计模式遵循以下两个简单规则。 分开原始的类表示形式及其构造方法。 在最后一步返回类的实例 问题: 考虑一下类,说Person具有十个或更多属性,当您需要创建Person类的实例时,对它的构造函数进行设计。 它的构造函数将使用十个或更多的参数,很难将多个参数作为单个函数或构造函数进行管理,最终,您将失去代码的可读性。 查看以下示例。 尝试在操场上运行上面的示例,它将成功运行,并为您提供预期的输出。 从逻辑上讲这是正确的。 我们可以通过克服以下几点来改进上面的示例。 我们必须以提到的顺序传递值,不能重新排列参数序列以提高可读性。 即使在对象创建时不知道某些值,我们也必须传递所有值。 例如,假设您需要创建一个Person类的对象,但是此人仍在寻找工作。 当该人加入任何公司时,只有我们会提供作品详细信息。 解: 创建相关属性的逻辑组。 为不同的属性组创建单独的构建器类。 在最后一步中检索实例。 让我们用一个例子简化一下, 在示例WithoutDesignPatternExample1.swift中,我们已经有一个名为Person的类,其中有14个属性。 如果我们仔细检查所有14个属性,则这些属性具有4个逻辑组。 个人详细信息属性 联系人详细信息属性 地址详细信息属性 公司详细信息属性 多面设计和流畅设计模式共同帮助我们克服了上述两个问题。 在上面的示例中,我们将Person类的职责划分为不同的类。 现在, Person类仅包含数据属性,而我们创建了多个构建器类,它们负责构建/更新相对的属性组。 我们有一个基本的构建器类PersonBuilder ,还有四个派生的构建器类,分别为PersonPersonalDetailsBuilder , PersonContactDetailsBuilder , PersonAddressDetailsBuilder和PersonCompanyDetailsBuilder 。 基类PersonBuilder帮助我们随时在多个构建器之间切换,而派生自PersonBuilder的其他四个构建器负责更新相对属性。 在上面的示例中,我们可以清楚地看到,与第一个示例WithoutDesignPatternExample1.swift相比, Person对象的构造更具可读性,而且我们可以随时以更易读的方式更新属性组或任何单个属性。 在上面的示例中,请注意,在调用每个属性更新方法后,我们将返回生成器实例的自身。 这有助于我们编写同一构建器的多个方法的链接,而不是分别编写多行。 这个概念被称为流畅模式。 好处: 以更易读的方式轻松初始化具有太多属性的类的对象。 遵循单一责任原则。 根据您的方便,以任何顺序初始化对象或更新属性。

在Swift 5中编写可扩展的API客户端

对于本文,我们决定为Marvel API编写一个客户端。 在深入研究代码之前,让我们解释一下为什么选择它: 它是开放的 。 去获得一个API密钥! 它很大 。 否则,为什么要建立一个可扩展的客户端? 是真的 。 迫使我们处理丑陋的现实细节。 这是一致的 。 好的,我们不需要太多丑陋的细节,我们也需要系统的实现。 它有一个很棒的API测试器 。 文档非常丰富,此在线工具使测试我们的代码变得非常容易。 太酷了 。 😎 在本文的其余部分,我们将使用Swift Playgrounds对该API进行试验。 如果您真的想对它有用,请推荐使用Karumi的MarvelApiClient。 功能性无状态核心周围的有状态外壳 定义组件接口时,一个很好的规则是使您的设计基于无状态类型,且其值语义不会产生任何副作用。 拥有该核心后,您可以创建另一个将这些类型映射到实际副作用的类型。 我们的API客户端组件将围绕三种类型构建: APIRequest :将创建JSON请求的值类型。 APIResponse :将从JSON响应中创建的值类型。 APIClient :将接收请求,将其发送到服务器,然后通过回调通知调用方。 最后一种似乎比其他类型更混乱! 好吧,这就是我们的有状态外壳,它将是处理这种混乱状态的外壳。 实际上,该组件将与大多数细节无关,而您几乎不需要更改它。 APIClient初始接口 基于先前的想法,我们可能会从以下内容开始: 让我们从更改APIRequest协议开始: Decodable协议为我们做了很多工作! 您是否注意到ID是非可选的? 因此,如果我们遇到格式不正确的ComicCharacter ,则会引发错误,并且我们将能够以我们认为合适的任何方式对其进行处理。 但是,那里还有另一种类型。 查看Image类型? 在任何Apple框架中都没有定义,这是我们定义的自定义类型。 让我们看一下它的代码: 由于某种原因,Marvel API决定发送分为路径和扩展名的图像URL。 我们不希望将此解析细节公开给我们的业务逻辑层,因此我们尝试从该输入中构建正确的URL。 由于我们的输入和输出不匹配,因此我们必须走很长的路,并完全实现Decodable 。 这意味着定义一个CodingKey枚举和一个init 。 […]

教程设计模式— OOP的功能(第2部分)

先决条件—本博客系列需要具有面向对象编程的中级专业知识。 您应该具有有关类,对象,构造函数,继承,值和引用类型的基本知识。 通过从头到尾阅读本系列文章,中级者将获得知识,专家将增强其知识。 单身人士班 在面向对象的编程中,单例类是在应用程序或项目的整个生命周期中只能有一个对象的类。 Singleton设计模式是iOS应用程序生命周期代码的一部分。 例如,在iOS项目中, UIApplication类是单例类的最佳示例,该类由iOS系统在应用启动时创建,并作为application(_:didFinishLaunchingWithOptions:)方法中的参数传递给AppDelegate。 有两种类型的Singleton设计模式。 纯单设计模式 半单设计模式 纯单设计模式: 在这种模式下,不允许使用纯单身类功能的程序员创建该类的实例。 程序员只能使用该类的预定义实例来调用单例类可用的方法和访问属性。 在应用程序启动期间,将使用创建该类的开发人员提到的预定义参数自动创建纯单类的对象。 纯单类必须标记为final,以避免继承混乱。 迅速地,您也可以使用结构来实现相同的概念。 程序员不能继承纯单类。 当您尝试快速继承任何类时,必须调用超类的构造函数。 在pure-singleton类中不可能调用超类的构造函数,因为pure-singleton类的所有构造函数始终被标记为private 。 让我们通过以下示例以一种简单的方式来理解这种设计模式。 问:什么时候应该使用第一个,而另一个应该使用“纯-单一设计模式”或“半-单一设计模式”呢? 这完全取决于您的班级职责。 如果您在项目中创建了singleton类,并且需要在某个时候更改某些属性,或者您想通过将来添加新方法来给类增加更多责任,并且还需要为其测试用例提供新的模拟数据添加方法后,应该使用半单例设计模式。 如果创建了类,则单元测试已经完成,并且想要通过框架或库进行发布,则可以采用纯单设计模式。 因为您创建了该类,并且其他开发人员将使用它,所以对单例类的单元测试是发布前的责任,而不是使用它的开发人员的责任。

ABI稳定性:Swift 5.0中的功能

Apple Swift 5将于2019年初发布。这是Swift的下一个主要版本。 目前,Swift的首要任务之一是在未来的Swift版本之间实现兼容性。 其中一个主要组件是ABI稳定性,它使应用程序和使用不同版本的Swift编译的库之间具有二进制兼容性。 Swift 5为应用程序提供了二进制兼容性:保证以后,使用一个版本的Swift编译器构建的应用程序将能够与使用另一版本的编译器进行通信。 ABI稳定性 应用程序二进制接口(ABI)是程序调用函数并使用其他编译程序中的数据结构的一种方式。 它是应用程序编程接口(API)的编译版本 。 对于使用外部库的应用程序,ABI非常重要。 如果程序是为使用特定库而构建的,而该库后来又进行了更新,则您不必重新编译该应用程序。 如果更新的库使用相同的ABI,则无需更改程序。 具有相同ABI的两个库版本称为“二进制兼容”,因为它们具有相同的低级接口。 ABI稳定性意味着将ABI锁定到某种程度,以便将来的编译器版本可以生成符合稳定ABI的二进制文件。 Swift的当前版本不稳定,因此每个二进制文件(App)都捆绑了自己的Swift动态库版本。 例如,如果App1使用的是Swift 3.0 ,则它将内部的Swift 3.0动态库 (包含3.0 ABI )捆绑在一起。 如果App2使用的是Swift 3.2 ,它将捆绑Swift 3.2和3.2 ABI 。 在这里,Swift并不存在于iOS操作系统中,而是存在于每个App中。 Swift 5.0中的ABI将使将来的编译器版本能够生成符合稳定ABI的二进制文件。 如果Swift成为ABI Stable,则Swift将被嵌入到iOS操作系统中,并且其ABI将与每个Swift版本兼容。 例如,如果App1使用Swift 5.0 ,但是App2使用Swift 5.3 ,则两者都将使用嵌入在操作系统中的Swift ABI。 在此示例中,使用Swift 5.0构建的应用程序将在安装了Swift 5标准库的系统以及假定的Swift 5.1或Swift 6的系统上运行。 为什么ABI稳定性很重要? 捆绑包大小将减小:您不再需要在Frameworks文件夹中包括Swift标准库。 更少的移植工作:较新的编译器可以编译用较早版本的Swift编写的代码。 这旨在减轻开发人员面临的迁移痛苦。 二进制框架和运行时兼容性:由于无需嵌入Swift,开发人员可以在Swift中创建预编译框架(当前,在编译应用程序时会编译框架)。

在Xcode中安装Swift 5工具链

苹果发布了Swift 5.0开发快照(工具链),供开发人员试用新语言。 在本文中,我将解释如何将Swift 5.0工具链与Xcode捆绑在一起。 根据Apple的定义, “ Xcode工具链( .xctoolchain )包括编译器,lldb以及其他相关工具的副本,这些副本可提供在特定版本的Swift中工作时提供凝聚力的开发经验。” 使用Xcode捆绑Swift 5工具链 从这里下载Swift 5.0快照。 (在撰写本文时,Swift 5.0可以作为开发快照使用。其他快照可以在此处找到:https://swift.org/download/#snapshots) 2.打开下载的软件包。 按照屏幕上的说明完成安装。 3.打开Xcode并导航到Xcode->首选项->组件。 在这里,您可以找到Mac上安装的所有工具链。 4.选择“ Swift 5.0快照” ,然后单击“关闭”。 恭喜你! 我们已经在Xcode中成功安装了Swift 5工具链。 谢谢阅读。 如果您有任何疑问,请随时询问! 在推特上关注我

是可选的,闭包可以抛出,是的。 –本–中

是可选的,闭包可以抛出,是的。 但是,没有语言功能可用于处理回调中的错误。 让我解释: 想象一下,我将闭包传递给了进行网络调用的函数。 如果该网络调用失败(例如,我收到HTTP 503 ),此功能将如何告诉我? 我看到三种方式: 回调有两个参数:成功值和错误值,两者都是可选的。 如果成功,则错误为nil ;如果错误,则成功为nil 。 这是不理想的,因为两者都可能为nil或都不为nil ,在这种情况下这是无意义的 该函数接受两个回调:一个在成功时传递值,一个在失败时传递错误值。 这样比较好,但是仍然可以同时调用两者,这是胡说八道。 另外,它体积大,并且没有利用Swift的闭包语言功能,例如在仅需要1个闭包的函数上省略括号。 回调采用一个参数,该参数是非可选的Result类型。 这是理想的,因为它永远不会同时具有成功或失败状态。 此外,您可以利用语言功能,例如省略括号和模式匹配。 同意,到今天为止,它体积很大。 但是,我看到了将来可以简化的一种方式,尤其是在标准库中提供了Result时。

Swift 5.0的新功能

了解Swift 5.0中可用的关键功能。Swift 5.0的主要目标是使语言达到ABI稳定性。 这将使稳定的Swift运行时能够由OS供应商部署,并且可以通过可执行文件和库进行链接。 Swift 5的新改进: 增强字符串文字定界符以支持原始文本(SE-0200) 将结果添加到标准库(SE-0235) 修复ExpressibleByStringInterpolation (SE-0228) 引入用户定义的动态“可调用”类型(SE-0216) 处理将来的枚举案件(SE-0192) 拼合由“ try?”产生的嵌套可选内容 (SE-0230) 将isMultiple添加到BinaryInteger (SE-0225) 特别说明: 在运行iOS 12.2,watchOS 5.2和tvOS 12.2的设备的构建变体中,Swift应用程序不再包含用于Swift标准库的动态链接库和Swift SDK覆盖。 因此,在部署用于使用TestFlight进行测试或为本地开发分发而精简应用程序存档时,Swift应用程序可以较小。 为了减少Swift元数据占用的空间,现在,在Swift中定义的便捷初始化程序正在调用Objective-C中定义的指定初始化程序时,才提前分配一个对象。 阅读这些改进说明,以获取更深入的知识,以增强您对即将发生的变化的了解。 增强字符串文字定界符以支持原始文本(SE-0200) 扩展定界符 我们的设计添加了可定制的字符串定界符。 您可以使用一个或多个# (磅,数字符号,U + 0023)字符填充字符串文字: “This is a Swift string literal” #”This is also a Swift string literal”# 自定义转义分隔符 使用自定义边界定界符的字符串在前导反斜杠后镜像其英镑符号,如以下示例所示,它们产生的结果与前面的字符串文字相同: #”This string has an \#(interpolated) item”# ####”This […]

Swift与Objective-C在2019年

Objective-C由Brad Cox和Tom Love于1984年创建,是C的扩展。它在C语言中添加了SmallTalk样式消息传递和对象定向。 Objective-C的比较优势: 与C ++和Objective C ++的互操作性 动态功能,例如方法混乱 更好地支持编写二进制框架。 Objective-C的缺点: 由于Objective-C建立在C之上,因此缺少命名空间 。 Objective-C应用程序中的所有类都应该是全局唯一的。 因此,为了避免冲突,有一个在类名前加前缀的约定。 这就是为什么我们在Foundation Framework中为类提供了‘NS’前缀,在UIKit中为类提供了‘UI’前缀。 显式指针。 在nil对象上发送消息而不会崩溃的能力以及缺乏严格的键入导致了难以跟踪和修复的错误。 该语言在语法上冗长而复杂,但是鉴于它是一种相当古老的语言,因此可以预期。 Swift是一种于2014年发布的年轻语言。它采用现代语法和功能,旨在确保安全性和高性能。 Swift于2015年12月开源。 Swift的比较优势: 由于使用静态类型以及使用可选对象和可选链接,因此Swift更安全。 支持名称空间,清晰的可变性语法,功能模式和简洁的语法。 使用Playgrounds进行交互式开发。 对于新程序员来说,Swift更容易学习。Apple的官方语言指南是一个很好的资源。 Swift表现出色,正在服务器端应用程序中找到自己的位置。 克里斯·贝利 ( Chris Bailey)在Realm Academy上的一次演讲中解释了在服务器端使用Swift的优势,他指出了Swift与服务器和云上其他框架相比的优势。 据他介绍,Swift性能卓越,内存占用量低,这使其成为服务器端开发的理想选择。 Swift现已稳定,其ABI已锁定。 Swift标准库代码包含约42.5%的Swift代码。 标准库中使用的不同语言的拆分如下图所示。 此Swift代码可能是开发人员可以用来改进自己的Swift编码的最佳Swift代码。 在本演讲中,它涵盖得很好。 Swift的比较缺点: 编译时间更长。 没有直接使用C ++库的方法。 模块格式的稳定性仍未实现,对于希望将其代码共享为二进制框架的开发人员而言,这是必需的。 结论 Swift现已正式成为ABI的稳定用户,可以被认为是一种成熟的语言。 Swift中的未来更新不会破坏从现在开始在Swift 5中编写的当前代码。 苹果提供了Objective-C和Swift之间的出色互操作性,并且不会在不久的将来放弃对Objective-C的支持。 对于团队来说,最好将其Objective-C代码的一部分迁移到Swift,因为它现在是ABI Stable。 如果您正在开发一个二进制框架,我建议您等待Swift实现模块格式稳定性。 另外,如果您要使用C ++和Objective-C ++代码库或框架,那么您将需要使用Objective-C和Swift。 […]