直接可以参考官方的文档即可:https://swift.org/migration-guide-swift4/

简单记录我的步骤:

  1. 利用Xcode9的 Swift Migrator tool迁移Swift3.2
  2. 利用Xcode9的 Swift Migrator tool迁移Swift4
  3. 如果是CocoaPods,目前建议保持Swift3。Xcode9支持Swift3和Swift4的target混合编译,这也是这么快能把项目迁移Swift4的原因。https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Compatibility.html

需要手动更改的地方:

  1. NSAttributedString attributes 类型 [String: Any] 改为 [NSAttributedStringKey : Any]

  2. Swift Migrator tool 会错误地转为NSAttributedString.DocumentAttributeKey.documentType 改为NSAttributedString.DocumentReadingOptionKey.documentType

  3. Swift 4: Cannot assign value of type ‘(_) -> Void’ to type ‘(() -> ())?’ 部分情况不能使用下面的简写格式。

    1
    2
    3
    { _ in
    print($0)
    }

  4. Method ‘initialize()’ defines Objective-C class method ‘initialize’, which is not permitted by Swift。 关于Swift4不支持initialize()这个问题,先跳过了,项目只有工具类定义且未使用。

总结

这一次新版本迁移很轻松,API更改也不多,强烈迁移立即迁移Swift4。

The Ultimate Guide To iPhone Resolutions

最近思考设计稿一个字号显示在不同设备物理尺寸是否一致,即对于用户看到的大小是否一致?

因此从理论和实践两个方面对于三个尺寸(4、4.7、5.5)英寸的差异。

1. 理论:

参考资料:The Ultimate Guide To iPhone Resolutions https://www.paintcodeapp.com/news/ultimate-guide-to-iphone-resolutions

根据上图的计算每个点对应物理尺寸,公式为:

1
2
3
piexl / inch = (point * (render * downsmaping)) / inch 

inch / point = (render * downsmaping) / (piexl / inch)

每个点的大小 等于 每个点实际对应的像素数 除以 每英寸像素(PPI)

render downsmaping piexl / inch inch / point 20 * (inch / point)
4” 2 1 326 0.00613497 0.12269939
4.7” 2 1 326 0.00613497 0.12269939
5.5” 3 1/1.15 401 0.00650548 0.13010951

1.06039312336 = 0.00650548 / 0.00613497

结论:4” 和 4.7” 完全一致,5.5”同样点数要比其他的大,约为1.06倍。

2. 实践:

写了一个Demo https://github.com/gewill/Demo/tree/PPI ,真机量了一下物理尺寸也和上面的结论一致。

1
2
3
4
5
6
7
8
9
10
11
12
13
/// 各种字号的文本
func drawLabel() {
var y: CGFloat = 40
for size in 13...24 {
let label = UILabel()
label.text = "Font size: \(size)-壹拾贰亿拾陆-@#¥ABCxyz"
label.font = UIFont.systemFont(ofSize: CGFloat(size))
label.backgroundColor = UIColor.green.withAlphaComponent(0.4)
y += CGFloat(size) + 20
label.frame = CGRect(x: 0, y: y, width: UIScreen.main.bounds.width, height: CGFloat(size))
self.view.addSubview(label)
}
}

WWDC 2017 Session 219 地址:[https://developer.apple.com/videos/play/wwdc2017/219/

目录:

  • 手势 The UIGestureRecognizer system
  • 系统手势 System gesture interaction
  • 拖拽 Drag and Drop

1. 手势

基础:

  • UIGestureRecognizer 比 UITouch 优先级高

    1
    2
    3
    4
    5
    class UIGestureRecognizer: NSObject {
    open var delaysTouchesEnded: Bool // default is true.
    open var cancelsTouchesInView: Bool // default is true.
    open var delaysTouchesBegan: Bool // default is false.
    }

  • UIGestureRecognizer 只有一个的胜出相应手势

  • UIGestureRecognizer 是否允许同时响应其他手势:在delegate可控制

    1
    2
    3
    4
    5
    public protocol UIGestureRecognizerDelegate: NSObjectProtocol {

    optional func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool

    }

  • UIGestureRecognizer 是否让其他手势失效

    1
    2
    3
    4
    open class UIGestureRecognizer: NSObject {
    open func shouldRequireFailure(of otherGestureRecognizer: UIGestureRecognizer) -> Bool
    open func shouldBeRequiredToFail(by otherGestureRecognizer: UIGestureRecognizer) -> Bool
    }
  • Hit Testing

  • 新属性 name,便于调试

手势系统的注意事项:

  • 复查你的构建步骤(Revisit your setups )
  • 排除和失效的标准(Exclusion and failure requirements)
  • 手势是否在正确的视图上?( Are your gesture recognizers on the right views?)

2. 系统手势

应用手势和系统手势之争!如非沉浸式的游戏或画画的应用,别推迟系统手势。

1
2
3
4
5
6
7
8
9
10
11
12
13
class MyViewController: UIViewController {

// override to return which screen edges to defer system gestures
override func preferredScreenEdgesDeferringSystemGestures() -> UIRectEdge {
return deferControlCenter ? .bottom : UIRectEdge()
}

// call whenever your method would return a different screen edge
var deferControlCenter: Bool {
didSet { setNeedsUpdateOfScreenEdgesDeferringSystemGestures() }
}

}

3. 拖拽

1
let dragInteraction = UIDragInteraction(delegate: myDelegate) myView.addInteraction(dragInteraction)

总结

手势部分关于同时兼容或禁止其他的应该都很熟悉,尤其是分页加 table view经常处理。iOS可以延迟系统边缘手势很不错的选择,很多app手势经常与系统同步调出。拖拽的话,主要在iPad上应用,就不深入学习了。

WWDC 2017 Session 201 地址:https://developer.apple.com/videos/play/wwdc2017/201/

主要是新的API概述,所以简单听一下,主要感兴趣的点:

  • 自动变化的大标题栏(Large Titles)
  • Safe Area Insets
  • 屏蔽系统边缘手势:preferredScreenEdgesDeferringSystemGestures
  • UIScrollView:contentLayoutGuideframeLayoutGuide
  • 闭包式KVO
  • 通过Keychain 自动填写密码(Password AutoFill for Apps )

iPhone Sound Switch

WWDC 2017 Session 803 地址:https://developer.apple.com/videos/play/wwdc2017/803/

1. 为何声音是设计的一个重要方面

  • 很多app都自己的通知的声音,为自己app设计声音可提高辨识度。

2. 为通知设计声音

  • Dark Sky为例,好的通知声音:已于辨识、传达信息、友好的、清晰的
  • 立项时要思考的问题:产品的本质?唤起什么样的情感?符合app的美学?声音来源?
  • 推荐采集合成声音的app:Voice Memos、Music Memos、Garage Band、Logic Pro
  • 好的通知声音的特性:可辨别的、符合设计、不突兀、可重复的、清晰的

3. 为UI元素设计声音

  • UI声音:键盘、滚动、按钮、点击、滑动、变换
  • 好的UI声音的特性:谨慎的使用、低音量、有帮助、愉悦的、建立深入人心的体验

4. 提示和技术

  • 思考几个问题:通知频率?品牌建立有什么作用?对UI有什么好处?没有界面时如何理解我的app?
  • 不要过度使用
  • 为用户提供开关
  • 细节很重要
  • 真机测试,包括耳机
  • 和专家合作:声音设计师、声音工程师

总结

感觉每次听下来都很容易,毕竟是苹果出品,写笔记时才感觉要操作的细节很多。作为一个开发者更多的是思考:声音对app的体验的帮助。

ps:稍后看WWDC打算参考这个 WWDC 2017 Viewing Guide:https://useyourloaf.com/blog/wwdc-2017-viewing-guide/

WWDC 2017 Session 102 地址:https://developer.apple.com/videos/play/wwdc2017/102/

1. Swift Playground

  • 更强大的 Playground,支持控制外设,如:机器人、无人机。

2. Xcode 9

  • 重写的代码编辑器( Source Editor),支持Markdown,开源转换引擎(Transformation Engine)
  • 问题(Issues) 更好的提示和更智能的自动修复
  • 当然还有缺席已久的重构(Refactoring)
  • 移动文件到group,自动移动物理位置
  • 完整支持git,和github集成

3. Swift 4

4. 调试和分析(Debugging and Analysis)

  • View Debugger
  • Thread Sanitizer、Address Sanitizer
  • 正确的 Main Thread API Checker

5. Xcode Server Built in

6. UITest更快,支持多应用多模拟器

  • 模拟器支持自定义大小

7. 无线调试

8. Frameworks

  • 简单介绍了主要更新的库,就不看了,和Keynote差不多,直接看感兴趣的Session好了。

ps:不知不觉看到了凌晨一点,今天把感性的的Session都下载了。立个flag,今年争取看30个。

WWDC 2017 Session 402 地址:https://developer.apple.com/videos/play/wwdc2017/402/

一些特性在 https://github.com/ole/whats-new-in-swift-4 的 Playground 已经演示,就不具体记录了。

总的来说:应用方面小修小补,迁移成本也很小,最高兴的就是编译方面的优化,结合Xcode的优化,相信Swift 4会更快。

1. 语言修饰和增补

  • private 变回 Swift 2,extension可见
  • 组合类和协议 (Composing Classes and Protocols),用法class & protocol
  • KeyPath
  • Swift 对 JSON 解析,Codable协议
  • 对Swift 3兼容,项目中3和4并存

2. 编译的提升

  • New build system 必须手动打开
  • index 优化,很赞会节约不少时间,我一度以为这是Xcode的bug
  • 不可预知类型性能优化(Unpredictable Performance in Swift 3),用COW优化(COW Existential Buffers)
  • 更小的二进制:移除无用的@objc部分代码,编译设置(Change build setting to Default: Swift 3 @objc Inference)
  • 符号大小(Symbol Size)

3. 字符串

  • Unicode支持,重音或表情,为一个字母,count为1。In Swift, a Character is a grapheme.

  • 表情处理速度提升

  • characters 改为集合类型

  • 字符串也改为集合类型

  • 支持切片(Slicing),let s = "one,two,three"; s.split(separator: ",")

  • 子字符串(Substrings)浪费内存,应该String(substring)

  • 终于支持多行字符串,格式为首尾 """

4. 一些通用特性

  • 拓展Sequence
  • Sequence拥有Element
  • 通用的下标(Generic Subscripts)

5. 独占的访问内存(Exclusive Access to Memory)

运行时强制:

  • 全局变量(Global variables )
  • 类的属性(Properties of classes )
  • 逃逸闭包中的变量(Local variables captured in escaping closures)

默认编译时打开,运行时关闭,可在build settings更改。

这一段有点难,回头再看看Onevcat翻译的 所有权宣言 - Swift 官方文章 Ownership Manifesto 译文评注版

自从学习iOS开发以来,断断续续加起来也有2年时间了。最近离职,是时候做一下总结,梳理一下知识点。

iOS开发最开始入门是 Stanford University Developing iOS 7 Apps,虽然是英语,但是最基本的概念也是那时候一点点学的。当然后来离职参加培训班,是进步最快速的一段时间,也培养了真正自学的能力。到后来参加iOS的工作,一直以来引以为好的就是自学能力。因为对于iOS开发来说:语言、设计模式、框架、文档、调试和测试等都已经掌握了,实际开发工作中,无非是一些实际的问题或者新的框架和系统特性,只要查询文档或者Google一下都能解决了。

框架

谈到iOS框架,必须是MVC,工作以来的项目一直都是MVC。足够简单的分层和经久验证的良好设计。对于其他的如:MVVM,只是了解,实际项目中未曾应用。比较简单的业务逻辑和团队人数少的情况下,MVC足够好用。

语言

Objective-C是入门语言,其语言复杂性足够新手望而却步,但是也就属性特性和方法调用比较难。后来工作中一直使用Swift,才感觉到现代语言的简单和强大。尤其是Swift多范式,支持函数式编程,尤为方便。由于对Swift的偏爱,我也逐渐把第三方库都替换成了Swift对应的版本。Cocoapods对于Framework的支持也比较好, 添加use_frameworks!,即可调用Objective-C的库也很Swifty。

设计模式

Delegate、通知、KVO、Target-Action、Block(Closure)、工厂方法、单例等就不一一介绍,更具实际需求选择合适且喜欢的就行。特别推荐这篇文章:消息传递机制

Cocoa Touch

iOS渲染层次树、view、layer、响应链、Core Animation、自定义view、常见UIKit的控件的继承关系,table view、collection view等都应该熟练使用。

学习资源

微博、Twitter、博客、书、视频教程都是很好的。列几个对我影响比较的:

常用库

这里是最为推荐的几个库:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

pod 'SwiftyJSON'
pod 'SnapKit'
pod 'IGListKit'
pod 'Kanna'
pod 'URLNavigator'
pod 'MXSegmentedPager'
pod 'QMUIKit'
pod 'IBAnimatable'
pod 'Ruler'
pod 'DZNEmptyDataSet'
pod 'CYLTabBarController'
pod 'FDFullscreenPopGesture'
pod 'MJRefresh'
pod 'SwiftyUserDefaults'
pod 'YYKit'

# Test tools
pod 'MLeaksFinder'
pod 'FLEX', '~> 2.0', :configurations => ['Debug']
pod 'Reveal-SDK', '~> 4.0', :configurations => ['Debug']
0%