Tag: Swift 4

Swift#1:元组或元组?

问题 Entédéveloppeur,关于如何解决唐纳德的问题。 Dans le cas d’unedonnée很简单,例如在renvoie comme valeur de retour d’une fonction上。 Dans le cas d’unedonnéeComplexe,在适当的“人间结构”上。 Mais si cettedonnéen’est ni trop简单,ni trop复合物? 恩·贾瓦(En JAVA),杜瓦河沿岸(envoy de renvoyer deux)的康菲恩·德·富瓦(Trois Valeurs sans pour autantcréerun tableau)? 解决方案存在于Swift中: les tuples 。 Quéest-ceque les tuples? 永久组团的便利性的元帅,新古典主义风格的无价之宝。 瓦伦西亚和瓦卢斯的元帅同盟 斯威夫特的自由主义者丹尼斯·拉·库普里斯(Das la librairie standard de Swift),前女同性恋夫妇(clé, valeur) valeur (clé, valeur)专注于类型Dictionary上的结构和功能,而您可以根据自己的喜好来选择。 语言元组: let person =(名称:“ […]

Swift 4中的主函数

目的 介绍在Swift 4中使用函数的所有有用信息。希望到本文结尾,您将对在Swift 4中使用函数有深刻的了解,然后将其优雅地应用到您的项目中。 我给出的例子将是相关的。 基本上使用我们已经知道的东西来解释一些新东西。 我会尽力而为。 清晰,简洁,实用。 目前为止就这样了。 打开Playground,让我们直接潜水。 什么是功能? 函数是执行特定任务的独立代码块。 – 苹果 我们定义函数来执行某些任务,稍后可以调用。 就像具有已定义功能的“打开”按钮的交流遥控器一样。 我们可以通过按“开”按钮来调用该已定义的函数,AC会尝试冻结您。 有史以来最简单的功能 让我们从零地面开始,然后逐步发展。 这样我们就不会错过任何一件事情。 在我下面是一个空函数,请检查一下: func emptyFunction(){ } 我可以在我的代码中这样调用: emptyFunction() 目前,它绝对不执行任何操作。 这样,我们就可以剖析函数并了解Swift中创建函数的每个细节。 与iOS开发人员,代码访问员和书面交流时,下一部分特别有用。 要“命令”我们刚刚对另一个人所做的事情,可以说定义一个称为“空函数”的函数。 func→定义一个功能 emptyFunction→函数名称 现在可以使用 如今,我们中的很多人都沉迷于皇家冲突。 也许只是我。 无论如何,让我们从Clash Royale的场景中举例说明。 我们将定义一个函数,对其进行调用,然后逐步学习一些东西。 让我们来看看它的作用。 限定 尝试看看是否可以根据我收到的描述提供一个功能。 定义一个名为“ battle with”的函数,该函数带有两个参数。 第一个参数是字符串类型的播放器名称。 第二个参数是我们要使用的战斗甲板。 如果您没有获得参数部分,请不要担心,因为我尚未向您介绍参数,但是在本文中将进行详细介绍。 这是函数编写方式的示例: func BattleWith(playerName名称:String,BattleDeck卡座:Int = 2)->字符串{ return(“使用甲板编号\(甲板)的战斗\(名称)。”) } 不要惊慌。 […]

在项目中管理快速扩展的更好方法

我们如何在项目中管理扩展。 下面来自我的项目的截图说明了一切。 例如,我有一个简单的扩展UIColor + toImage,用于从一种颜色生成图像。 用法。 让redImage = UIColor.red.toImage() 完美不是吗? 可读性 。 1.没有人可以轻易猜出此函数是来自原始UIColor类还是来自我自定义的扩展(除非深入阅读该定义。) 2.该扩展会在不同的项目中重复使用,因此我们很可能希望它们继续进行到下一个项目中。 很难猜测它所属的名称空间。 一种简单而古老的方法是在扩展名中的所有函数名称之前使用带有_( 下划线 )的前缀。 例如。 my_或abc_ 让redImage = UIColor.red.my_toImage() 但是这种解决方案是无法管理的,因为我们必须确保所有函数都以my_作为前缀。 如果我们使用my.toImage()而不是my_toImage()怎么办。 因此,想法是制作一个名为MyHelper的单个模块类/结构,其中将包含所有扩展方法。 如果需要,我们也可以将功能分组为扩展。 MyHelperCompatible协议具有` my`变量,该变量保存整个MyHelper类/结构对象。 现在,我们可以根据用途扩展MyHelper 。 例如。 在上面的文件中,我们可以添加与UIColor相关的其他帮助器函数。 同样,我们可以将alls函数分组为MyHelper扩展。 最后,我们可以像下面一样访问toImage()。 让redImage = UIColor.red.my.toImage() 从现在开始,我们只需要创建上面的扩展和方法即可。 无论如何,我们都想停止这种行为,我们可以注释掉/删除一致性部分。 //扩展名UIColor:MyHelperCompatible {} 提示 :将所有一致性保持在一个地方而不是分散在项目周围是一件好事,这样您就可以更好地控制。 我知道这似乎有点棘手,并且需要花费额外的精力来设置一次,但是我相信,随着项目的发展,它会大有帮助。

Swift中的内存管理

什么是弱变量? 您知道吗,在IBOutlets前面。 查看苹果的文档,我发现了自动引用计数(ARC)。 Apple使用ARC进行内存管理并跟踪内存使用情况。 诸如强,弱或无主之类的关键字会在何时添加或释放保留计数时向ARC发出信号。 坚强的默认Default 每次我们声明一个class属性时,默认值都是一个强引用。 神奇宝贝类{ var名称:String =“ Pikachu” var skill:Skill = Skill() } 班级技能{ var类型:字符串=“ Pika Thunder” } 让myPokemon = Pokemon() 打印(“我的新皮卡丘技能:”,myPokemon.skill.type) 宠物小精灵具有技能属性。 当我们创建Pokemon类时,也会创建Skill类。 因此,Pokemon类具有指向Skill类的强大指针,并增加了Skill的保留计数。 当Pokemon类被释放后,指针将被删除,Skill类将其保留计数减少为零。 参考不足 等一下,如果指针指向两个方向的是双向关系呢? 如果Skill类具有指向Pokemon类的指针,并且Pokemon类被分配了一个值,我们将创建一个保留周期 🔄这可能导致内存泄漏🙁 class Pokemon {var name:String =“ Pikachu” var技能:Skill = Skill()} class Skill {var type:String =“ Pika Thunder” var pokemon:Pokemon?} let myPokemon = Pokemon()myPokemon.skill.pokemon […]

数据结构

堆栈和队列 堆 堆栈是后进先出数据结构。 想象一下一大堆砖头。 您已经承担了将这些砖块放在盒子中运输的任务。 那么,看看这个庞大的堆栈,我们是从堆栈的底部开始拉砖还是从顶部取砖? 常识将指示我们从顶部开始,而不是从10,000磅的Jenga游戏开始。 这很像堆栈在这里的工作方式。 放置在LIFO数据结构中的最后一个元素是从中检索的第一个元素。 尽管堆栈可能从表面上看起来像数组,但元素的顺序支撑了功能。 因此,在创建堆栈时,必须限制访问堆栈中元素的方式。 队列 队列是先进先出列表数据结构。 先进先出数据结构意味着元素只能在后面插入,并在前面出队。 队列在现实世界中最好用购买电影票的线来表示。 在售票热线中,第一个排队的人首先要购买门票,排队的每个人都按照加入队伍的顺序购买门票。 像使用Stacks一样,从队列中删除数据的顺序对于其能否正常运行至关重要,因此确保对队列数据的访问进行适当管理至关重要。 var queue = Queue () queue.isEmpty // true queue.push(值:“一个”) print(queue.count) // 1 queue.push(值:“两个”) print(queue.count) // 2 queue.push(值:“三”) print(queue.count) // 3 queue.push(值:“四个”) print(queue.count) // 4 queue.isEmpty // 否 print(queue.pop()) //一个 print(queue.pop()) //两个 print(queue.pop()) //三个 print(queue.pop()) //四个 堆栈和队列的实际使用 在需要保留列表顺序或添加或删除项的顺序很重要的情况下,堆栈和队列可用作临时数据结构。

iOS移动应用程序中的推送通知

+ Shubaham Jain iOS移动应用程序中的推送通知 对于iOS应用,您可以通过以下两种方式实施Firebase Cloud Messaging: 通过Firebase Cloud Messaging APNs界面接收最大4KB的基本推送通知消息。 在前台应用程序中向上游发送消息和/或接收高达4KB的下游数据有效载荷。 将Firebase添加到您的iOS项目 对于iOS客户端应用程序,您可以通过两种互补的方式实施Firebase Cloud Messaging: 通过Firebase Cloud Messaging APNs界面接收最大4KB的基本推送消息。 在前台应用程序中向上游发送消息和/或接收高达4KB的下游数据有效载荷。 将Firebase添加到您的iOS项目 先决条件 在开始之前,您需要在环境中进行一些设置: Xcode 8.0或更高版本 针对iOS 8或更高版本的Xcode项目 Swift项目必须使用Swift 3.0或更高版本 您的应用程序的捆绑标识符 CocoaPods 1.2.0或更高版本 对于云消息传递: 物理iOS设备 您的Apple Developer帐户的Apple Push Notification身份验证密钥 在Xcode中,在“ 应用”>“功能”中启用“推送通知” 在Mac机器上安装Cocoapods的步骤: 步骤1:如果您的计算机上未安装cocoapods,请首先在终端sudo gem install cocoapods上使用以下命令将其安装在计算机上 步骤2:将汇出至 导出PATH = $ PATH:/ Library / Ruby / […]

Swift中泛型和协议一致性的功能。

在Swift协议和泛型中可以很好地协同工作,实际上有一个术语可以简化这种关系。 它被称为DRY(不要重复自己),它的意思是:使用抽象避免重复。 因此,在这里,我将向您展示泛型在Swift中的强大功能以及协议一致性如何提升泛型。 让我们看一下以下示例: 假设您要确定两个条件是否相等。 编写一个函数,该函数返回一个布尔值以根据我们正在比较的两个事物是否相等来返回true / false。 例如,让我们编写一个函数来测试两个整数值是否相等: 太酷了,现在可以测试两个整数是否相等,但是无法测试其他类型,例如Double’s,Floats和其他可以相等的Swift类型。 因此,使用Swift中的泛型以及协议一致性,我们可以做到这一点: 哦哦 ,现在发生了什么? 为什么会出现错误? 该错误是由于以下事实造成的:T是泛型类型,并且未知它是否可以相等。这就是协议一致性起着重要作用的地方。 因此,我们强制等于函数仅采用相等的参数类型。 这就是我们在Swift中可以做到的方式: 要么, 从上面的代码片段中可以看到,泛型和协议一致性如何真正帮助您避免编写重复的代码。 如果您开始在代码库中更频繁地使用泛型和协议,这是一个好习惯。 它肯定会简化您作为开发人员的生活。

掌握CoreData(第3部分:核心数据中的CRUD)

为了演示核心数据的基础知识,让我们创建一个单视图iOS应用,并选择“ 使用核心数据”或下载入门项目。 如果您有一个现有项目,但未选中“ 使用核心数据”复选框,则仍然可以添加核心数据,我将在后面的部分中进行介绍。 创建项目后,您将看到添加的文件如CrudOperationCoreData.xcdatamodeld 。 我将在Todo应用程序上演示CRUD操作。 最终版应用可以执行以下功能 用户可以添加任务 用户可以删除任务 用户可以看到所有任务 当您使用CrudOperationCoreData.xcdatamodeld文件时,您将看到一个工具,可用于配置代表数据模型的实体。 您可以为每个实体定义一些事物,但对我们而言, 属性和关系将是最重要的。 到目前为止,我们已经完成了创建并获得核心数据支持的项目。 在CrudOperationCoreData.xcdatamodeld中,我们用数据库术语定义Entity或表,并定义属性(数据库术语列)。 “ xcdatamodeld ”是一个称为“ 受管对象模型 ”的文件,其中,如上一部分所述,定义了应用程序的所有架构。 我说过,我们将 深入讨论时 将称为 第2部分 ,因为我们在该部分的理论方面进行了很多讨论。 托管对象模型 托管对象模型是一组对象,这些对象一起构成了一个蓝图,描述了您在应用程序中使用的托管对象 您的应用程序中使用的模型对象的架构 正如我们在第2部分中讨论的那样,我们需要创建Core Data堆栈才能使用Core Data,但是我们还没有创建堆栈。 事实是,当我们在创建项目时选中“ 使用核心数据”时,它会自动在AppDelegate文件中创建堆栈代码。 打开AppDelegate文件 当您看到代码时,您几乎看不到您在Core Data stack Part 2中学到的任何东西。 但是您可以看到NSPersistentContainer的惰性属性 NSPersistentContainer NSPersistentContainer通过处理托管对象模型(NSManagedObjectModel),持久性存储协调器(NSPersistentStoreCoordinator)和托管对象上下文(NSManagedObjectContext)的创建,简化了核心数据堆栈的创建和管理。 可从iOS 10获得 当您跳到NSPersistentContainer类定义时,您将在此处看到所有Core Data堆栈组件。 创建记录核心数据 将记录添加到核心数据的过程具有以下任务 从appdelegate单例对象引用persistentContainer 从persistentContainer创建/访问单例托管对象上下文 使用Task创建一个实体(代表ToDo任务) 使用此任务实体创建新记录 设置每个键的记录值 将其保存到磁盘(永久存储)。 […]

精通CoreData(第17部分,多线程并发策略上下文UndoManager)

这一部分是上一部分的延续。 必须查看使用父子策略解决的临时问题。 现在,在这一部分中,我们将使用undo manager解决此问题。 要了解什么是临时更改问题,请参考上一部分 在第二部分中,我们说 托管对象上下文(MOC) 托管对象上下文提供缓存,更改跟踪,延迟加载, 重做,撤消和验证功能 撤消管理员 UndoManager提供了一种简单的方法来向您的托管对象上下文添加撤消/重做功能。 它是托管对象上下文的Instance属性。 如果您遵循这些教程,请下载入门项目或删除应用程序。 首先注释掉这些行, 如图1所示。 从流程图了解撤消管理器 如您在图2中看到的,我们执行了许多任务以了解undo manager的工作方式 首先,我们启动/开始撤消组以跟踪我们将执行的更改。 此时撤消管理器开始跟踪更改 将用户1添加到托管对象上下文中,并将其引用到撤消堆栈 将用户2添加到托管对象上下文中,并将其引用到撤消堆栈 结束撤消组(这很重要,否则应用程序将崩溃) 执行context.undo撤消更改 如您所见, 用户1和用户2现在已删除并移至重做堆栈中 现在出现执行重做用户1和用户2 如您在图3中看到的,我们将流程图论证明为代码 已创建“托管对象上下文”的undoManager实例属性。 默认情况下,在iOS中,其值为nil 通过调用beginUndoGrouping ,我们开始跟踪对象并将其分组到撤消堆栈中 在托管对象上下文中添加了两个用户对象 endUndoGrouping将结束该组。 这个非常重要 最后,我们通过执行撤消和重做操作来查看日志 如您所见,撤消操作后未打印任何User对象。 通过重做在控制台上打印的两个用户对象 注意:首先beginUndoGrouping将分组级别增加到2。 嵌套撤消组 在最后一个撤消组中执行撤消操作 如图4所示undoNestedGroup组撤消添加用户2时的最后一个组。 如您所见,我们在第一个撤消组上添加了用户,在第二个或最后一个撤消组上添加了用户2。 通过执行undoNestedGroup ,它将撤消添加了User2的最后一个撤消组。 现在,第一个撤消组成为再次调用undoNestedGroup之后的最后一个撤消组,它将删除User1, 如图4所示。 如您在图5中看到的,我们使用代码进行了证明。 执行撤消嵌套组撤消最后一组。 有很多事情你应该知道 undo →如有必要,关闭顶级撤消组,并调用undoNestedGroup() 。 undoNestedGroup →在最后一个撤消组(顶级或嵌套)中执行撤消操作,将重做堆栈上的操作记录为单个组 […]

使用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)// […]