WWDC19

Dec 2, 2019


244: Visual Design Accessibility

  1. Dynamic Type
  2. Reduce Motion
    • 一些人对动态效果感知非常强烈,甚至引起焦虑,需要关闭。
  3. 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

  1. 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

  2. Protocols and generics

  3. 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)
    
  4. 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”

  1. po
    • po is an abbreviation for expression -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
  2. p
    • p is an abbreviation for expression --
    • p Under the Hood: (lldb)p view -> Create compilable code -> Compile -> Execute -> Dynamic type resolution -> Formatter -> Display result string
    • use: Data formatters
  3. v
    • v is an abbreviation for frame variable
    • v Under the Hood: (lldb) v variable -> Examine program state -> Read value from memory -> Dynamic type resolution -> Formatter
    • use: Data formatters
  4. Customizing Data Formatters
    • type filter
    • type summary
  5. Python Formatter, CustomReflectable

707: Advances in App Background Execution

  1. 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
    
  2. New BackgroundTasks Framework

723: Advances in Foundation

  1. Ordered Collection Diffing
  2. Data
    • Contiguity
    • DataProtocol
    • MutableDataProtocol
    • Compression
  3. Units and Formatters
    • RelativeDateTimeFormatter
    • ListFormatter
  4. OperationQueue
    • addBarrierBlock
    • Progress reporting
  5. USB and SMB on iOS
  6. Swift Update
    • Scanner