Tag: swift

IBM通过Swift获得成功

IBM因成为技术领域笨拙的老人而臭名昭著。 它们已经存在了很长时间,并且(不包括IBM Watson)在寻求可以迎合时代精神的新创新方面一直落后于他们。 随着IBM最近为Swift推出的IBM Bluemix Runtime(IBM的多面云平台即服务),他们证明了他们的确表明自己确实可以变得肮脏不堪,并与我们那些ra脚的年轻人混在一起。 对于那些不熟悉的人,Swift是苹果的宝贝。 这是他们为macOS,iOS,OSOS开发的编程语言,基本上就是您可以想到的任何现代Apple OS。 简洁,自然的语言特性使它在编码社区中大受欢迎,尤其是对于那些有志于为Apple OS做出任何贡献的人(移动开发人员,我在看着你!)。 它适用于客户端和服务器端开发,需要较少的内存使用,并且总体上减少了硬件磨损,所有这些都导致了一种编码语言,使每个人的生活变得更加轻松。 苹果公司使学习变得简单(和FuN !!!),使Swift更具吸引力。 以iPad上的Swift Playgrounds应用程序为例,在该应用程序中,用户可通过围绕一个谜题的小头像来学习如何使用Swift。 可爱。 如果您在Quora,Medium或Twitter上关注我,那么您可能已经注意到我是Swift的忠实粉丝: 最初发布在 DamianEsteban.com

斯威夫特:无财产

TL; DR:UnownedProperties.playground 我们研究了从强到弱到懒惰的各种属性,以及如何观察它们。 接下来是无人财产。 这是一种属性,您可以避免长时间使用而不会遇到任何麻烦。 在过去的一年中,尽管有充分的理由使用它,但我并没有强烈地需要一次使用该无用功能。 无财产的主要目的是防止保留周期。 它的工作原理类似于弱属性,但主要区别在于,弱属性必须是可选的,而无主属性必须是非可选的。 它与弱属性的共同之处在于,无所有权的属性不会增加保留数,这就是为什么它被用来防止保留周期。 它有效地允许使用非可选属性,而无需增加引用的保留计数。 对于代码示例,我创建了一些类来表示乘客,驾驶员和出租车。 出租车的每个实例都需要驾驶员,而乘客是可选的。 Taxi类包含一个函数,该函数允许将驱动程序属性更改为另一个驱动程序,但无法将该属性设置为nil。 本质上,我们要强制执行的逻辑由编译器维护。 但这很危险。 如果基础价值消失了,那么在Taxi实例中该值将突然为零,因为Taxi实例并未保留该值。 在示例游乐场中,将驱动程序设置为nil的行被注释掉,因为使用nil值打印Taxi实例将导致运行时异常。 对于每天使用无人财产的情况,您可以考虑将闭包保留在自身上的时间过长,从而导致保留周期。 Hector Matos的详细示例对此进行了详细介绍。 重要的是要理解何时可以使用弱者或无人者。 以“驾驶员和出租车”示例为例,规则是没有驾驶员就不能存在出租车。 它根本无法操作来接载乘客。 另一个示例是始终要求银行客户存在的信用卡。 使用无财产时要谨慎。 它们可能是您应用程序中的隐藏杀手。 如有疑问,只需使用弱属性并在使用可选属性之前将其拆开即可。 那是安全的方法。 下一页:枚举和模式匹配 GitHub Gist

我在iOSCon 2017上的演讲经验

我很幸运参加了在伦敦举行的iOSCon 2017,并谈到了Swift中带有协议缓冲区的类型安全Web API 。 这是我第一次在国际会议上发言,但我真的很享受! iOSCon — iOS和Swift开发人员会议这是一年一度的iOS会议,每年都有很棒的演讲者! 因此,我很荣幸在如此出色的会议上担任演讲嘉宾! iOSCon 2017 – iOS和Swift开发人员会议| 2017年3月30日至31日| 伦敦 在英国伦敦举行的为期2天的会议。 iOSCon庆祝iOS的最新发展和最敏锐的头脑。 做… skillmatter.com 如果您对明年的iOSCon感兴趣,那么您绝对应该检查一下! iOSCon 2018 – iOS和Swift开发者大会| 2018年3月22日– 23日| 伦敦 在英国伦敦举行的为期2天的会议。 iOSCon庆祝iOS的最新发展和最敏锐的头脑。 做… skillmatter.com 我的话 我的目标是向许多人介绍协议缓冲区(也称为protobuf)。 因此,我分享了有关protobuf为何如此重要以及我如何在Swift中使用protobuf的经验和知识。 这是protobuf的快速回顾。 类型安全-您可以为HTTP请求/响应定义自己的类型 跨平台一致-您可以通过代码生成器共享模态数据 可扩展-protobuf是一种序列化格式,可以在任何地方使用。 我相信protobuf最适合Swift! 像我上面提到的那样,它有很多好处,所以绝对值得! 如果您对更多细节感兴趣,可以在这里找到我的幻灯片,示例应用程序和视频。 kitasuke / SwiftProtobufSample SwiftProtobufSample –使用协议缓冲区的Swift中客户端/服务器的示例项目 github.com Swift中带有协议缓冲区的类型安全的Web API 技能专区| 2017年3月30日 iOSCon 2017 – iOS会议和Swift […]

Swift 3中的错误处理:尝试,尝试?和尝试!

某些人可能已经熟悉使用关键字try来处理Swift中的错误。 对于那些不知道try是什么的人, try只是一种处理任何给定函数中可能出现的错误的方法。 通常,我们具有“抛出”功能,这意味着它们具有抛出错误的能力,而try是一个简洁的关键字,它使我们能够处理那些错误的可能性。 在构建我们的应用程序时,可以使用三种try形式。 尝试 尝试? 尝试! 如果您对这些变体感到恐惧,那就不要! 而且,如果您不确定要使用哪一个,请不要担心,我已为您覆盖。 正如我之前提到的, try通常与throw函数结合使用,因此我们将讨论一下throw函数,并在实际中使用try关键字。 假设我们正在尝试通过一些JSON进行解析,以便可以将这些数据带入我们的应用程序。 此数据可能由于互联网中断而无法到达我们的应用程序,或者您尝试提取的数据不再存在! 这些都是在我们尝试从API检索数据时可能出现错误的情况。 但是Swift的JSONSerialization方法具有内置函数,默认情况下throws 。 Swift知道我们检索数据的尝试可能会带来一些错误,并创建了一个函数,该函数使我们能够在发生错误的情况下解决该情况。 使用try ,我们的throw函数必须包装在do-catch语句中。 这使我们能够自定义错误处理并根据错误执行特定的操作。 下面我们将使用try来优雅地捕获任何错误。 做{ 让responseJSON =试试JSONSerialization.jsonObject(with:data,options:[])as! [[String:Any]] 完成(responseJSON) } { 打印(“嗯,这里出了点问题。请尝试连接到wifi。”) } 作为开发人员,将try与do-catch语句一起使用可使我们检查有意义的错误,以样式处理它们,并避免用户感到沮丧。 考虑一下,我们是否真的希望我们的应用程序在用户没有任何互联网连接时崩溃,还是我们要让他们知道该应用程序一旦连接到wifi就会继续运行? 在这种情况下,通知会更有帮助,而我们的do-catch语句使我们可以做到这一点。 另一方面,我们也可以使用try?处理错误try? 。 如果您有使用可选控件的任何经验,那么您很快就会意识到该try? 就是这样。 try? 让我们忽略我们的错误,并在我们的函数将其抛出时让它们变为nil。 因此,我们不必将代码包装在do-catch语句中。 但是,如果要分配try?我们是否必须解开变量try? 有价值。 让responseJSON =试试吗? JSONSerialization.jsonObject(with:data,options:[])as! [[String:Any]] 如果让responseJSON = responseJSON { print(“是的!我们刚刚包装了responseJSON!” } 上面的代码为responseJSON分配了一个可选值,并在调用的函数引发任何错误时将其设置为nil。 使用try? […]

大中央调度-Swift 3

Grand Central Dispatch或GCD是一种在我们的iOS应用程序中处理多任务的方法。 该系统的工作方式是可以将许多任务发送到调度队列,而调度队列又将在多个线程上运行,并最终由系统进行管理。 当我们尝试在其中一个应用程序中更新UI时,常常会想到GCD。 这些更新发生在主线程上,但是我们可能需要执行其他任务,并且这些任务可以在并发线程或后台线程上运行。 要添加一些上下文,队列是可以在主线程或后台线程中同步或异步运行的代码块。 使用队列时,我们可以使用Apple提供给我们的全局队列,也可以创建自己的自定义队列。 应该注意的是,全局队列应该谨慎使用,因为我们不想滥用它们。 为了更好地理解其中一些概念的含义,让我们直接进入代码并创建队列。 let queue = DispatchQueue(标签:“ queue.1”) 在这里,我们创建了一个自定义队列,并为其分配了唯一的标签。 您所说的标签完全是任意的,但最好为其命名与您的应用相关。 我们可以在这些队列上调用不同的方法,例如异步与同步。 这些关键字将告诉我们的应用程序如何执行我们的代码。 这是我们的代码在后台线程上同步运行而在主线程上运行的代码的示例。 //后台线程 queue.sync { 对于i in 0 .. <10 { 打印(“🔷”,i) } } //主线程 对于20中的i。<30 { 打印(“⚪️”,我) } 如果运行此代码,我们将看到如下所示: //打印:🔷0🔷1🔷2🔷3🔷4 … ⚪️20⚪️21⚪️22⚪️23⚪️24 … 我们的程序将在主线程上运行的for循环处停止,因为它是同步的,因此它可以在队列中执行我们的代码块。 如果我们将队列更改为异步,我们的应用程序将可以在主线程上自由运行代码,并且还将同时在队列中执行代码块,因此我们得到如下信息: //打印: 🔷0⚪️20🔷1⚪️21🔷2⚪️22🔷3⚪️23🔷4⚪️24🔷 … 尽管主线程是应用程序中的最高优先级,但是我们也可以指定队列的重要性,并让我们的应用程序知道如何确定任务的优先级。 该规范称为服务质量 (QOS)。 QOS是一个枚举,我们可以按从最高优先级到最低优先级的顺序将以下值分配给列出的队列。 .userInteractive .userInitiated 。默认 。效用 […]

如何保持您的iOS本地化文件整洁-Swift脚本版本

与bash脚本类似,我们首先通过create()从根目录中递归搜索本地化的字符串文件。 Apple的FileManager通过枚举对象使文件搜索变得容易。 注意,由于我们通常将打包在本地化文件中的Pod本地化文件打包,因此我们将忽略它们。在parse(_ path: String)方法中的本地化文件并存储时,我们将在此处搜索键重复来优化脚本。 Set的键。 该方法将为所有重复的密钥以及找到的文件路径打印error 。 ( 注意:任何 print(“error:”) 或 print(“warning:”) 格式都会通知Xcode在工具栏上显示相应的消息以及其他构建失败和警告 ) 接下来,我们将验证validateMatchKeys方法中所有可本地化的字符串文件中的键是否匹配。 我们将使用symmetricDifference编织出任何与基本文件都不匹配的额外键。 如果任何可本地化的文件不包含相同的键,则此方法将引发错误并中止脚本。 这使您有机会在下一次执行cleanWrite()之前清理可本地化的文件,它会使用已排序的键并删除多余的空格和换行符来重写可本地化的文件。 下一步是搜索代码库,存储这些文件中使用的密钥,并根据我们的基本密钥进行验证。 有了一点正则表达式,我们就可以成功找到密钥并将它们和文件的路径存储在LocalizationCodeFile结构中,同时还可以通过紧凑地映射出没有密钥的任何文件来优化脚本。 一旦有了我们的结构,我们将点击validateMissingKeys() -将遍历我们的LocalizationCodeFile集合,并减去基本键的每组键。 此结果中的任何其他键都不是我们基本键的子集,因此会给我们丢失的键。 如果找到任何丢失的键,则会引发错误。 我们的最后一个策略是搜索任何死键,这些死键是在可本地化文件中定义但未在我们的代码库中使用的键。 我们可以通过从flatization从LocalizationCodeFile集合中收集的所有键减去基本键来检索死键。 此处找到的所有键均显示为警告,因为此步骤更多是建议清除技术债务,而不是影响问题的用户。 对具有600多个可执行文件和估计800多个密钥的企业代码库执行bash脚本平均要花费81秒 。 在相同的代码库上运行此swift脚本平均要花3秒 ! 🚀🙌 保持干净 ,可读的代码库应该是每个工程师的目标。 通过将此Swift脚本注入到您的后期构建中,清理和维护可本地化的文件应有助于实现该目标并感到自动化。 您可以阅读我以前的博客,以了解如何将脚本注入到Xcode构建后编译中( https://buildingvts.com/clean-ios-localizable-files-8b910413b985 )。 我还在其中包括了一个包含整个脚本的GitHub项目以及此处的示例项目:https://github.com/ginowu7/CleanSwiftLocalizableExample。 随时发表任何意见或建议,您可以在Twitter @ ginowu07上关注我! 编码愉快! 🙏

在您的Swift应用中运行时内省和修改类

介绍ObjectiveKit 还记得2016年5月的重大动态辩论吗? 如果没有,请快速阅读以下内容: 动态迅捷 布伦特·西蒙斯(Brent Simmons)(如果有不清楚的话,请参见存档):在最近和将来的文章中,我正在记录问题…… mjtsai.com 简而言之,争论是开发人员目前正在利用ObjC运行时的动态功能解决许多类型的问题。 当我们(可能)朝着Swift完全取代Objective C的未来迈进时,Swift将需要提供自己的本机动态解决方案。 在iOS和macOS上,至少在可预见的将来,Swift将在Objective C运行时之上运行,这意味着我们可以完全访问这些功能。 可悲的是,在Swift中使用它们确实很痛苦。 我们可以做得更好…… 你好ObjectiveKit ObjectiveKit是用于访问Objective C运行时函数的新Swift框架。 它使自省,修改方法和在运行时创建类之类的事情变得非常容易,以一种对Swift来说尽可能原生的方式进行。 它是如何工作的? 您需要做的就是初始化一个ObjectiveClass对象,该对象的类型是您要内省/修改的类,然后使用ObjectiveKit的众多功能之一。 这是一个简单的示例: 使用Objective C运行时既有趣,有教育意义,又对调试非常有用。 但是,这也很危险-在生产中使用前请格外小心。 检查一下: github.com/marmelroy/ObjectiveKit

[Workshop]导航器视图(快速)

目的 创建一个导航器视图并测试它是否可以导航回到上一个视图 方法 创建UI 2.在第一个视图控制器和导航控制器之间将segue的类型设置为“当前模式” 3.将条形按钮项Item放置到3rd View Controller中。 在第3个View Controller和最后一个View Controller之间将segue的类型设置为Show 测试 点击按钮,下一步 2.单击按钮,项目 3.单击按钮,返回

View Controller的基本生命周期

好的,这是View Controller的基本生命周期。 这是Apple的View Controller文档。 有一些不同的生命周期事件 – loadView 创建控制器管理的视图。 仅在创建视图控制器且仅以编程方式完成时才调用它。 – viewDidLoad 在控制器的视图加载到内存后调用。 仅在创建视图时调用。 – viewWillAppear 只要视图出现在屏幕上,就会调用它。 在此步骤中,视图已定义边界,但未应用方向。 – viewWillLayoutSubviews 调用以通知视图控制器其视图将要布局其子视图。 每次框架更改时都会调用此方法 – viewDidLayoutSubviews 调用以通知视图控制器其视图刚刚布置了其子视图。 视图布局其子视图后,请在此处进行其他更改。 – viewDidAppear 通知视图控制器其视图已添加到视图层次结构中。 – viewWillDisappear 在过渡到下一个视图控制器并且将源视图控制器从屏幕上移除之前,将调用此方法。 – viewDidDisappear 从屏幕中删除视图控制器后,将调用此方法。 通常,您可以重写此方法以停止视图控制器不在屏幕上时不应运行的任务。

踢您的手动迭代习惯

当约翰·巴科斯(John Backus)于1977年在他的ACM图灵奖演讲中问“编程是否可以从冯·诺伊曼风格中解放出来?”时,他肯定比40年后仍为for(i = 0; i < n; i++)写作的人寄予更高的希望。 冯·诺依曼(Von Neumann)编程语言使用变量来模仿计算机的存储单元。 控制语句详细说明其跳转和测试指令; 和赋值语句模仿其获取,存储和算术。 赋值语句是编程语言的von Neumann瓶颈,使我们可以一次单词的方式思考,就像计算机的瓶颈一样。 到2017年,主要的编程语言已经吸收了函数式编程中最实用的思想。 我在这里说服您,使用高阶函数来处理数据集合通常可以使您的意图比手动迭代更清晰。 从描述如何执行计算作为循环增加计数器的副作用,或者通过从键集中索引到字典开始,我们早就应该进行下一步了。 这种命令式风格要求代码的人工阅读者在脑海中模拟计算机的执行。 那是一件坏事! 取而代之的是在抽象阶梯上上移一个梯级,并根据功能组成描述您的计算工作:过滤,转换和减少输入流。 在我遇到的大多数情况下,数据存储在数组或列表中的事实是出于方便。 存储在其中的数据没有真正排序。 数组通常只是最易于键入的集合,因为所有语言都内置了语法糖。 最好将集合一般认为是容纳某些元素的容器。 在处理它们时,请开始考虑符合给定条件的元素集-这就是过滤器应用程序。 是否需要为每个元素计算一些派生值? 这种转换称为映射。 需要整个集合中的一些总价值吗? 那就是缩小或折叠。 学习这些概念,并使用它们更清楚地表达您的意图。 当您将计算作为增加索引的副作用时,了解它需要您逐步执行所有命令。 当您通过功能组合来表达自己的意图时,隐藏错误的空间就更少了。