Tag: Swift编程

蒸气3入门

Vapor是iOS社区中领先的服务器端Swift框架,它使Swift开发人员可以将其现有的Swift技能带到云中。 在蒸气1和蒸气2成功之后,蒸气团队通过创建蒸气3框架使它变得更好。 在撰写本文时,Vapor 3尚未发布,但足够稳定,可以在应用程序中使用。 在这篇文章中,我将介绍如何开始使用Vapor 3。 安装蒸气3 Vapor文档提供了有关如何安装Vapor 3框架的详细说明。 我不再重复安装过程,而是直接链接到此处的过程。 你好蒸气 安装Vapor后,下一步是初始化Vapor项目。 可以在终端中通过运行以下命令来完成此操作。 蒸气新的你好蒸气 这将创建一个新的“ hello-vapor”项目文件夹,其中包含使用Vapor入门的所有默认文件。 跳到hello-vapor文件夹并运行以下命令。 蒸气Xcode 该命令将为您的Vapor项目创建一个Xcode项目。 该过程完成后,您将为hello-vapor项目获得一个xcodeproj文件。 现在,您只需双击Xcode项目文件即可在Xcode中打开Vapor项目。 在构建应用程序之前,请确保将目标设置为“运行”,并选择“ 我的Mac”作为设备,如以下屏幕截图所示: 构建完成后,运行您的应用程序。 这将在端口8080上启动服务器。在浏览器中访问http:// localhost:8080 / hello,查看正在渲染的hello路由。 恭喜你! 您现在正在使用Vapor框架在服务器上运行Swift。 路由 默认情况下,Vapor在routes.swift文件中添加一些锅炉级别的代码,该代码为您的Vapor项目创建默认路由。 您可以在routes.swift文件中创建自己的路线。 让我们为电影添加一条路线,如下所示: 您甚至可以将不同的路线嵌套在一起,如下所示: 您可以使用“路由参数”的功能,而不是为每种可能的流派创建路由,如下所示: 借助蒸气参数,我们不必为每种类型创建单独的路线。 Vapor还提供了一种简单的方法来访问查询字符串,分组路由等等。我在我的课程“ 使用Vapor 3掌握服务器端Swift ”中对此进行了详细讨论。 您可以使用下面的优惠券代码获得该课程的折扣。 希望您喜欢这篇文章! 编码愉快! 使用Vapor 3掌握服务器端Swift 乌迪米 您是否有兴趣学习如何使用Swift编写完整的后端API? 服务器上的Swift是…的未来。 www.udemy.com

iOS响应链:UIResponder,UIEvent,UIControl和使用

在上一个操作由UIViewController处理的示例中,UIKit首先将操作发送给了UIView第一响应者-但由于它没有实现myCustomMethod因此视图将操作转发给了下一个响应者–恰好具有该方法的UIViewController在执行中。 尽管在大多数情况下,“响应者链”只是子视图的顺序,但您可以对其进行自定义以更改一般流程顺序。 除了能够覆盖next属性以返回其他内容之外,您还可以通过调用becomeFirstResponder()强制UIResponder成为第一响应者,并通过调用becomeFirstResponder()使UIResponder返回其位置。 这通常与UITextField结合使用以显示键盘inputView可以定义一个可选的inputView属性,该属性仅在响应者是第一响应者(在这种情况下为键盘)时显示。 响应者链自定义用途 尽管Responder Chain由UIKit完全处理,但您可以根据自己的喜好使用它来解决通信/代理问题。 在某种程度上,您可以将UIResponder操作视为一次性通知。 考虑一个几乎每个视图都支持“闪烁”动作的应用程序,目的是帮助用户在教程中导航。 触发此操作后,如何确保仅当前“活动”视图闪烁? 可能的解决方案包括使每个视图都继承一个委托或使用除”currentActiveView”之外每个人都需要忽略的简单通知,但是响应程序操作使您可以使用零委托和最少的编码轻松实现此目的: final class BlinkableView: UIView { override var canBecomeFirstResponder: Bool { return true } func select() { becomeFirstResponder() } @objc func performBlinkAction() { //Blinking animation } } UIApplication.shared.sendAction(#selector(BlinkableView.performBlinkAction), to: nil, from: nil, for: nil) //Will precisely blink the last BlinkableView that had select() called. 它的工作原理与常规通知非常相似,不同之处在于,尽管通知将触发注册它们的每个人,但是这会有效地循环响应程序链,并在找到第一个BlinkableView时立即停止。 […]

拆开Massive View Controller

在每个项目的某个时刻,设计师都会坐在您的办公桌旁,询问您将屏幕移动到流程中其他位置的难度。 也许您的同事无所适从,问为什么您的Sweet View Controller会知道每个其他View Controller。 或您的经理突然来询问您为什么没有任何测试。 所有合理的问题。 您的脸(如图所示:😬)比您以前说的更多。 这将比他们想象的要多得多 。 一个相当典型的iOS应用程序体系结构涉及创建视图控制器,这些视图控制器决定下一个要呈现的视图控制器以及应如何呈现它们。 他们还负责启动网络请求,解释响应,更新模型并调解子视图或子视图控制器之间的通信。 mega-view-controller做很多事情: 获取有关其呈现方式的上下文。 处理用户交互,启动计算,更新结果。 确定接下来要显示的屏幕。 配置下一个视图控制器。 在某个地方展示下一个视图控制器。 它会进入导航控制器吗? 哪一个? 它是模态的吗? 这样的细节不太可能通过通常狭窄的API表面公开-通常,没有超出UIViewController呈现的东西。 结果,这段代码充满了隐式依赖。 这很难测试,甚至更难重新排列。 这个想法很简单:隔离您的视图控制器- 他们不需要知道哪个屏幕在前或下一屏幕 。 在这种模式下, 视图控制器的工作是控制视图,布局和动画。 流量控制器的工作是代表一个特定的状态机并遍历该状态机。 当需要进行状态转换时(例如,网络请求,流程中的前进或后退等),视图控制器将通过委派或阻止回调将其推迟回流程控制器。 这样,可以在不实例化所有支持基础结构的情况下测试视图控制器。 啊哈! 现在可以测试视图控制器了! 它不再依赖于之前发生的事情,也不知道接下来会发生什么-它与表示样式无关。 现在可以轻松地在流内或流之间移动视图控制器。 如果那是您的事,那么流量控制器本身也很容易测试。 甚至公开一些基本细节,例如当前显示的屏幕以及调用代表动作以模拟在流程中的遍历,都会带您到达那里。 毕竟这只是一台状态机。 在这种模式下,视图控制器应该做的尽可能少。 逻辑应仅限于将数据提供者连接到子视图,管理动画以及响应用户事件。 还有更多应该委托出去。 步骤1使View Controller委派所有操作 接下来是Flow对象。 这充当所有托管视图控制器的委托,并负责呈现和配置它们。 步骤2设计由您的View Controller组成的流程 这就是全部。 这种设计模式使隐式依赖关系的网络反转,有利于委派和显式依赖关系注入。 准备测试时,构造视图控制器,遵守委托协议并练习公共API。 当然,大多数项目要复杂得多-这就是这种模式的真正体现。 现在不仅可以在流之间重复使用视图控制器,还可以轻松地从其他流中构建聚合流。 很疯狂的东西,是吗? 我汇集了一个非常简单的基于这些概念的Master […]

使用Nginx和Supervisor部署基本的Vapor应用程序

本文将指导您完成将简单的蒸气应用程序部署到VPS的过程。 我使用的是数字海洋,但是只要您的实例运行Ubuntu 16.04并且可以通过ssh访问该主机,托管服务提供商就没有关系。 先决条件: 具有ssh访问权限的Ubuntu 16.04实例。 我强烈建议您在继续之前阅读本文。 熟悉终端文本编辑器,例如nano,vi或emacs。 熟悉基本的bash命令。 安装和设置Nginx 通过运行以下命令来安装Nginx: sudo apt-get更新 须藤apt-get install nginx 将规则添加到防火墙以允许端口80上的TCP连接。(仅在启用防火墙的情况下才需要执行) sudo ufw允许’Nginx HTTP’ sudo ufw状态 检查Nginx是否正在运行systemctl status nginx 最后,您可以通过从浏览器向服务器的域或ip发送GET请求来检查nginx是否设置正确。 如果您在下面看到欢迎页面,则说明您已经成功设置了Nginx。 如果您没有看到此页面,请查看此详细教程。 安装和设置蒸气 使用以下命令安装Swift和Vapor。 评估“ $(curl -sL https://apt.vapor.sh)” 须藤apt-get install swift vapor 评估“ $(curl -sL check.vapor.sh)” 如果输出“与蒸气2兼容”,则可以继续进行。 创建一个基本的蒸气项目。 蒸气新你好 注意:如果您有现有的蒸气项目,则可以从github克隆该存储库。 但是请记住,在本教程的其余部分中,请用您的项目名称替换“ hello”。 配置Nginx以将请求转发到Vapor App 更改/etc/nignx/sites-available的default配置文件,使其看起来像以下片段。 服务器{ 监听80 default_server; 听[::]:80 […]

在Swift 4中解析JSON:基础知识

Swift标准库定义了一种用于数据编码和解码的标准化方法。 您通过在自定义类型上实现可Encodable和可Decodable协议来采用这种方法。 采用这些协议可以使Encoder和Decoder协议的实现获取您的数据,并在外部表示形式(例如JSON或属性列表)中对数据进行编码或解码。 为了同时支持编码和解码,请声明对Codable符合Codable ,后者将Encodable和Decodable协议结合在一起。 此过程称为使您的类型可编码 。 编码和解码自定义类型 如何在Swift 4中解析JSON? 让我们直接说清楚。 这是一个User的JSON示例: 为了将JSON转换为User实例,我们将struct标记为Codable 。 它应该看起来像这样: 然后,我们创建一个解码器: 还有BOOM! 这就对了!! 重要说明:我们使用了try! 并强行解包,但这只是出于示例的目的,您不应以这种方式使用它。 您应该使用catch来正确处理错误。 做一个好的开发者。 自定义键名 如果您的API采用蛇形惯例,则只需对CodingKeys枚举进行自定义实现。 该枚举定义了如何将属性连接到JSON字段名称。 因此,我们的User模型应如下所示: 来源和阅读链接 编码和解码自定义类型 将JSON与自定义类型一起使用

成为开发人员

没有计算机科学背景 品尝编程 我在高中期间学习了解决算法问题。 这是我第一次编程经验。 我对使用C ++感到非常兴奋。 它产生了有意义的结果。 我在高中部门的首尔信息奥林匹克竞赛中获得了大奖。 主修业务管理并作为数据分析师开始工作 我搬到美国学习业务管理,是因为我想学习更多有关管理组织以解决实际问题的知识。 这是我一生中非常愉快的经历。 有非常有组织的步骤来管理项目和人力资源。 大学毕业后,我开始担任商品数据分析师3年。 我已经使用Excel VBA和SQL进行报告。 这是处理大量市场研究和数据分析的一切。 我感觉就像是一家生产报告的工厂。 这就是为什么我开始iOS开发的原因 但是,除了通过创建报告来支持管理团队之外,我希望看到更现实的结果。 当时,我的妻子正努力使用iPhone Calendar App。 所以我想成为一个超级可爱的家伙,解决她的问题。 我开始研究iOS开发,终于在App Store上成功发布了我的第一个应用程序。 这是我的每日备忘录。 我的每日备忘录:在App Store上的内容 阅读评论,比较客户评分,查看屏幕截图,并详细了解“我的每日备忘录”。 下载“我的每日备忘录”并… itunes.apple.com 我的特长 英语是我的第二语言。 我在学习英语时学到的是,语言只是表达我的知识或思想的一种技能或方式,而不是目的。 (当然,有些人将语言用作翻译或翻译之类的目的。)编程语言是相同的。 它是我可以通过使用它表达我的想法的一种语言。 编程主要是关于如何为人们提供效率和便利,而不是技巧或技术本身。 如果说编程语言不是目的,那么我在大学学习业务管理的4年经验就是一种优势,而不是劣势。 您可以考虑一所法学院。 法学院的学生来自各个专业。 那里的主要目的是作为一名研究生从法学院毕业。 学过各种专业的人有可能通过进一步研究法律来改善社会对许多领域不了解行业的状况,从而丰富法律的解释,因此结果与实际不同。 我认为非计算机科学专业的人们将能够通过将他们的知识与编程相结合来找到市场想要的东西。 通过学习四年的业务,我了解了如何改变世界的见解,并且可以通过查看服务运营商和消费者的职位来进行编程。

Swift 4.1:标语牌中的新增强功能

Swift 4.1现在已经正式发布,您可以浏览下面的图片所实现的增强功能,这些信息来源于—官方Swift博客 增强功能1:SE-0143条件符合性 条件一致性表示这样的概念,即泛型类型仅在其类型参数满足某些要求时才符合特定协议。 例如,仅当Array集合的元素本身是Equatable时,才可以实现Equatable协议 增强功能2:SE-0157支持对关联类型的递归约束 该提议解除了对协议中关联类型的限制。 它们的约束将被允许引用任何协议,包括依赖于封闭协议的协议(递归约束)。 增强功能3:SE-0185综合可量化和可哈希化的一致性 开发人员必须编写大量样板代码来支持复杂类型的相等性和哈希性。 该提议为编译器自动合成符合Equatable和Hashable以减少样板,在已知可能生成正确实现的部分场景中提供了一种方法。 增强功能4:SE-0187引入Sequence.compactMap(_ 🙂 现在不建议使用Sequence.flatMap方法,并且可以使用不同的名称(可能更具描述性)使用相同的功能。 增强功能5:SE-0188使标准库索引类型可哈希化 关键字路径表达式现在可以包括下标,以引用集合和其他可下标类型中的各个位置,但仅当下标参数为Hashable 。 为了提供最大的实用性,标准库索引类型都应添加可Hashable一致性。 增强功能6:SE-0191从集合中消除IndexDistance 从Collection消除关联的类型IndexDistance ,并将所有用法修改为具体类型Int 。 对于其他更新,您可以在我的Twitter句柄@NavRudraSambyal的Twitter上关注我。 要跟随我对RxSwift的工作,您可以找到我的书《 Swift 4中的反应式编程》的链接。 感谢您的阅读,如果发现有用,请分享share

依赖注入iOS让我们变得简单

依赖注入:拆分此英语术语以获取更简便的方法 依赖-您所依赖的东西 注入-用于注入东西 所以依赖注入意味着注入需要的依赖而不是创建它 或者我们也可以说将依赖注入到对象中,而不是负责创建对象依赖的任务 。 或某些怪胎将其定义为为对象提供实例变量,而不是在对象中创建实例变量。 😛 让我们以一个例子来获得更清晰的图像: 在这里的例子 关键是MyViewController负责创建Service实例。这意味着MyViewController类不仅了解Service类的行为。 它还知道其实例化。 现在在下一个DI示例中,我们在创建对象时将Service实例注入MyViewController实例。 尽管最终结果可能看起来与上面的示例相同,但事实并非如此。 通过从外部注入Service , MyViewController不知道如何实例化Service 。 简单来说,这就是依赖注入。 通常,依赖注入被认为是3种类型: 通过初始化程序进行依赖注入: 也称为基于构造函数,最优选的 是在初始化期间在构造函数 (构造函数) 中传递依赖项。在初始化程序中,通过将依赖项的属性声明为常量(使用let)来使基于DI的依赖项不可变。让它在整个客户的一生中都发生变化。 因为要求我们在初始化期间将服务作为参数传递,所以指定的初始化程序清楚地显示了DataManager类的依赖项。 通过属性进行依赖注入: 在类中声明的Internal或Public属性也可以用于将依赖项注入到类对象中。 这似乎很方便,但是它增加了一个漏洞,因为可以修改或替换依赖关系。 换句话说,依赖关系不是一成不变的。 使用serviceManager属性将服务依赖项传递给类MyViewController的viewController实例。 通过方法进行依赖注入: 依赖项也可以在需要时注入。 通过声明一个将依赖项作为参数接受的方法,这很容易做到。 在下面的示例中,该服务不是DataManager类的属性。 而是将服务作为方法的参数注入。 即使DataManager类失去了对依赖项,服务的控制,这种类型的依赖项注入也带来了灵活性。 为什么要使用依赖注射:- 测试:依赖注入使开发人员可以用模拟对象替换对象的依赖关系,从而使单元测试更易于设置和隔离行为。 透明度:通过注入对象的依赖关系,类或结构的职责和要求变得更加清晰和透明。 松耦合:协议和依赖注入的使用可以减少项目中的耦合。 协议在Swift中非常有用且用途广泛。 这是协议真正发挥作用的一种情况。 关注分离 :依赖注入严格地分离了对类的关注。如果类不负责实例化依赖实例,则它不需要知道如何做到这一点。 即使它与依赖关系的行为有关,但也不应与其实例化有关。 我们得出结论: 依赖注入是您在项目中可能已经在使用的东西,它的好处确实使结构易于理解,可重用,可测试和可维护,因此不要再键入几行代码,而是开始使用聪明的想法。 快乐编码 保持冷静和智能代码

迅速。 功能阵列

Swift为iOS开发带来了很多机会。 其中有一些非常有用的功能挂钩。 有些人立即将函数式编程与复杂的数学和M字相关联,但事实并非如此。 函数是函数编程中的真正力量。 在本文中,我们将介绍如何使用其中的一些功能,以使您的日常Array例程更加舒适,避免仅通过使用函数避免代码重复和不必要的键入。 回顾我的一位同事,我们讨论了下一个功能: 现在该回到我们的摘要了。 在第2行中,我们为将在第3行中使用的函数形成一个元组。因此,在第3行中,只要意识到offerCellReactorFactory参数是元组而不是,就可以使代码更甜美 self.offerCellReactorFactory($ 0.0,$ 0.1) 我们可以写 self.offerCellReactorFactory($ 0,$ 1) 那就对了! 元组的元素是函数的独立参数,因此闭包中不需要丑陋的点符号。 这是真正的魔术发生的地方。 类型推断是语言自动检测表达式类型的能力。 在声明变量时,我们每天都在使用它,但是它具有更强大,更漂亮的应用程序。 还记得我们的UIViewController.viewDidAppear声明吗? 该viewDidAppear变量存储一个函数,Swift能够理解该函数是什么。 很酷,但还有更多。 首先, Array的map函数采用一个非转义的闭包作为参数,因此不需要[unown self]。 现在,注意指针,第三行变成 .map(offerCellReactorFactory) 妈呀 在这里,类型推断为我们完成了所有工作。 Swift能够找出该特定表达式中的所有类型,因为我们的元组为该函数形成正确的参数,并且map本身采用了将元组转换为某种东西的函数。 我们只是节省了自己的打字时间。 此功能具有许多优点,从涉及重命名的较少键入和易于重构开始,到使用类型正确的表达式结束。 希望,这也阐明了为什么类型转换和强制转换很差的问题 。 谈论重命名…让我们将offerCellReactorFactory重命名为makeOfferCellReactor🙂 看看我们如何在第2行和第3行中应用两个映射函数。这种应用称为管道 。 实际上,可以将管道调用应用于某些值的一系列函数。 坦白说,我们的问题是功能的流水线应用。 但是此应用程序被变量声明破坏了。 这不好吗? 不,不是真的,但是Array不仅是像Int这样的普通类型。 数组是容器类型。 它通常封装许多元素,并且该数目在计算过程中可能会发生变化。 这被称为非确定性行为。 为了保留不确定性, 数组类型具有特定的属性。 他们为我们提供了我们刚刚描述的出色的管道应用程序功能。 您是否注意到地图返回了另一个Array ? 这样可以进一步应用诸如map , compactMap , […]

函数与计算属性-使用什么?

如果任何调用被认为是昂贵的,会在多次调用时引发错误或返回不同的结果-首选函数。 如果调用便宜,则不会引发错误,不会返回相同的结果,也不会缓存第一次调用的结果-计算属性可能会满足您的需求。 – – – – – – – – – – – – – – 要么 – – – – – – – – – – – – – – 如果您的代码执行了某个动作并返回了例如该动作的结果的描述,那么您应该首选函数。 如果您的代码计算出一个属性,但是从用户的角度来看,这可能是一个存储的属性,或者可能是一个存储的属性,需要先更新某些缓存的值,那么您应该更喜欢计算的属性。 例如 ,我们有CookieFactory类来烘烤一些cookie。 我们需要它来查看成分并决定要制作哪种曲奇。 它需要检查有多少成分可用以确定批次大小。 然后,它将需要分割并创建cookie。 听起来很复杂,所以要使用函数是这里的方法。 遵循统一访问原则 模块提供的所有服务都应通过统一的符号表示,无论是通过存储还是通过计算实现,都不应背叛。 —伯特兰·迈耶(Bertrand Meyer) 属性表示实例的固有质量,而方法则执行操作。 方法有参数; 属性没有。 对于有副作用的任何调用,最好使用方法。 如果某个方法执行某些操作(例如,它加载,解析,切换或打印)或具有动词名称,则它不应是属性。 首选属性以获取和/或设置简单值。 属性应表示类型实例的语义固有质量。 错误的计算属性示例: –随机值 – 今天的日期 –来自另一个对象或单例的值 […]