作者:KHANLOU,原文链接,原文日期:2017-03-28
译者:四娘;校对:Cwift;定稿:CMB

Swift 标准库里最容易被滥用的就是 Sequence 的 enumerated() 函数。这个函数会返回一个新的序列,包含了初始序列里的所有元素,以及与元素相对应的编号。

enumerated() 很容易被误解。因为它给每一个元素都提供了一个编号,对于很多问题来说这是一个很简便的方案。然而,这些问题大多数都可以被另一种方式更好的解决,让我们来看一下其中的一些例子吧,要注意理解它们有什么问题,然后如何使用更好的抽象去解决它们。

阅读全文

作者:Soroush Khanlou,原文链接,原文日期:2016/8/8
译者:Cwift;校对:Crystal Sun;定稿:CMB

译者注:英文原文发布时间较早,故原文代码中的 Swift 版本较旧,但是作者已将 GitHub 上的 Promise 示例代码更新到了最新 Swift 版本,所以译者在翻译本文时,将文章里的代码按照 GitHub 上的示例代码进行了替换,更新成了最新版本的 Swift 代码。

上周,我写了一篇介绍 Promise 的文章,Promise 是处理异步操作的高阶模块。只需要使用 fulfill()reject()then() 等函数,就可以简单自由地构建大量的功能。本文会展示我在 Promise 方面的一些探索。

阅读全文

作者:Natasha The Robot,原文链接,原文日期:2017-03-12
译者:saitjr;校对:Crystal Sun;定稿:CMB

几个月前,我在 iOS Conf SG 上做了名为 创建 Feature,而不是 App 的分享(你可以在这里查看完整分享)。在 WWDC 2016 之后,我清晰地认识到今后的发展不是一个大一统的 App,而应该拥有各种小功能的 Feature。想想 Apple Watch,Widget,可交互的 Notifications,App Search,iMessage 贴纸,地图这些数不胜数的应用。

阅读全文

作者:Erica Sadun,原文链接,原文日期:2016-10-08
译者:粉红星云;校对:Crystal Sun;定稿:CMB

McFly 问到:我在这个地方一直报错:"不能将 ·String? 变量强制转换为 NSString",而且我在 stackoverflow 上也没有找到解决方法。

先回答这个问题,在转换成其他类型之前必须将可选类型解包。String? 指的是一个存储在可选类型枚举(Optional enumeration)中的值,可以是有值的也可以为空。这就是报错的原因了。

阅读全文

作者:Tomasz Szulc,原文链接,原文日期:2016-07-30
译者:智多芯;校对:Crystal Sun;定稿:CMB

同时负责两个项目是个探索应用架构的好机会,可以在项目中试验一下已有的想法或刚学到的知识。我最近学习了如何封装一个网络层框架,说不定对你有所帮助。

如今的移动应用几乎都是“客户端-服务端(client-server)”架构,在应用里都会有网络层,大小不同而已。我见过很多种实现方式,但都有一些缺陷。当然这并不是说,我最近实现的这个一点缺陷也没有,但至少在目前的两个项目上都运行的很不错。测试覆盖率也将近百分百。

本文涉及的网络层仅限发送 JSON 请求给后端,也不会太复杂。该网络层会和亚马逊 AWS 通信,然后向它发送一些文件。这个网络层框架能容易地扩展其他功能。

阅读全文

作者:Dominik Hauser,原文链接,原文日期:2016-04-19
译者:Darren;校对:Crystal Sun;定稿:CMB

昨天有人问我, Swift 初学者应该先学什么。 问题是这样的:

我有个问题想咨询一下你, 是应该花时间学习 TDD (测试驱动开发) , 还是应该学习 Swift 和函数式编程,哪样更值得学习?

当然,我的观点会有一些偏见,因为我写了一本关于 Swift TDD 的书。在看我的回答时,切记这一点。

阅读全文

作者:Andyy Hope,原文链接,原文日期:2016-07-20
译者:X140yu;校对:walkingway;定稿:CMB

↑ ↑ ↓ ↓ ← → ← → B A

无论是你学习的第一门语言是 Swift 还是之前学过 Objective-C,在学习 Swift 的过程中,一定会感叹它真的是一门超赞的语言。但如果你不熟悉它的某些语法,就可能会被某些写法吓到。在这里我会介绍一些在写 Swift 过程中常见语法,希望你们能用 Swift 写出更简洁的代码。

阅读全文

作者:Arthur Knopper,原文链接,原文日期:2016-06-01
译者:TonyHan;校对:walkingway;定稿:CMB

让观察者模式变得更美好

OSX 已经有至少 17 年的历史,而 NotificationCenter 在其第一次版本发布就已经存在,并且一直是苹果开发者常用的工具。对于不了解的人来说,NotificationCenter 是基于 观察者模式 的概念,也是软件设计模式中行为型模式的一部分。

阅读全文

作者:Arthur Knopper,原文链接,原文日期:2017/04/05
译者:Crystal Sun;校对:walkingway;定稿:CMB

picker view 看起来像是自动贩售机或者角子老虎机,用于展示一组或者多组数值。用户通过滚轮来选择数值,选中的值处在同一行中。Xcode 里的 User Interface 提供了 picker view 控件,展示可选的组件和行。组件就是滚轮,有很多行,每行都有固定的 index 值。本教程使用的是 Xcode 8.3 和 iOS 10.3。

阅读全文

作者:Arthur Knopper,原文链接,原文日期:2017-01-09
译者:钟颖Cyan;校对:Cwift;定稿:CMB

通过长按手势来展示上下文菜单,给了用户对选中对象进行 剪切/复制/粘贴 操作的能力。在默认情况下,Table View 的上下文菜单是禁止的。在本文中,使用上下文菜单复制 Table View Cell 上面的文字,随后可以将文字粘贴到 Text Field 里面。本教程基于 Xcode 8.1 和 iOS 10。

阅读全文

作者:Arthur Knopper,原文链接,原文日期:2015-12-22
译者:钟颖Cyan;校对:Cwift;定稿:CMB

译者注:由于原文日期较早,文章代码已更新为新版本。

UITextChecker 对象可以用来对一个字符串进行拼写检查,在这篇教程里面我们将在一个 Table View 里面展示一些单词。当单词被选中的时候,会被进行拼写检查,拼写正确的背景将会变成绿色,否则将会变成红色。本教程在 Xcode 7.2 和 iOS 9 环境下进行。

阅读全文

作者:Ole Begemann,原文链接,原文日期:2017-02-08
译者:四娘;校对:Cwift;定稿:CMB

上周的 Swift Talk 里,Florian 和 Chris 编写了一个有序数组类型 SortedArray:一个总是按照指定规则排序的数组。这很赞,因为它将多个不变性编码到了类型系统里。用户可以使用这个类型去取代普通的 数组 ,而且不用担心忘记手动排序数组。

为了保持视频简短,Florian 和 Chris 省略掉了一些很实用的功能。我想给你展示一下这部分实用功能的实现。这些实现都不难编写,我的主要目的是让你明白借助标准库去实现一个紧贴需求的自定义集合类型是多么简单。

你可以去 GitHub 上查看全部代码 ,但下面会有更多讲解。

阅读全文

作者:Ole Begemann,原文链接,原文日期:2017/3/6
译者:Cwift;校对:walkingway;定稿:CMB

有时候为了新增一个功能,会去修改你的 ViewController 。但代码总是环环相扣的,你会发现在 ViewController 中引入一个可选型的属性时,在某些情况下该属性会被赋值,而在另一些情况下它不会被赋值。

我认为大多数情况下,这种方案是有缺陷的。原因有几点。首先,当一个类含有未使用的可选型属性时,这个类中描述身份的语义会变弱。换句话说,添加可选型属性会模糊 类型的基本语义 。第二,可选型的属性不带任何语义。如果该属性的值是 nil ,那么当前对象处于什么状态呢?如果别人只是粗略浏览你的代码,并不能搞清楚什么情况下属性会是 nil ,或者如果属性是 nil 的话对对象本身有什么影响。第三,代码会继续发生变异。一个可选型的属性会变成两个,然后变成三个,等你发现的时候已经掉坑里了。在某个值还是 nil 的时候你想要表达出该值当前必须存在的意愿,仅靠普通的可选型是办不到的。

在我见过的代码库中,我发现有两种原因可能会致使你在 ViewController 中添加一个可选型的属性。我会对这些情况进行探索,提出有针对性的更好的解决方案。

阅读全文

作者:Ole Begemann,原文链接,原文日期:2017-03-08
译者:Cwift;校对:walkingway;定稿:CMB

假设你有一个结构体:

struct Person {
var name: String
}

并且让其遵守 Equatable

extension Person: Equatable {
static func ==(lhs: Person, rhs: Person) -> Bool {
return lhs.name == rhs.name
}
}

实际的效果满足预期:

Person(name: "Lisa") == Person(name: "Lisa") // → true
Person(name: "Lisa") == Person(name: "Bart") // → false

阅读全文

作者:Soroush Khanlou,原文链接,原文日期:2016-08-01
译者:Cwift;校对:walkingway;定稿:CMB

Promise 是一种链接异步任务的方式。通常来说,异步任务会在异步操作完成时执行回调闭包(有时候要准备两个闭包,一个代表成功,一个代表失败)。要执行多个异步操作,必须将第二个异步操作放在第一个异步操作的完成闭包中执行:

APIClient.fetchCurrentUser(success: { currentUser in
APIClient.fetchFollowers(user: currentUser, success: { followers in
//现在你得到了一个 followers 数组
}, failure: { error in
// 错误处理
})
}, failure: { error in
// 错误处理
})

Promise 的作用是格式化完成闭包,简化链式异步调用的形式。如果系统能够分辨成功和失败,那么组合这些异步操作就变得容易很多。比如,编写具有下列功能的可重用代码:

  • 使用尾闭包执行一系列依赖关系的异步操作
  • 通过一个完成闭包同时执行多个独立的异步操作
  • 多个异步操作竞争,返回第一个完成的值
  • 重试异步操作
  • 为异步操作设置超时时间

阅读全文