- 244: Visual Design Accessibility
- 413: Testing in Xcode
- 415: Modern Swift API Design
- 429: LLDB: Beyond “po”
- 707: Advances in App Background Execution
- 723: Advances in Foundation
244: Visual Design Accessibility
- Dynamic Type
- Reduce Motion
- 一些人对动态效果感知非常强烈,甚至引起焦虑,需要关闭。
- Differentiate Without Color
- 针对色盲用户
413: Testing in Xcode
- Test Plans
- Continuous integration workflows
$ xcodebuild build-for-testing $ xcodebuild test-without-building $ xcodebuild -project ... -scheme ... -showTestPlans $ xcodebuild test -project ... -scheme ... -testPlan 'Smoke Tests' $ man xcodebuild.xctestrun $ xcodebuild test -project MyProject.xcodeproj -scheme MyScheme -resultBundlePath /path/to/ResultBundle.xcresult $ xcrun xcresulttool get --path ResultBundle.xcresult --format json $ xcrun xcresulttool formatDescription get $ man xcresulttool $ xcrun xccov view --report ResultBundle.xcresult
415: Modern Swift API Design
- Values and references
Choosing — Reference or Value?
Prefer structs over classes
• Only choose classes when reference semantics are important
Classes can make a good choice when
• You need a reference counting and deinitialization
• The value is held centrally and shared
• Where there is a separate notion of “identity” from “equality”
• Only choose classes when reference semantics are important
-
Protocols and generics
- Key path member lookup
- Swift Evolution: SE-0252
- @dynamicMemberLookup
class Texture: NSObject { var isSparkly: Bool = true } @dynamicMemberLookup struct DynamicStruct { private var _texture: Texture = .init() subscript<T>(dynamicMember keyPath: ReferenceWritableKeyPath<Texture, T>) -> T { get { _texture[keyPath: keyPath] } set { if !isKnownUniquelyReferenced(&_texture) { _texture = _texture.copy() as! Texture } _texture[keyPath: keyPath] = newValue } } } let m = DynamicStruct() print(m.isSparkly)
- Property wrappers
- Swift Evolution: SE-0258
- @LateInitialized, @DefensiveCopying
@propertyWrapper struct UserDefault<T> { let key: String let defaultValue: T var wrappedValue: T { get { return UserDefaults.standard.object(forKey: key) as? T ?? defaultValue } set { UserDefaults.standard.set(newValue, forKey: key) } } } enum GlobalSettings { @UserDefault(key: "FOO_FEATURE_ENABLED", defaultValue: false) static var isFooFeatureEnabled: Bool /* Compiler-synthesized code... static var $isFooFeatureEnabled: UserDefault<Bool> = UserDefault<Bool>(key: "FOO_FEATURE_ENABLED", defaultValue: false) static var isFooFeatureEnabled: Bool { get { $isFooFeatureEnabled.wrappedValue } set { $isFooFeatureEnabled.wrappedValue = newValue } } */ }
429: LLDB: Beyond “po”
- po
po
is an abbreviation forexpression -O --
po
Under the Hood: (lldb)po view -> Create compilable code -> Compile -> Execute -> Create code to access description -> Compile -> Execute -> Get string result -> Display result string- use: Object description
- p
p
is an abbreviation forexpression --
p
Under the Hood: (lldb)p view -> Create compilable code -> Compile -> Execute -> Dynamic type resolution -> Formatter -> Display result string- use: Data formatters
- v
v
is an abbreviation forframe variable
v
Under the Hood: (lldb) v variable -> Examine program state -> Read value from memory -> Dynamic type resolution -> Formatter- use: Data formatters
- Customizing Data Formatters
- type filter
- type summary
- Python Formatter, CustomReflectable
707: Advances in App Background Execution
- Different Use Cases(后台用例)
//Gives app additional time to run in the background before being suspended UIApplication.beginBackgroundTask(expirationHandler:) //静默推送, Must set apns-priority = 5 or app will not launch //Should set apns-push-type = background Muted Threads/Background push //Background fetch UIApplication.setMinimumBackgroundFetchInterval(_:) UIApplicationDelegate.application(_:performFetchWithCompletionHandler:) //Discretionary Background URL Session let config = URLSessionConfiguration.background(withIdentifier: "com.app.attachments") let session = URLSession(configuration: config, delegate: ..., delegateQueue: ...) //Phone Calls VoIP push notifications
- New BackgroundTasks Framework
723: Advances in Foundation
- Ordered Collection Diffing
- Data
- Contiguity
- DataProtocol
- MutableDataProtocol
- Compression
- Units and Formatters
- RelativeDateTimeFormatter
- ListFormatter
- OperationQueue
- addBarrierBlock
- Progress reporting
- USB and SMB on iOS
- Swift Update
- Scanner