Tag: Swift编程

了解回调

这些是什么? 它们如何运作? 它们是用来干什么的? 整篇文章将使您对 iOS开发中最常见的编程模式之一有深入的了解 。 在此项目中,回调用于在ChoosePokemonTableViewController和PokemonDisplayViewController之间发送和接收信息。 要设置项目,请在此处下载文件。 首先,让我们打开ChoosePokemontTableViewController.swift文件。 在文件中,您将看到/// TODO:像这样的评论⬇️ 我们将逐步完成在ViewController和TableViewContoller文件之间创建成功的回调的步骤。 类型别名 类型别名允许您将现有时间重命名为您选择的时间。 目的是使我们的代码更具可读性和易于理解。 查找// TODO:1.在您的ChoosePokemonTableViewController.swift文件中,然后键入⬇️ typealias PokemonCallback =(口袋妖怪)->虚空 您的文件应该看起来像这样⬇️ 大! 我们刚刚将Type Pokemon重命名为PokemonCallback。 使用Struct在Pokemon.swift文件中创建了Pokemon类型。 接下来,我们将创建一个名为pokemonCallback的变量并将其设置为Type PokemonCallback? <-箭头表示它是可选的。 *更多关于可选内容的信息。 var pokemonCallback:PokemonCallback? 这是重要的部分,因为我们现在将调用Callback方法并传递selectedPokemon 。 这将充当将ChoosePokemonTableViewController连接到PokemonDisplayViewController的桥梁。 在tableView函数中使用参数中的didSelectRowAt键入以下代码。 当我们点击口袋妖怪的列表时, didSelectRowAt tableView将运行。 pokemonCallback?(selectedPokemon) 当选择表格中的一个单元格时,让我们切换到PokemonDisplayViewController来接收消息! 我们将在下面的代码中输入⬇️ selectPokemonController.pokemonCallback = self.checkGuessedPokemonAndShowPokemon 这将调用我们从choicePokemonController创建的pokemonCallback ,并将其设置为此文件中的功能checkGuessedPokemonAndShowPokemon 。 恭喜! 现在,每次您从ChoosePokemonTableViewController中选择一个单元格时,回调就会启动,步骤4中的最后一行代码将开始检查猜想的Pokemon名称是否正确,然后显示Pokemon是否被正确猜中。 很容易吧? 实质上,这就是回调的工作方式。 4个简单步骤! 想象一下从一个ViewController到另一个ViewController建一个金州大桥。

Swift 4:可丢弃的结果

斯威夫特2.2 在Swift 2.2中,如果您调用一个函数并且不使用其返回的结果,则不会收到任何警告。 要生成警告,方法定义本身需要使用以下注释: @warn_unused_result 即 Swift 3和Swift 4 此行为已在Swift 3和Swift 4中翻转,现在所有未使用的返回结果都会生成警告。 如果您正在设计API,则某些函数的返回值应更多,因此应将其视为副作用,您可以使用以下注释函数: @discardableResult 即 可以在此处阅读有关此更改的快速建议

图书馆和数据库

事实证明,在各个幼儿园之间骑自行车游览并不是完成很多工作的好方法。 谁会打它呢? 昨天很有趣,但我仍然设法使清单上的至少一件事完整。 对我来说,这是一个胜利。 在昨天的帖子中,我提到了几天前所做的研究,试图为我的应用程序选择后端服务。 简而言之,我决定使用Google的Firebase产品,实际上是他们仍处于测试阶段的Cloudstore。 使用仍处于测试阶段的内容的想法可能会吓到某些人,或者使您怀疑我的判断。 但是,正如我现在已经明确指出的那样,我只是在此阶段瞄准最低限度可行的产品,而将整个产品基于beta产品的风险很小(没有?)。 我会让您知道,我对这一选择进行了很多思考,这可能比我的项目所需要的要多,而这在此时仍只是我的想象力。 我的研究确实做了一件很棒的事情,我发现它对未来充满了希望:编写自己的后端服务的想法听起来真的很有趣。 我读得越多,就越会深深地想到Firebase,Realm等解决方案非常适合以很少的时间和资源(我的实际情况)启动并运行某些解决方案。 对于大多数自定义操作,并且显然是独立的,编写自己的服务器端代码和API是理想的选择。 我只想为学习体验而尝试一下,再加上一些其他语言的介绍。 是的,我知道Swift也可以是服务器端语言,但是我想深入了解Python和Ruby,并了解它们可以带给我的力量。 我迫不及待地想要扩展我的工具箱,使其包含更多的语言,并对全栈有更多的了解。 当我说我的待办事项清单很长时,请相信我,最困难的部分是将我应该首先学习的内容放在优先位置。 就像我在上面说的那样,昨天并不是一个总的“损失”,而我用这个词是宽松的,因为我确实解决了自动布局所带来的一些问题。 仍然有一些警告,因此我想我仍然有很多事情要学习,但是我能够在所有iPhone屏幕尺寸上启动该应用程序,并且表现出我的预期。 结果,我今天可以继续进行一些严肃的编码。 大肆宣传!

探索一些标准库排序功能

在今天的文章中,我们将探讨一些排序功能。 这些是我们作为开发人员在几乎所有日常任务中使用的非常常见的功能。 我们将探索clang libc ++的一些函数,例如std :: sort,std :: stable_sort和std :: partial_sort。 另外,我们将研究其中一些函数的算法,并尝试了解它们的工作原理。 另外,我们将讨论Swift Collection排序方法\ o /。 使用排序算法时,我们要了解的最重要的事情之一就是时间复杂度。 幸运的是,此信息始终是这些方法文档的一部分,因此在调用标准库排序方法时,我们具有此保证。 分类 std :: sort是使用Introsort算法的排序函数,其复杂度为O(N log(N)),其中N = std :: distance(first,last)自C ++ 11起,且元素顺序相等不能保证保留[3]。 gcc-libstdc ++也使用Introsort算法。 Introsort是一种混合算法,基本上使用两种(或在某些实现中为三种)算法来优化运行时复杂性。 它开始使用Quicksort,并且如果递归深度超出接近O(N log(N))[1]的阈值,它将切换到Heapsort算法,以避免Quicksort最坏情况下具有O(N²)的情况。时间复杂度。 在某些实现中,它使用InsertionSort在排序过程中对小区域进行排序,因为在这种情况下,它的处理效率更高。 我们没有详细介绍Introsort算法的实现细节,但是您可以在[7]上看到伪代码,该伪代码显示了其背后的逻辑。 在下面,我们可以看到一个非常简单的示例,说明如何使用std :: sort对int向量进行升序和降序排序。 这就是本文的全部,希望您喜欢🙂 如果我有问题或您有任何意见或疑问,请告诉我。 我很高兴收到您的反馈feedback 您可以在Twitter上@ LucianoPassos11找到我。 感谢您阅读🙂 参考文献 2017年LLVM开发人员会议:A.基于Kumar Introsort的libc ++排序功能。 https://www.youtube.com/watch?v=Lcz0ZHewkHs “ libc ++” C ++标准库。 […]

iOS Touch ID身份验证教程

苹果在iPhone 5s中引入了TouchID,用户无需输入密码就可以使用指纹来解锁iPhone中任何功能的设备。 在OS 7中,Apple并未向开发者发布FingerPrint API,但在OS 8中,Apple向我们提供了在您的iOS App中使用此功能的API。 在本教程中,我将解释如何在iOS应用程序中使用此功能。 本地认证框架 要添加TouchID功能,您必须在项目中添加LocalAuthentication Framework。 转到项目设置>常规,然后向下滚动到链接的框架和库部分。 单击+号并添加LocalAuthentication.framework 。 2.认证视图 对于TouchID,我们将创建一个登录按钮,并在按钮的onClick上提供TouchID身份验证屏幕,以供用户解锁功能。 @IBAction func clickLoginButton(_ sender:Any){self.authenticateUSerTouchID()} 3. TouchID验证的成功与失败 func authenticateUserTouchID(){让上下文:LAContext = LAContext()//声明一个NSError变量。letmyLocalizedReasonString =“访问您的Home ViewController需要验证。” var authError:NSError? ){context.evaluatePolicy(.deviceOwnerAuthentication,localizedReason:myLocalizedReasonString){成功,评估错误,如果成功// //如果触摸ID身份验证成功,请导航到下一个视图控制器 { DispatchQueue.main.async {print(“系统验证成功”)let storyBoard:UIStoryboard = UIStoryboard(名称:“ Main”,bundle:nil)让homeVC = storyBoard.instantiateViewController(withIdentifier:“ HomeViewController”)为! //其他如果触摸ID身份验证失败,则打印错误MSG, {HomeViewControllerself.navigationController?.pushViewController(homeVC,animation:true)}} else // 如果让错误=错误{让消息= self.showErrorMessageForLAErrorCode(错误。代码)打印(消息) } }}}} 4.在Touch ID身份验证失败时打印错误消息 func showErrorMessageForLAErrorCode(errorCode:Int)->字符串{ var […]

服务器端Swift-配置文件

在前两篇文章中,我描述了如何向服务器端Swift HTTP服务器添加MVC模式(带有单元测试)。 在本文中,我将展示如何向应用程序添加对配置文件的支持。 配置框架 在ASP.NET Core MVC应用程序中,Microsoft添加了对读取配置文件(以及环境变量,命令参数等)的支持,语法和想法看起来很酷。 下面是可用于读取Microsoft框架中的配置的代码示例。 我想在我的Swift应用程序中实现类似的构造。 决定哪些参数最重要(基于执行方法的顺序)非常重要。 我想订购: file -> system environment -> command parameters 。 首先,我认为我必须自己创建这些类,但是后来我发现IBM创建了一个非常好的库。 IBM-Swift /配置 配置–用于Swift应用程序的分层配置管理器 github.com 这确实是一个很好的框架,可以满足我的所有要求。 它与Microsoft解决方案非常相似。 读取配置 要从我想支持的所有地方读取配置,我们必须将以下代码添加到我们的main.swift文件中。 将BasePath.pwd指定为relativeFrom参数很重要。 它是当前工作目录( PWD )的相对路径。 我的整个main.swift文件现在看起来像这样: 使用IBM的框架读取配置后,我将配置设置转录为自己的对象-该对象仅将我在应用程序中使用的配置存储为属性。 因此,我将在应用程序中使用真实的类属性,而不是字符串键。 我将拥有智能感知和更轻松的重构。 为此,我创建了ConfigurationManager类的简单扩展。 仅根据管理器的属性创建Configuratio对象。 我的Configuration对象真的很简单。 它存储了我可以在整个应用程序中使用的所有配置属性。 我的configuration.json对应于上述类,如下所示: 我们必须将该文件放在Package.swift文件附近。 当我们在Xcode中工作时,这一点很重要,因为此文件夹是当前工作文件夹,并且ConfigurationManager会正确找到此文件。 重建可执行文件后,我们的配置文件必须放在该文件附近。 依赖注入 现在,我已将所有配置存储在专门为此目的创建的对象中。 现在,我希望有一种方法可以在需要访问配置设置的所有地方使用该配置。 当然,最好的解决方案是依赖注入。 我将在我的依赖项容器中注册我的配置对象,并且我可以在任何需要的地方解析配置。 可以按照以下代码进行注册。 我正在将配置注册为单例。 现在我们可以例如通过注入构造函数来解析配置: 因此,在我的TaskRepository我注入了配置对象,并且可以使用该对象中的所有属性。 现在,我已经实现了可用于存储对数据库的访问信息的机制。 在下一篇文章中,我将使用该信息来准备连接以及从实际数据库(使用某些ORM框架)读取/写入对象。 […]

新的iOS软件体系结构:4V引擎

原始文章:https://marcosantadev.com/new-ios-software-architecture-4v-engine/ 您应该阅读这篇文章吗? 本文介绍的是一种新的软件体系结构,它具有比VIPER和MVVM-C更高的层次。 这意味着它可能比其他已知体系结构更复杂。 如果您想继续阅读本文,则必须接受我的观点,即如果我们想要一个干净且可测试的体系结构,则我们应该有几层责任。 我不想将其作为可以解决您所有问题的完美架构来出售。 它可能无法完全满足您的需求。 出于这个原因,我建议您通读这篇文章,并自己判断这种体系结构对您的项目是否有意义。 如果您想知道为什么MVC不足以进行iOS开发,建议您跳入为什么MVC不足。 介绍 我创建了这个博客,撰写了有关MVVM-C的文章。 然后,我写了一篇关于SOLID原理的文章。 在这一点上,您可能会认为我没有实践我的讲道。 如果我说的是“单一责任原则”,那么即使Coordinator层承担多个责任,为什么我仍要使用MVVM-C? 它创建堆栈( View Model , View和Service ),在父UIKit组件中添加View并确定路由添加/删除子协调器。 MVVM-C必须进行一些重构,以免违反“单一职责原则”。 在本文中,我将解释主要的iOS软件体系结构的替代方案: 4V Engine 。 祝您阅读愉快! 为什么MVC不够 我在上一篇有关MVVM-C的文章中已经介绍了这一点,但是我想再次写出来,因为我认为它非常重要。 成为iOS开发人员的一种常见方法是查看文档,并按照Apple建议的模式编写一些简单项目。 这意味着我们大多数人已经开始使用MVC作为软件架构来创建我们的第一个应用程序。 逐步地,我们开始习惯于MVC。 在学习过程的这一点上,我们认为MVC是正确的方法。 它起作用了,为什么我们要迁移到另一个增加代码复杂性的体系结构中? 主要有两个原因: SOLID原则:视图控制器的职责过多。 可测试性:视图控制器与UIKit紧密结合,因此很难进行测试。 如果我们想解决以上问题,则应该采用另一种架构。 不幸的是,没有什么是免费的。 这种改变有一个代价:复杂性。 如果我们查看VIPER和MVVM-C,我们会注意到有多个层次可以管理并让它们一起通信。 如果我们拥有简单的应用程序,或者我们实际上并不关心SOLID和可测试性,则可能会适得其反。 我个人的观点是: 我喜欢编写遵循SOLID原则并经过适当测试以尽可能避免错误的编写良好的代码。 因此,我想花时间和精力来创建新的干净软件体系结构。 MVVM-C的问题 如前所述,MVVM-C还不够。 Coordinator层违反了“单一责任原则”,必须分为三个部分,承担以下职责: 管理应用程序路由。 创建堆栈( View Model , View和Service )。 在父UIKit组件中显示View […]

Swift编程基础概述

Swift是一种用于IOS,macOS,watchO和tvO的新编程语言。 它也可以用于后端和前端开发,也可以用作脚本语言。 与其他任何编程语言一样,swift也使用变量通过标识名称来存储和引用值。 除普通类型外,Swift还引入了新类型,例如元组,枚举,结构,可选(无值)等。 Swift是一种类型安全的语言 ,它有助于弄清我们编写和工作的类型。 类型安全性有助于我们在开发过程中尽早发现并修复错误。 常量和变量 : 常量和变量将名称与特定类型值相关联。 如果未在声明中分配值,则需要为其指定类型,以便将来使用该属性。 常量的值一经设置就无法更改,因为将来可以将变量设置为新值(不同)。 “ let”用于定义常量属性,“ var”用于变量属性。 我们可以在一行中声明多个常量或变量,以逗号分隔。 2.类型注释: 在swift中,存在类型推断,因此当我们声明具有值的属性时,swift会将该值的类型分配给该属性。 因此,指定类型是可选的,但有时需要告诉编译器我们将用于该属性的特定类型。 要提供类型注释,我们需要在冒号“:”之后指定类型,后跟空格,然后是属性名称。 3.命名常量和变量: 常量和变量名称几乎可以包含任何字符,包括Unicode字符。 一旦声明了某种类型的常量或变量,就不能再用相同的名称声明它,或将其类型更改为另一种类型。 我们也不能将常量更改为变量或将变量更改为常量。 4.打印,评论,分号, 我们可以迅速使用全局函数“ print(_:seperator:terminator :)”将一个或多个值打印到适当的输出。 我们可以在SDK的调试控制台上看到打印输出。 分隔符和终止符参数具有默认值,因此我们可以在调用函数时将其省略。 我们使用注释在代码文件中包含不可执行的代码,作为对自己或团队成员的注释或提醒。 编译器将忽略所有注释。 单行注释以两个正斜杠(//)开头。 多行注释以正斜杠后跟星号(/ *)开头,以星号后接正斜杠(* /)开头 我们还可以为大型代码块编写嵌套的多行注释。 我们不需要在swift语句的末尾放置分号(’;’)。 如果需要,可以在语句末尾使用分号。 但是,如果我们想在一行上编写多个单独的语句,则需要分号。 5. Swift中的一些类型 整数 Int,UInt,UInt8,UInt16,UInt32 浮点数 双人,浮动 弦乐 6.类型安全性和类型推断: Swift是一种类型安全的语言。 类型安全的语言鼓励您清楚代码可以使用的值的类型。 编译器类型在编译代码时进行检查,并将所有不匹配的类型标记为错误。 如果我们没有指定所需的值类型,则Swift会使用类型推断来得出适当的类型。 通过类型推断,编译器只需检查您提供的值,即可在编译我们的代码时自动推断出特定表达式的类型。 当我们不指定任何类型时,Swift类型推断将提供顶级类型。 例如,即使您提供浮点类型,它也倾向于使用Double。 […]

Swift-Fileprivate ve openErişimBelirleyicileri Nedir,Ne Yaparlar?

Merhabaarkadaşlar, 苹果,苹果公司迅捷3’le birlikte fileprivate ve openerişimbelirleyicilerini dile dahil etti。 fileprivateErişimSınırlayıcısınedir ?, ne yapar吗? fileprivate’i anlatmadanönce私人erişimbelirleyicisi ne idihatırlayalım。 ☺️ 私人 erişimbelirleyicisi,方法论vb。 tamamen scope’dakullanılabilirkılar。 fileprivate eribel belirleyicisininamacıdeğişkenintanımlandığı作用域dışındaaynıdosyaiçerisindetanımlananbirdiğer类(sınıf)/扩展名( uzantı )tarafındanerişilmesidir。 Diyeceksiniz ki public negüneduruyor,onukullanırsamzatenaynıdosyaiçerisindeerişebilirim… Yanlış , neden mi? 公共尺寸istediğinizerişimseviyesininçokdahafazlasınısunuyor。 Ancak sizin bunaihtiyacınızyok,tanımladığınız私人değişkeninaynı类içerisindefarklı 类 / 延伸 tarafındankullanılabilirolmasınıistiyorsunuz,buununiçinfileprivate。 😎 打开ErişimSınırlayıcısıNedir,Ne Yapar吗? Aynışekildeburada da openerşimsınırlayıcısınıanlatmadanöncepublicerşimsınırlayıcısıüzerindenilerlemeninanlatımınyalınveözolmasıaııııııııııııını 🤪 公共 erışimsınırlayıcısıtümmodültarafındaerşilebilirdurumdadır,ancak ikimodülkullanıldığıdurumlarda altsınıflarda( 公共 […]

使用Swift爆炸IPv4范围。 💥

最近,在使用SwiftNIO进行宠物项目时,我发现需要将定义为范围的IPv4集扩展到IP地址数组中。 我上过Google,但是可惜,我在Swift中找不到任何预先存在的模块或代码示例。 我还简要阅读了Apple的新Network.framework,其中引入了新的IPAddress Type和其他一些简洁的东西……但是它不包括对我所寻找的功能的支持。 😔 在过去的类似项目中,我已经多次使用ipaddress等python库。 就像一个好的图书馆一样,它们总是抽象化事物的工作原理,并为您提供一种或两种简单的方法来完成大多数任务。 我自己做一个简化版本有多难? 事实证明,一次尝试以错误的方式做几次就不会太难。 IP范围 经过几次失败的尝试,尝试使用花式迭代和不同八位位组级别的嵌套后,它突然浮现了…… “ IP地址实际上只是用易于沟通的包装表达出来的大数字”🧐 这是真的。 IPv4地址只是1到4,294,967,296(IPv4地址空间)之间的整数,表示为由句点分隔的4个8位数字(八位字节)。 知道这一点,问题就变得简单得多。 要将IP范围扩展到其组成地址列表中,您只需执行几个简单的步骤。 将上限和下限转换为整数。 构建一个数组,其中包含上限和下限之间的所有整数。 遍历数组,将整数转换回IPv4格式。 我编写了几个函数,使用几种不同的方法来完成这些步骤。 IP到整数 从IPv4转换为整数并不复杂。 我研究了几种方法。 第一种方法较为详细,但对于某些人可能更容易理解。 它的工作原理是遍历IP地址中的八位位组,然后将每个八位位组乘以下一个256的幂。这是有效的,因为IP地址的基数为256。 使用base256的IP到Int 另外,您也可以在Swift中使用位移运算符来完成此操作。 如您所见,我们的通用函数看起来非常相似,但是,我们只是在移位位,而不是进行算术运算。 使用移位将IP转换为Int 整数到IP 我认为这是棘手的部分。 同样,我们可以通过从较早的时候反转256操作的幂或使用位移来做到这一点。 但是,与从IP到Int不同,在这种情况下,按位运算显然不那么复杂。 这里使用256的幂的基本思想是在每次迭代期间(从最高有效到最低有效)使用循环提取原始IP的一个八位位组。 这有点混乱,因为第一个八位位组和最后一个八位位组与中间两个八位位组的处理方式必须有所不同。 幸运的是,按位执行此功能非常容易。 在这里,我们只是进行移位操作和按位与,以确定每个八位位组值。 放在一起 这确实是很容易的部分,并且不管上面使用的方法如何组合都应该起作用。 使用Swift即可进行简单的IPv4范围扩展。 如果您知道执行此操作的任何更优雅或有效的方法,请在评论中分享。