Tag: Swift编程

NotificationCenter使用评论家Swift 4

NotificationCenter是您可以根据应用程序范围内的操作触发事件的地方。 用法经过多年发展,变得更加安全。 即使是这种情况,使用选择器和填充物仍然保留目标c的痕迹。 当我决定开始实施某些功能时,我通常不会考虑通过框架来实施。 首先,我认为我要如何解决该问题并略微调整框架的使用方式来满足我自己的需求。 一般的做法: 提供Notification.Name是为了在触发和接收动作时不会将类型与字符串错字混淆。 为了更好地进行管理,可以在Notification Name类上进行扩展,并可以在其中静态定义通知名称。 扩展Notification.Name { 静态让MagicHappened = Notification.Name(“ MagicHappened”) } 您发布通知: NotificationCenter.default.post(名称:Notification.Name.MagicHappened,对象:self,userInfo:[“ eventId”:“ 4392349jfjasdfj234”]) 然后添加观察者 : NotificationCenter.default.addObserver(自身,选择器:#selector(magicHappened(_ :)),名称:Notification.Name.MagicHappened,对象:nil) 然后,您还可以添加选择器方法 : @objc private func magicHappened(_通知:通知){ 打印(“魔术偶然在乎。”) } 当然之后,您还需要删除观察者。 现在黄油来了。 主要用法应以安全,静态的方式触发操作,而不会带来很多麻烦。 接收广播应该以一种更自然的方式进行,只需提及您想听的内容以及发生时要做的事情,并传递数据即可。 这就是为什么我在通知中心使用情况上写了一个包装器的原因。 我决定使用枚举’ ZMLocalBroadcastType ‘作为起点。 这种用法对于任何人来说都很容易扩展。 如果您有新的使用通知类型,则只需再添加一个case语句。 通知名称太宽泛,这就是为什么我选择localbroadcast作为名称的原因。 之后,我为通知观察创建了一个新的代理侦听器类,该类从viewcontroller的闭包中委派了工作。 首先从触发通知开始。 广播: 数据是可选的,可以广播。 观察: 您需要坚持观察者,以便在时间到时停止观察。 这是绝对必要的。 否则,观察对象将丢失在大天空的深处,并且观察将无法进行。 时间到了deinit或任何其他块。 您只需停止观察即可。 这种方法使我更容易扩展通知类型。 清除我手指不必要的打字肌肉。 […]

模块化iOS应用程序时的常见问题

您可能想模块化您的iOS应用程序,但是在某些情况下,事情可能会变得复杂起来 。 在这篇文章中,我将介绍在对现有的大型iOS应用进行模块化时遇到的最常见的问题,以及为解决或避免这些问题而采取的措施。 本文将主要介绍封装 , 循环依赖项, 图像 (捆绑), pbxproj以及将现有应用程序部分提取到框架中。 “好吧,我要在哪里创建这个?” 当您的应用程序中有框架时,您可能会想到的第一个问题是“您将在哪里为下一个功能编写代码?”。 正如我在上一篇有关框架的文章中所说的那样,您应该对框架进行分类。 您可以拥有一个Core框架,一些特定于功能的框架以及其他一些技术框架。 如果您的新功能或要开发的功能没有输入任何现有框架,则可能需要创建一个新框架。 请谨慎选择,因为如果您想更改此新功能或与该新功能交互 ,它肯定会在以后产生影响 。 “公共的,内部的,私人的?” 您将在您的鼻子前看到这个弹出窗口! 这是因为您需要声明您的类/结构或您在模块中定义的任何内容,并希望以public的形式从外部 访问它。 在开发不带框架的应用程序时,您通常不会过多地关注可见性或访问控制,因为默认情况下,Swift中的所有内容都是internal 。 内部意味着您可以在当前模块中访问它。 在开发模块时,需要从外部将要使用的类显式定义为public 。 这也迫使您拥有更好的代码封装并更好地定义应用程序结构 。 您只应将希望从框架外部 访问的类型标记为公共 。 其他所有内容至少应该是内部的 ,或者甚至是私有的(如果用于本地)。 因此,如果您想消除Xcode错误,只需将您的类标记为public即可 。 “让我们在需要的任何地方导入此框架!” 对,但是 ! 使用框架时,您必须要小心,否则您将面临循环依赖和许多麻烦 。 在您的框架内,您不能导入已经 直接或间接 导入第一个框架的第二个框架。 另外,您可能会遇到这样的情况,即功能框架(假设为Account )想了解有关另一个框架( Booking )的一些知识,以创建链接。 例如,您想根据您在“ 帐户”部分中的 偏好启动预订搜索 。 您想从帐户框架中启动搜索,因此您可能要导入Booking框架,但这是错误的,因为这将质疑这两个框架的分离。 那么,如何处理不应相互导入的两个框架之间的链接 ? 这种情况是一个有趣的问题,一种解决方案是使用称为POP […]

使用Alamofire在Swift4中发出简单的API请求

API是应用程序编程接口(Application Programming Interface)的缩写,它是一种软件中介,基本上允许两个应用程序相互通信。 因此,基本上任何应用程序都分为两个不同的部分。 一个是后端 ,其中所有预处理均基于API请求期间传递的参数进行,另一个是前端 ,在此前端 ,所有处理后的数据均显示给用户。 这种架构通常称为微服务架构。 使用这种架构,我们可以为多个前端服务(例如Web,Android和特别是iOS)提供一个后端。 坦率地说,对于Swift4而言,Alamofire是目前最好的开源库。 Alamofire是迅速最完善的网络库,可将数十行代码转换为仅几行。 可以在其README.md中找到安装指南。 发出GET请求 GET是一种HTTP方法,用于使用给定URI从给定服务器检索信息。 使用GET的请求仅检索数据,而对数据没有其他影响。 使用Alamofire,这简直是小菜一碟。 Alamofire.request(“ https://YourURI.com/get”).responseJSON {在 print(response.request)//原始网址请求 print(response.response)// http网址响应 print(response.result)//响应序列化结果 如果让json = response.result.value { print(“ JSON:\(json)”)//序列化的json响应 } } 发出POST请求 POST是一种HTTP方法,用于使用HTML表单将数据发送到服务器,例如,注册号,文件上传等。 //必要时在请求中发送的标题 let标头:HTTPHeaders = [ “授权”:“承载者” + access_token! //如果使用JWT ] //需要在后端发布的参数 让参数= [ “ parameter_name_1”:value_1, “参数名称_2”:value_2 ]作为[String:任何] Alamofire.request(“ http://YourURI.com/post/”,方法:.post,参数:params,标头:标头).responseString { print(response.request)//原始网址请求 print(response.response)// […]

SwiftSyntax概述

SwiftSyntax是一个在libSyntax之上提供Swift抽象的库,它公开了一组API,这些API使得诸如访问,重写和从swift源的语法结构中检索信息等操作成为可能。 因此,在今天的文章中,我们将试玩一下SwiftSyntax库,以更多地了解它的工作原理以及如何使用它来创建可以帮助解决一些问题的东西。 所以,让我们潜入…… 编译器 在深入探讨SwiftSyntax之前,我们需要至少从高层次上了解有关编译器流程的一些知识。 swift编译器采用Swift源代码,将其处理为手动编码的Lexer,将其标记化并将其转换为抽象语法树(AST),然后是语义分析(Sema),其中编译器采用由XML生成的AST。解析器,并进行类型检查的AST并检查其上的语义问题。 然后,Swift中级语言生成(SILGen)阶段将通过语义分析生成的AST转换为他们所谓的原始SIL,在对原始SIL进行了一些优化(如通用专业化,ARC优化等)之后……它生成了他们所谓的规范SIL。然后将其交给IRGen生成中间表示(IR),该中间表示将传递给LLVM以使其继续工作并生成目标文件(.o),该文件随后将由链接器粘合在一起并生成用于任何给定的平台。 这是对编译器管道的简要概述。 在这里,我们将更多地关注AST,因为在SwiftSyntax上,我们基本上以语法节点的形式来表示它。 因此,要了解本文中的术语,我们只需要知道AST就是树形结构形式的源代码语法的表示。 让我们看一个简单的例子: 上图是树形式的代码示例的表示形式,我们可以注意到,它表示经过类型检查的AST,但仍然没有语义信息,只有语法信息。 请注意,在顶部,我们有一个struct_decl ,内部是子结构,我们有var_decl和func_decl ,它们可以包含自己的子结构,依此类推……等等,还有语法标记,如brace_stmt 。 SwiftSyntax以Syntax节点的形式提供了这种表示形式,我们可以使用Visitors浏览它,也可以使用Rewriters对该结构进行更改(我们将在本文的后面讨论它们)。 每种结构都有类型表示形式,例如struct_decl具有SwiftSyntax结构StructDeclSyntax类型,将其表示为语法节点。 现在我们知道了AST的基本概念,下面我们来谈谈SwiftSyntax \ o / lib语法 我们可以说SwiftSyntax是一个swift程序包,它在libSyntax之上提供了一组swift绑定,libSyntax是在其中处理swift源的实现,结构和逻辑。 在libSyntax上阅读: 该库实现了用于处理Swift语法的数据结构和算法,力求安全,正确和直观地使用。 该库强调不可变的,线程安全的数据结构,源的全保真表示以及结构化编辑的便利。 换句话说,它将为我们提供一个必要的基本块,以使我们能够通过良好而便捷的API对快速的源语法结构进行安全可靠的分析和编辑。 SwiftSyntax API 我们不会在这里深入探讨如何在libSyntax中内部表示源数据,因此,我们将更多地关注SwiftSyntax提供的高级swift API(用作客户端)。 libSyntax自述文件的“内部”部分中有详细的文档。 而且,Harlan Haskins的演讲中有关于尝试的部分! Swift NYC 2017 [3]关于libSyntax如何在内部表示语法树。 但简短的摘要是,libSyntax将AST的表示划分为: 语法 :或语法节点是为公共API提供的表示形式。 RawSyntax :是所有语法的内部原始不可变后备存储。 像令牌种类一样存储数据,并且还表示子树结构。 RawTokenSyntax : RawSyntax的特殊情况,表示语法中的所有RawSyntax 。 Trivia :表示对源没有任何语义含义的所有语法部分,例如空格,换行符和注释。 SyntaxData :它用一些附加信息包装RawSyntax节点:指向父级的指针,该节点在其父级中出现的位置以及缓存的子级。 高级API 在这里,我们将看到一些可以在SwiftSyntax上使用的高级API,以及一些有关如何使用它的示例代码。 […]

Swift 5.0引入了新的结果类型…..?

Swift 5.0引入了新的 结果类型 作为通用枚举实现的,有两种情况 :。 成功和。 失败 , 在每种情况下都包括一个关联值。 值与大小写关联。 成功可以是任何值(取决于您)。 值与case关联。failure必须是采用Error协议的类型 。 为什么? 结果类型 — 它 提供 了一种更清晰,类型安全的错误处理方式。 例如-让我们创建一个简单的函数toInteger ,它将字符串转换为整数并返回Result 。 请注意, case .success的关联值是Int类型,而case .failure的关联值是AnErrorType类型,该值采用Error协议。 现在我们可以像这样使用它: 因此,通过使用 Result类型 ,很明显,我们可以获取 Int 类型的 结果值 或 AnErrorType 类型的强类型错误值 。 不可能 全有 或 全无 结果类型 提供 了更清晰,类型安全的错误处理方式。 另外, Result类型支持特定的初始化器,该初始化器接受引发的闭包- 例如 – 目前为止就这样了。 感谢您的阅读! 这是我有史以来第一篇中级职位。 我希望本快速阅读可以使您快速了解利用枚举功能在Swift 5.0中引入的新Result类型。 我真的很感激我的任何建设性批评,请随时在这里发表您的看法。 请通过与世界各地的Swift爱好者分享并分享这篇帖子,来帮助我传播信息。 […]