Auto-defaulting ObjC Arguments

My recent post about Objective-C name pruning in Swift 3 garnered some lovely  feedback. I thought I’d throw up a few more posts about the big 3 proposals and SE-0005 in particular, and how automatic translations of ObjC APIs will affect Cocoa use in Swift.

Of the upcoming changes, auto-defaulting is probably my favorite part of the SE-0005 proposal. Among its other automated changes like pruning, SE-0005 introduces rules that allow imported APIs to default many arguments, enabling you to skip parameters when calling from Swift.

Any method that matches one of the following patterns will now provide default values:

  • Trailing closures: nullable closure parameters will default to nil.
  • NSZones: nullable zones also default to nil. (The proposal notes that they should always be nil to begin with as they are unused in Swift.)
  • Option sets: Any type name containing the word `Options` defaults to [], the empty option set.
  • Dictionaries: NSDictionary parameters with names including `options`, `attributes`, and `info` default to [:], the empty dictionary.

This translation excludes single-parameter setters so `setCompletionHandler: value` and `setOptions: value` aren’t affected by these rules.  Otherwise, the upshot of these rules means that a call like this:

    animated: true, 
    completion: nil)
    0.2, delay: 0.0, options: [], 
    animations: { self.logo.alpha = 0.0 }) { 
        _ in self.logo.hidden = true 

simplifies to this in Swift 3:

rootViewController.present(alert, animated: true)
UIView.animateWithDuration(0.2, delay: 0.0, 
    animations: { self.logo.alpha = 0.0 }) {
        _ in self.logo.hidden = true 

This automated default introduction has the greatest impact on completion handlers, user info dictionaries, attribute dictionaries (for example when working with `NSFileManager` and `NSAttributedString`), and option groups (like AVFoundation’s `AVMusicSequenceLoadOptions`, `AudioComponentInstantiationOptions`, and `AVMovieWritingOptions`).

The result is a much cleaner Swift, where you choose when to introduce customization on calls instead of reflexing populating them with “opt-out” values like nil and `[]` and `[:]`. View side-by-side examples of these changes here, by searching for “= nil”, “= []”, and “= [:]” on the green right Swift 3 side.


  • UIView.animate(duration: 0.2, delay: 0.0,
    animations: { self.logo.alpha = 0.0 }) {
    _ in self.logo.hidden = true

    would make more sense to me

    • Same for me, `present(viewController: xxx)` since all parameters aim to be named in Swift 3 unless I’m wrong.