Tag: 编码

斯威夫特:边做边学

正如我所说的,我根本没有发布任何应用程序的计划–直到我上了Udemy的Geeky Lemon课程。 在编写了基本应用程序,设计并添加广告以及关闭广告的方法之后,他通过发布与我进行了交谈。 在不知不觉中,我已经在App Store上发布了一个应用。 Tap Stars在我的生日那天上线,并且仍可供下载-现在我正在了解一个新版本,有关Swift和iOS的更多信息。 瑞安·莫里森(Ryan Morrison)的《踢星》 自那时以来,我已经完成了数十门课程,遵循了在线指南并观看了YouTube视频,从而使我对自己构建基本应用和游戏的能力充满信心。 我的想法是我通过建造中学到的。 通过遵循指南和编码以及与其他人一起构建一个完整的应用程序,我比以往任何时候都可以教我更多的知识,从而更快地获得了更多的知识。 实际上,我最近已经完成了另一个对儿童友好的计算器应用程序–而不是一个屏幕来完成您具有加,减,减,除,乘和平方根屏幕的所有功能。 我遵循了一个指南,但是从他的代码中转移了很多,以一种更适合我的风格的方式来做。 我也已经开始研究macOS版本以练习跨平台工作。

开发自己的应用程序以做笔记。

这不是一个应用程序广告,而是一个关于为什么和我以及Sunm设计和开发此应用程序的故事。 应用是我们的日常生活,我们通过构建应用来改善生活。 深度学习 作为沉重的互联网查看者,这些年来,我阅读了3w上的大量文章,文章或故事。 不幸的是, 那些引起我兴趣的想法随着时间的流逝而悄悄溜走了 。 我意识到我应该充分利用它们,而不仅仅是滚动和查看,我努力在物理笔记本或应用程序中做笔记。 参与生活似乎是生活中一种重要的方式。 不再有笔记应用程序 许多朋友推荐Evernote做笔记,但我对此表示严重怀疑。 我强迫自己使用带有过度设计的动画的此应用程序,直到以烦人的格式打开我的笔记。 然后我切换到Apple Notes。 Notes应用程序具有许多新添加的功能,例如与其他用户同步,手绘图等。它对作者很有吸引力,但对我而言却不那么有吸引力。 这些强大的功能是不必要的,对我来说是浪费的。 基本要求 作为开发人员,为什么不自己创建自己的(不适用于App Store)笔记应用程序? 我把这个想法告诉了我的UI / UX设计师女友Sunm。 她和我有同样的情况。 对于使用多个应用程序来记住词汇,记笔记和准备厨师食谱,她感到非常沮丧。 她肯定需要定制的应用程序。 因此,让我们开始思考我们的需求。 URL链接是具有上下文的来源。 原始上下文有助于我们轻松理解。 应该对其进行维护并方便地进行检索。 单词->句子->故事语境 。 这些要素对于理解任何新词汇都非常有用。 它必须包含在内。 单词发音纠正了我们的问题。 它只需要一步就可以得到它。 (现在我们必须长按->说) 图片可以帮助视觉记忆。 在google或bing中搜索图像应该放在首位。 Quizlet功能是t0测试的好方法。 通常,记笔记应该既有趣又迅速。 我们的想法/笔记应用 首先,我们基于URL创建了一个文件夹。 顺便说一句,我们从macOS复制了颜色标签来标记文件夹(对我来说,绿色代表中等故事,紫色代表小说,蓝色代表音频材料)。 然后我们在这个应用程序中阅读它。 在阅读时,我们复制了我们感兴趣的这些项目。(“复制”直接创建项目)。 阅读完毕后,我们很容易获得该故事的单词或句子列表。 如果您再次阅读该故事,则您感兴趣的所有单词和句子都将突出显示。 同时,您可以单击它以发言,或在bing.com中搜索该项目的图像。 下图第一张右上角的按钮的功能是: 播放声音:说出/ mp3文件(如果您为此文件夹插入了mp3网址)。 查看此文件夹的链接。 原始上下文在这里。 测验:从单词到带有图片的句子 添加一个新项目。 […]

快速入门Swift中的面向协议的编程

首先,我不会理解为什么面向协议的编程要比继承等更好。 有很多有关该主题的材料,因此您可以发表自己的看法。 我只想与您分享一些我在学习过程中学到的好东西。 我目前正在将我的Objective-C库WANetworkRouting重写为Swift。 顺便说一句,我们在Wasappli的许多应用程序中都使用了该库,您应该尝试一下:通过一些配置行,您可以将应用程序连接到REST Web服务,并在几分钟内将数据缓存到CoreData。 我可能一直在说:我只是将我的代码翻译成Swift,但我想潜入该语言提供的新思维方式。 在过去的8年中,成为Objective-C开发人员使我的习惯变得异常激动。 在Swift中,我最喜欢的事情之一就是如何使用协议为类添加行为。 除了使用继承,您还可以摆脱任何层次结构并放宽行为堆栈。 您还可以精确地决定采用哪种行为,而不必在某个时候吃一堆意大利面。 这样做还鼓励您编写更可测试的代码👍 让我们深入研究代码:WANetworkRouting的功能之一就是能够执行GET myObject之类的功能,而无需知道API上的路由。 在OC库中,我有一个名为WANetworkRouter的组件(很明显),它注册WANetworkRoute,它具有一些属性,例如pathPattern (例如: pathPattern shelves/:itemID ), httpMethod ( POST , GET ,…)和对象类。 这主要是受RestKit和一种方便的配置方式(一劳永逸地配置所有库,以使内容分离)的启发。 例如,您可能正在编写此 然后,通过调用此方法,路由器将针对您的API构建路径。

现在,您的孩子可以一边吃零食,一边学习代码

您的孩子还有另一个理由要您购买糖果和饼干,这一次是有充分理由的。 日本公司Glico以生产诸如Pocky等一堆受欢迎的小吃而闻名,它为孩子们提供了一种令人垂涎的方式来学习代码。 该公司已经推出了一个名为Glicode的新应用,该应用可以让您的孩子在玩饼干和糖果的同时学习编码。 要玩游戏,孩子们必须按照特定的顺序放置实际的饼干和小吃,以使角色在游戏中前进。 然后,他们必须拍摄一张照片,以将其转换为数字命令。 每种糖果都与动作有关,例如杏仁峰巧克力和饼干奶油沙,格力高公司的其他产品分别与“ if”和“ sequence”命令有关。 这个想法很像Apple即将推出的iPad应用程序Swift Playgrounds,在其中必须通过简单的编程任务来移动角色。 该应用程序当前仅在Android上可用,但该公司可能还附带iOS版本。 由于该品牌因其经典的Pocky而非常受欢迎,因此该游戏极有可能成为热门游戏。 尽管此应用程序是为儿童设计的,但您也可以尝试一下。 毕竟,任何人都可以玩自己的食物。

使用可编码对带有关联值的枚举进行编码和解码(Swift 4)

在下载管理器框架的Swift 4迁移过程中,我重写了模型对象(符合NSCoding NSObject子类)。 我的DownloadItem的状态由带有关联值的枚举表示: 使用Swift 3,我必须编写一个符合NSCoding的包装对象,以保留该枚举。 使用Codable不再需要此解决方法,因为我可以直接向枚举添加Codable一致性。 现在,有不同的方法可以实现此目的。 我仍然不确定最好的解决方案是什么,但是也许有人可以使用我目前的方法。 在查看DownloadState ,让我们看一下一个简单的Value枚举示例: 在类型和大小写之间存在一对一的映射,因此我们可以设置一个如下所示的容器: //伪字典 [“ string”:字符串,“ int”:Int,“ data”:数据,“ double”:Double] 毕竟, KeyedDecodingContainer和KeyedEncodingContainer只是非常严格的字典,其中下标键是强类型的String枚举(符合CodingKey ),而getter和setter利用Swift的错误处理系统来提供有意义的错误,说明为什么获取或设置特定键的值可能失败。 因此,至少对我而言,将容器视为具有固定键的字典是有意义的🙂 为Value实现Codable可能看起来像这样: 我们使用decodeIfPresent函数,因为将只设置一个密钥。 缺点是我们不使用switch语句进行解码,因此当我们添加新的大小写而忘记对其进行解码时,编译器不会对我们大喊大叫。 而且,它不适用于DownloadState示例,因为我们有带有和不带有关联值的案例。 我的方法是使用“基本”案例和关联值作为CodingKey ,然后让一个私有枚举将所有基本案例作为简单String托管。 让我们看看它的外观: 我真正喜欢的是编译器可以完全自动生成Base的Codable实现,因为它只是一个String枚举。 不幸的是,我们仍然必须为DownloadState provide提供Codable实现。 以下伪字典都是DownloadState所有有效表示形式。 //伪字典 [“基地”:“取消”] ->下载状态。取消 [“ base”:“ paused”,“ pausedReason”:“ waitingForWifi”] -> DownloadState.paused(原因:.waitingForWifi) [“基础”:“下载”,“下载进度”:0.5] -> DownloadState.downloading(进度:0.5] 可以缩放吗? 不……如果涉及多个关联值,则实际上这是一个非常复杂的类型,应像嵌套结构或类一样进行处理。 请考虑以下示例,其中Route表示带有主页和详细信息页面(用于播放音乐)的音乐应用程序的不同屏幕: 超级简单吧? 但是将每个关联的值添加到CodingKeys 有一些缺点: 在与基本情况相同的层次结构上具有关联值在语义上是错误的(就像在DownloadState示例中一样,但是更加突出) 如果枚举得到更多的情况(和更多的关联值),这将变得更加难以阅读和维护 如果这是一个类或结构,则您永远不会考虑对父代中嵌套类型的信息进行编码。 […]

UICollectionView快照滚动和分页

对于具有相同大小的单元格和一个部分的集合视图,这是一种捕捉逻辑(可以轻松添加更多部分的逻辑)。 scrollViewWillEndDragging具有inout targetContentOffset参数,这意味着我们可以读取和修改滚动的结束位置。 幸运的是,我们不需要考虑插图,行或项目的间隔( 由于包含了它们而浪费了很多时间,因此无法理解为什么正确的数学会产生错误的结果 ),但是我们需要考虑情况用户滚动到最后一页的位置-targetContentOffset将在范围之内,但当前contentOffset不在范围内,因此我们也需要检查一下: //获取单元格宽度 让cellWidth = collectionView( collectionView, 布局:collectionView.collectionViewLayout, sizeForItemAtIndexPath:NSIndexPath(forItem:0,inSection:0)).width let page:CGFloat //计算建议的“页面” 让proposedPage = targetContentOffset.memory.x / cellWidth // 3.25应该返回第3页:floor(3.95)== floor(3) // 3.3+应该返回第4页:floor(4.0+)!= floor(3) 如果floor(proposedPage + 0.7)== floor(proposedPage) && scrollView.contentOffset.x <= targetContentOffset.memory.x { 页面=楼层(建议页面) } 其他{ 页=楼板(建议页+ 1) } //替换滚动的结束位置 targetContentOffset.memory = CGPoint( x:cellWidth *页面, y:targetContentOffset.memory.y ) 如果需要“真正的”分页,如一次滚动一页,我们需要做一些改动: //我们需要保存起点 私人var startingScrollingOffset = […]

Swift解决方案:装饰器模式

Swift Solutions是涵盖设计模式的一系列文章。 在每篇文章中,我们讨论该模式是什么,何时应用以及如何以Swifty方式实现它。 在Swift解决方案的此迭代中,我们将在Swift中实现Decorator Pattern。 该模式提供了一种向应用程序添加功能的有用方法,并且是每个开发人员都可以在其套件中使用的出色工具。 我们将在方法上做到周密,以免材料发粘。 我们将在Swift中定义,说明和编码模式。 最终,您将了解该模式是什么,何时应用以及如何编码。 让我们直接进入定义! 限定 装饰器模式可动态修改核心对象的行为,而无需更改其现有的类定义。 装饰器模式有两个主要组成部分:一个将修改其行为的核心对象,以及一个在核心对象中带来更改的行为的装饰器对象。 这两个组件可以共同实现两个主要目标: 行为修改 …动态实现 行为修改 该模式的目的是在不修改其现有类实现的情况下更改核心对象的工作方式。 这是通过用装饰器包装核心对象来实现的,装饰器可以增强核心对象的默认行为。 装饰器从字面上完全“装饰”(修改)了它们包装的对象。 装饰器增强了核心对象中已经存在的行为。 它们与核心对象共享相同的接口,但提供不同的实现。 结果,客户端无法区分是使用装饰器还是使用核心对象:它们在两者上调用完全相同的函数/属性。 此共享接口允许装饰器充当中间人,拦截对核心对象的调用并为客户端提供自定义行为。 动态修改 装饰器不只是简单地修改行为,而是动态地修改行为。 换句话说,它们更改了对象在运行时(而不是编译时)的工作方式。 编译时行为修改很简单:只需要​​直接更改对象的类定义或子类并覆盖其默认实现即可。 但是,由于以下原因,可能不希望使用这些选项: 可以将核心对象类声明为final ,这可以防止子类化。 该类可以在第三方框架中定义,对它的任何更改都将在下一次框架更新时丢失。 可能存在许多所需的修改,并且可以将几种行为链接在一起以产生复杂的组合。 为每种可能的组合创建一个子类将导致类爆炸。 对现有类的更改可能会导致意外的副作用,从功能中断到崩溃。 当继承脆弱且未完全理解的旧版代码库时,尤其如此。 所有这些缺点使动态方法成为有吸引力的替代方法。 我们没有将具有不同行为的核心对象的多个变体硬编码,而是将每个行为分成了自己的专用包装器类。 然后,通常在用户输入期间,将这些专用包装器在运行时应用于核心对象。 用户选择他们的自定义项,然后我们应用包装器以产生所需的结果。 这是一种灵活的方法,因为行为的组合是通过根据需要增量应用包装器来实现的。 说明 我们将使用赛车游戏作为插图。 在此游戏中,玩家在每次比赛前选择车辆。 选择后,他们可以自定义车辆的轮胎,变速箱,发动机等。 这些自定义通过更改其统计信息来影响车辆的行驶方式。 在我们的示例中,统计信息将是速度和牵引力。 玩家可以选择更换零件以更好地适应他们的喜好。 例如,玩家可以选择将默认轮胎更改为越野轮胎,这些轮胎的抓地力更好,但速度却有所降低。 实行 让我们使用赛车插图来实现该模式。 protocol Transporting { func […]

Swift数据结构:堆

堆是一个非常整洁的数据结构,可以对最小值或最大值进行优先级排序。 它与树的分层和节点结构有些相似,但是由于它是线性的,因此可以轻松地存储在数组中。 对于视觉人来说,如果我们将其绘制出来,这就是堆的外观: 上图显示了最小(最小)堆,该堆优先排列顶部数据集中的最小值作为根父节点。 在下面,存在值为3和8的节点,它们分别作为父节点的左和右子节点(值为2)存在。 值为3的节点的左子节点为4,右子节点为7。此过程将一直进行下去,直到所有数据集中的值都已布置好为止。 请注意,这些值通常随从顶部到底部的增加而增加。 它们本身不是从左到右组织的,而是按行组织的。 第1行在根节点的位置包含值2。 第2行的左,右子节点的值3和8都大于2。第3行包含了节点3和8的左右子节点。如您所见,两个节点的子节点在值。 希望您开始注意到一种模式。 最小堆中的每个父级可以有0、1或2个子级-所有这些子级的值都大于父级。 最大堆的工作方式完全相反。 堆利用索引系统(如数组)来确定值的顺序及其在堆中的位置(从索引0开始并向上计数)。 如果我们从较早之前引用可视堆图,则索引从上到下,从左到右递增,如下所示: 到目前为止,您所看到的示例都显示了静态数据。 我们没有添加或删除任何项目,但是最重要的是我们可以更改Heap中的数据,否则此数据结构将毫无价值。 在Swift中,我们将首先创建一个名为MinHeap的结构, MinHeap所示: 遵循堆的规则,您可以看到从上到下的每一行通常会逐渐变大,并且每个父节点的子节点都大于其自身。 调用peek()返回您期望的2值,而调用poll()在删除第一项后重新排列堆。 若要查看实际效果,请将以下代码添加到MinHeap结构的底部,然后再次调用dump(myHeap.items) : 我们做到了! 现在,我们已经成功地构建了一个最小堆,它对传入的最小值进行优先级排序。删除值后,堆将重新排序,因此下一个最小值位于顶部。 但是在现实世界中可以在哪里使用呢? 在Github Gist上获得完整的源代码:https://gist.github.com/kalub92/d269ba6b2bf05ca7dcbaae64b4ff7a2d 想象一下,您正在为儿科急诊室建立患者摄入系统。 医院希望优先考虑最年轻的患者,以便他们能够尽快接受护理。 想象一下,有几个6、7和8岁的孩子在候诊室,但一个病得很重的1岁孩子进入候诊室并经历了摄入过程。 在时间上,1岁应排在第4位,但该医院希望首先照顾最年轻的患者。 如果在患者摄入计划中使用了Heap,则1岁的孩子会马上去找儿科医生见面。 这是一个特定的用例,但我想知道您的想法。 您认为堆可以在现实世界中有用地实现在哪里。 在下面发表评论,让我们知道! 如果您准备加入我们并了解有关Swift,数据结构和iOS开发的更多信息,请查看Devslopes并注册我们的Apple坡度,以学习构建自己的应用程序和启动基于应用程序的初创公司所需的所有技能。 。

在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 。 […]

基础知识:Swift最佳做法

最近,我的伙伴对编程表现出了兴趣,因此自然而然地我推荐Swift作为一种很好的语言。 我花了很多时间亲自研究了Swift的最佳实践,我想确保她确实遵循了整个Swift社区的最佳/常见实践(我认为其中有些是最佳实践),并且没有从一些那里的教程。 即使这些教程为初学者提供了一个很好的起点,我也注意到一些确实困扰我的做法,我建议您反对。 注意 我应该指出, 这要取决于我在编写Swift代码时的最佳做法以及我在社区中的研究中所收集的内容。 我敢肯定会有人不同意,这很好。 我仍然会睡个好觉😉 首先,让我们从合作伙伴搜索初学者教程时遇到的编码实践开始。 我还将介绍与其他开发人员一起进行项目时所经历的一些经验。 1)冒号空间 尽管这看起来很小,因为它只是一个空格,但是它可以大大提高代码的可读性。 推荐的 命名:字符串 不建议 让名字:字符串 命名:字符串 让名字:字符串 简单。 在冒号之后,在类型之前添加一个空格。 2)花括号 当谈到花括号时,通常似乎是一个意见问题。 但是,在浏览互联网上的一些样式指南,Apple文档中的示例以及我个人的看法时,确实有一个赢家。 推荐的 如果isValid && list.count == 0 { …}否则,如果isValid { …}其他{ … } 不建议 如果isValid && list.count == 0 { …} 否则,如果isValid { …} 其他{ … } 要么 如果isValid && list.count == 0 […]