Swift 里的 String 繁琐难用的问题一直是大家频繁吐槽的点,趁着前两天 Swift 团队发了一份新的提案 SE-0265 Offset-Based Access to Indices, Elements, and Slices 来改善 String 的使用,我想跟大家分享一下自己的理解。

SE-0265 提案的内容并不难理解,主要是增加 API 去简化几个 Collection.subscript 函数的使用,但这个提案的背景故事就比较多了,看了这篇提案我思考了很多关于这个 API 相关的内容,我认为问题的核心在于 Collection.Index 的设计。

阅读全文 »

前几天 Cocoapods 1.7.0 正式版发布了,我最期待的一个功能是 Multiple Pod Projects,昨天顺手就给接入了,项目解析和索引效率有了非常明显的提升,过程中踩了些坑,这次一起把之前 debug 的经验分享一下。

阅读全文 »

SE-0244 Opaque Result Types 提案前一段时间通过了 review 并且在 Swift 5.1 里完成了实现,我最早阅读这份提案的时候理解不是很透彻,今天比较仔细地读了这篇 Improving the UI of generics 之后有了更多的认识,而且发现自己之前发的 tweet 里有一些错误的认知,所以这里写篇文章,希望用最直白的方式解释清楚提案的内容,跟大家分享一下我自己的理解。

Opaque Result Types?

用最最简单的一句话来介绍这个提案的内容,就是它能让被调用方选择泛型返回值的具体类型。

阅读全文 »

之前 Joe 跟 Doug 提了一个草案,提议加入一个叫做 Property Delegate 的提案,昨天作为一份预备提案发了出来,我看了之后觉得特别兴奋,所以写了这篇文章跟大家分享一下。

简介

我们在 Swift 定义属性的时候,有时候会需要它表现出更复杂的行为,例如线程安全(例子来源于 Objc.io 的这篇文章):

private let queue: DispatchQueue = ...
private var _count: Int = 3

var count: Int {
get { return queue.sync { _count } }
set { queue.sync { self._count = newValue } }
}

但每次都需要写这么长的代码显得很多余,所以这次提案提议增加一个名为 Property Delegates 的功能来简化这些属性的声明,这个名字翻译过来就是属性代理

有了这个功能之后,想要一个线程安全的属性时只要加上一个注解 @Atomic 即可:

@Atomic var count: Int = 3
阅读全文 »

最近公司的项目开始做登录模块的页面改版,验证码/邀请码的输入框没有找到很合适的第三方控件去做,自定义的时候踩了一些坑,所以写了这篇文章记录一下。

UI 大概是这样子的:

验证码输入框

阅读全文 »

之前 fir 上传接口返回的数据里增加了一个 release_id,让我们可以直接跳转到对应 Build 的下载页面,但 GitLab 并不支持动态 Environment URL

为此 GitLab 提供了一个环境变量 CI_ENVIRONMENT_SLUG,可以作为合法的子域名使用,但这种方式并不利于我们接入第三方服务,例如 iOS 常用的测试分发平台 fir。

解决方法也很简单,使用一个中转服务器去存储 CI_ENVIRONMENT_SLUG 与下载地址的映射,然后通过 CI_ENVIRONMENT_SLUG 访问时查询对应的下载链接,重定向过去即可。

阅读全文 »

这两天偶然发现系统设置里 tableView deselectRow 的时机和效果都很特别,正常情况下我们的 deselect 操作都会在 didSelect 代理方法里执行,抑或者是更加细致一点,在 viewDidAppear 里完成。

但 iOS 原生的 App 说不,我还可以做得更好,这是系统设置里的效果:

图像

阅读全文 »

  • 提案: SE-0206
  • 作者: Karoy Lorentey, Vincent Esche
  • 审核人: Joe Groff
  • 状态: 已实现 (Swift 4.2)
  • 决策记录: Rationale
  • 实现:
    • apple/swift#14913 (standard library, underscored),
    • apple/swift#16009 (Hasher interface),
    • apple/swift#16073 (automatic synthesis, de-underscoring)
  • 上一个版本: 1

概览

阅读全文 »

以往我们实现 debug 函数,一般都是直接使用 compile flag (也就是编译宏)去实现的:

func debug(_ action: () -> Void) {
#if DEBUG
action()
#endif
}

但这种方式需要修改工程文件的设置,而且离开了 Xcode 就不能很好地使用。

今天看 Vapor 的源码时看到了一个很巧妙的实现:

阅读全文 »

Codable 作为 Swift 的特性之一也是很注重安全,也很严谨,但它对于“严谨”和“安全”的定义不一定跟别的语言一样,这就导致了它在实际使用时总会有这样那样的磕磕绊绊,我们不得不重写 init 方法去让它跟外部环境融洽地共存。最近在工作中这样的事情发生多了,我也就不得不想办法去解决它。

阅读全文 »