img

系列文章目录:

  1. Realm 笔记 (一)
  2. Realm 笔记 (二)

Realm Database 基于C++编写的核心引擎,支持多平台多语言的移动端数据库。因其面向对象存取模型,高效的性能,开源的特性,不失为移动端数据库好的选择。之前项目也有使用过,基本上看官方文档和Demo,即可解决大部分问题。最近买了 Advanced Swift Spring Bundle,包含 Realm: Building Modern Swift Apps with Realm Database, 故再系统学习一遍,是为此笔记。

img


第一章:介绍Realm

  1. Realm API是更现代且符合最佳实践的代码,比处理C语言的API和SQLite容易的多。亦即无需使用SQL语言,而是苹果的NSPredicate。
  2. Realm 数据库的设计哲学的基础之一是现代的应用开发使用的对象。模型就是对象,Realm提供基类Object,继承自NSObject。属性也支持Swift中原始和基本类型,对集合类也进行了封装,纯面向对象编程。

对象:是指面向对象编程中的对象,Object:文中专指Realm中模型的基类Object

img

img

3.如果你偏爱 struct,只需要添加 toStruct()fromStruct(_) 方法到 object,即可快速读取struct的数据。

img


第三章:Object基础和数据类型

数据类型:

  1. 对象类型属性:@objc dynamic var 修饰,String、Date、Data,支持可选
  2. 原始类型属性:包含Bool、Int、Float、Double。let allowsPublication = RealmOptional<Bool>() 需要使用Realm封装的可选类型
  3. 自定义类型:比如封装CLLocation、封装枚举值

img

属性速查表

img

Object支持还以下几个属性:

  1. 计算属性
  2. 主键:在移动应用使用自增主键不是一个好主意,尤其是使用Realm。
  3. 索引:谨慎的使用索引,仅在反复查询的属性上使用。
  4. 忽略属性

@objcMembers 修饰 Object,是非常适合使用的一个场景。


第四章:模式和关系

  1. 对一
  2. 对多(Object):使用List,和Swift中Array类似
  3. 对多(Value):
  4. 反向关系:LinkingObjects

第五章:读写

查询结果(Results)

Results 是一个惰性抓取持久化数据的API。

过滤结果:使用NSPredicate

  1. 子查询谓词(Sub-query predicates)

img

  1. 谓词速查表

img

img

排序结果:单属性排序 .sorted(byKeyPath: “firstName”) 和多个属性排序

img

写入数据时:因为存储Object包括修改属性,都会修改硬盘文件,必须进行写入事务。


第六章:通知和响应式应用

更改的通知

Realm 的核心特征之一就是数据永不过时的理念。

通知三个级别:

  1. Object
  2. Collection:list、results、linking objects
  3. Realm

通知的细节:

  1. 线程:通知回调在和订阅通知相同线程被调用。
  2. Run loop:Realm使用 run loop 发送更改通知。因此你只能在有 run loop的线程订阅通知。
  3. 通知的间隔尺度(granularity):Realm在每次成功写入事务后推送通知给观察者。因为推送使用的是订阅线程的run loop(可能有时候忙于其它事情),可能会在Realm发生了其它更改才送达。这种情况下,Realm会聚集所有更改一起推送通知。
  4. 仅限持久化的 Object
  5. 通知令牌(Notification tokens):手动invalidate()或者在内存中释放(View Controller 被释放)

响应式应用

响应式系统拥有以下几个关键特性:对发生的变化做出反应,使用基于消息的工作流程,具有扩展能力等等。Realm 都提供了完整的支持。

该书对IB的讲解还是比较全面详细,建议大家读读,也算是差缺补漏。以下是我的一些笔记。

  1. xib 固化为 nib,storyboard 固化为 storyboardc。
  2. IB文件冲突,Open source 的方式查看和编辑。
  3. 同一个sb文件中的不同的VC都应该设置一个不同的StoryboardID与之对应
  4. App 启动过程,手动新建 main.swift 即可编辑修改。
  5. IB文件的 Target Membership的作用:当工程的某个Target被编译,只有IB文件中该Target被勾选,才会被序列化为对应的nib或storyboardc文件,并存放在该Target对应的Bundle中。
  6. Custom Class -> Module 标签是针对Swift设计的,代表命名空间。
  7. Document -> Label 给每个控件起一个简短的名字。
  8. IB使用Auto Layout,根据实时反馈机制,发现问题解决问题。

直接可以参考官方的文档即可: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个。

0%