Understanding Your Toddler
iOSConf 2016
Daniel H Steinberg
@dimsumthinking
Slide 8
Slide 8 text
Understanding Your Toddler
iOSConf 2016
Daniel H Steinberg
@dimsumthinking
Slide 9
Slide 9 text
Understanding Your Toddler
iOSConf 2016
Daniel H Steinberg
@dimsumthinking
No, this is not the same talk I gave last week at UIKonf
Slide 10
Slide 10 text
Summer 2010
Slide 11
Slide 11 text
No content
Slide 12
Slide 12 text
No content
Slide 13
Slide 13 text
Summer 2010
Slide 14
Slide 14 text
Xcode 4 shipped
Slide 15
Slide 15 text
Xcode IB
Slide 16
Slide 16 text
No content
Slide 17
Slide 17 text
18 months
Slide 18
Slide 18 text
No content
Slide 19
Slide 19 text
Xcode 4.2
Slide 20
Slide 20 text
LLVM Only
Slide 21
Slide 21 text
iOS 5
Slide 22
Slide 22 text
ARC
Slide 23
Slide 23 text
WWDC 2014
Slide 24
Slide 24 text
No content
Slide 25
Slide 25 text
Swift 1.0
Slide 26
Slide 26 text
Swift 1.1
Slide 27
Slide 27 text
Swift 1.2
Slide 28
Slide 28 text
WWDC 2015
Slide 29
Slide 29 text
"Swift will be open sourced
by the end of this year"
Slide 30
Slide 30 text
December 3, 2015
Slide 31
Slide 31 text
No content
Slide 32
Slide 32 text
No content
Slide 33
Slide 33 text
Proposals from the Community
Slide 34
Slide 34 text
PRs from the Community
Slide 35
Slide 35 text
Committers
Slide 36
Slide 36 text
Conversation
Slide 37
Slide 37 text
Swift Evolution
Slide 38
Slide 38 text
Open
Slide 39
Slide 39 text
Swift 3
Slide 40
Slide 40 text
"We have had a focus on
getting to source stability"
Slide 41
Slide 41 text
Swift 3
focus on source stability
Slide 42
Slide 42 text
API design guidelines
Focus and refine the language
Adoption of naming guidelines in key APIs
Automatic application of naming
guidelines to imported Objective-C APIs
Swiftification of imported Objective-C APIs
Improvements to tooling quality
Slide 43
Slide 43 text
API design guidelines
Focus and refine the language
Adoption of naming guidelines in key APIs
Automatic application of naming
guidelines to imported Objective-C APIs
Swiftification of imported Objective-C APIs
Improvements to tooling quality
Slide 44
Slide 44 text
API design guidelines
Focus and refine the language
Adoption of naming guidelines in key APIs
Automatic application of naming
guidelines to imported Objective-C APIs
Swiftification of imported Objective-C APIs
Improvements to tooling quality
Slide 45
Slide 45 text
API design guidelines
Focus and refine the language
Adoption of naming guidelines in key APIs
Automatic application of naming
guidelines to imported Objective-C APIs
Swiftification of imported Objective-C APIs
Improvements to tooling quality
Slide 46
Slide 46 text
API design guidelines
Focus and refine the language
Adoption of naming guidelines in key APIs
Automatic application of naming
guidelines to imported Objective-C APIs
Swiftification of imported Objective-C APIs
Improvements to tooling quality
Slide 47
Slide 47 text
API design guidelines
Focus and refine the language
Adoption of naming guidelines in key APIs
Automatic application of naming
guidelines to imported Objective-C APIs
Swiftification of imported Objective-C APIs
Improvements to tooling quality
Slide 48
Slide 48 text
Swift 3
focus on source stability
Slide 49
Slide 49 text
A Few Previews of
Coming Attractions
Slide 50
Slide 50 text
0025 - Scoped Access Levels
Slide 51
Slide 51 text
public
internal
private
Slide 52
Slide 52 text
public
internal
private
Slide 53
Slide 53 text
public
internal
private
Slide 54
Slide 54 text
public
internal
private
Slide 55
Slide 55 text
public
internal
fileprivate
Slide 56
Slide 56 text
public
internal
fileprivate
private
Slide 57
Slide 57 text
class MyClass {
private var myProperty = "Hello"
private func myPrivateMethod() {
print(myProperty)
}
fileprivate func myFilePrivateMethod(numberOfTimes times: Int) {
for _ in 1 ... times {
myPrivateMethod()
}
}
}
extension MyClass {
func myExtensionMethod(numberOfTimes times: Int) {
myFilePrivateMethod(numberOfTimes: times)
}
}
Slide 58
Slide 58 text
class MyClass {
private var myProperty = "Hello"
private func myPrivateMethod() {
print(myProperty)
}
fileprivate func myFilePrivateMethod(numberOfTimes times: Int) {
for _ in 1 ... times {
myPrivateMethod()
}
}
}
extension MyClass {
func myExtensionMethod(numberOfTimes times: Int) {
myFilePrivateMethod(numberOfTimes: times)
}
}
Slide 59
Slide 59 text
class MyClass {
private var myProperty = "Hello"
private func myPrivateMethod() {
print(myProperty)
}
fileprivate func myFilePrivateMethod(numberOfTimes times: Int) {
for _ in 1 ... times {
myPrivateMethod()
}
}
}
extension MyClass {
func myExtensionMethod(numberOfTimes times: Int) {
myFilePrivateMethod(numberOfTimes: times)
}
}
Slide 60
Slide 60 text
class MyClass {
private var myProperty = "Hello"
private func myPrivateMethod() {
print(myProperty)
}
fileprivate func myFilePrivateMethod(numberOfTimes times: Int) {
for _ in 1 ... times {
myPrivateMethod()
}
}
}
extension MyClass {
func myExtensionMethod(numberOfTimes times: Int) {
myFilePrivateMethod(numberOfTimes: times)
}
}
Slide 61
Slide 61 text
class MyClass {
private var myProperty = "Hello"
private func myPrivateMethod() {
print(myProperty)
}
fileprivate func myFilePrivateMethod(numberOfTimes times: Int) {
for _ in 1 ... times {
myPrivateMethod()
}
}
}
extension MyClass {
func myExtensionMethod(numberOfTimes times: Int) {
myFilePrivateMethod(numberOfTimes: times)
}
}
Slide 62
Slide 62 text
public
internal
fileprivate
private
Slide 63
Slide 63 text
0004 - Remove ++ and —
Slide 64
Slide 64 text
while count < upperLimit {
print( myArray[count++])
}
Slide 65
Slide 65 text
while count < upperLimit {
print( myArray[count++])
}
func noEscape(@noescape f: () -> ()) {}
func example(inout x: Int) {
noEscape { _ = x }
}
safe because @noescape => closure
can't be called after function returns
func escape(f: () -> ()) {}
func example(inout x: Int) {
escape {[x] in _ = x }
}
Slide 99
Slide 99 text
func escape(f: () -> ()) {}
func example(inout x: Int) {
escape {[x] in _ = x }
}
[x] is a capture list a constant is
initialized to have the value of x
Slide 100
Slide 100 text
0049 - Move @noescape and @autoclosure
to be type attributes
Slide 101
Slide 101 text
func noEscape(@noescape f: () -> ()) {}
Slide 102
Slide 102 text
func noEscape(f: @noescape () -> ()) {}
Slide 103
Slide 103 text
func noEscape(f: @autoclosure () -> ()) {}
Slide 104
Slide 104 text
0002 - Remove currying func
declaration syntax
Slide 105
Slide 105 text
0002 - Remove currying func
declaration syntax
Slide 106
Slide 106 text
0002 - Remove currying func
declaration syntax
Slide 107
Slide 107 text
func curried(x: Int)(y: Int) -> Int {
return {(y: Int) -> Int in
return x * y
}
}
curried(7)(8)
Slide 108
Slide 108 text
func curried(x: Int)(y: Int) -> Int {
return {(y: Int) -> Int in
return x * y
}
}
curried(7)(8)
Slide 109
Slide 109 text
func curried(x: Int)(y: Int) -> Int {
return {(y: Int) -> Int in
return x * y
}
}
curried(7)(8)
Slide 110
Slide 110 text
func curried(x: Int)(y: Int) -> Int {
return {(y: Int) -> Int in
return x * y
}
}
curried(7)(8)
Slide 111
Slide 111 text
func curried(x: Int)(y: Int) -> Int {
return {(y: Int) -> Int in
return x * y
}
}
curried(7)(8)
7 * y
Slide 112
Slide 112 text
func curried(x: Int)(y: Int) -> Int {
return {(y: Int) -> Int in
return x * y
}
}
curried(7)(8)
7 * 8
Slide 113
Slide 113 text
func curried(x: Int)(y: Int) -> Int {
return {(y: Int) -> Int in
return x * y
}
}
curried(7)(8)
Slide 114
Slide 114 text
func curried(x: Int)(y: Int) -> Int {
return {(y: Int) -> Int in
return x * y
}
}
curried(7)(8)
Slide 115
Slide 115 text
func curried(x: Int)(y: Int) -> Int {
return {(y: Int) -> Int in
return x * y
}
}
curried(7)(8)
Slide 116
Slide 116 text
func curried(x: Int) -> (y: Int) -> Int {
return {(y: Int) -> Int in
return x * y
}
}
curried(7)(8)
Slide 117
Slide 117 text
func curried(x: Int) -> (y: Int) -> Int {
return {(y: Int) -> Int in
return x * y
}
}
curried(7)(8)
Slide 118
Slide 118 text
func curried(x: Int) -> (y: Int) -> Int {
return {(y: Int) -> Int in
return x * y
}
}
curried(7)(8)
Slide 119
Slide 119 text
func curried(x: Int) -> (y: Int) -> Int {
return {(y: Int) -> Int in
return x * y
}
}
curried(7)(8)
Slide 120
Slide 120 text
func curried(x: Int) -> (y: Int) -> Int {
return {(y: Int) -> Int in
return x * y
}
}
curried(7)(8)
Slide 121
Slide 121 text
Testing
Slide 122
Slide 122 text
Playgrounds
Slide 123
Slide 123 text
Package Manager
Slide 124
Slide 124 text
Objective-C
Slide 125
Slide 125 text
0022 - Referencing the Obj-C
selector of a method
Slide 126
Slide 126 text
class MyClass : NSObject {
func callbackMethod(with notification: NSNotification){}
func setNotification() {
let center = NSNotificationCenter.defaultCenter()
center
.addObserver(self,
selector: "callbackMethod",
name: NSApplicationWillResignActiveNotification,
object: NSApplication.sharedApplication())
}
}
Slide 127
Slide 127 text
class MyClass : NSObject {
func callbackMethod(with notification: NSNotification){}
func setNotification() {
let center = NSNotificationCenter.defaultCenter()
center
.addObserver(self,
selector: "callbackMethod",
name: NSApplicationWillResignActiveNotification,
object: NSApplication.sharedApplication())
}
}
Slide 128
Slide 128 text
class MyClass : NSObject {
func callbackMethod(with notification: NSNotification){}
func setNotification() {
let center = NSNotificationCenter.defaultCenter()
center
.addObserver(self,
selector: "callbackMethod",
name: NSApplicationWillResignActiveNotification,
object: NSApplication.sharedApplication())
}
}
Slide 129
Slide 129 text
class MyClass : NSObject {
func callbackMethod(with notification: NSNotification){}
func setNotification() {
let center = NSNotificationCenter.defaultCenter()
center
.addObserver(self,
selector: "callbackMethod",
name: NSApplicationWillResignActiveNotification,
object: NSApplication.sharedApplication())
}
}
Slide 130
Slide 130 text
class MyClass : NSObject {
func callbackMethod(with notification: NSNotification){}
func setNotification() {
let center = NSNotificationCenter.defaultCenter()
center
.addObserver(self,
selector: "callbackMethod",
name: NSApplicationWillResignActiveNotification,
object: NSApplication.sharedApplication())
}
}
Slide 131
Slide 131 text
class MyClass : NSObject {
func callbackMethod(with notification: NSNotification){}
func setNotification() {
let center = NSNotificationCenter.defaultCenter()
center
.addObserver(self,
selector: "callbackMethod",
name: NSApplicationWillResignActiveNotification,
object: NSApplication.sharedApplication())
}
}
Slide 132
Slide 132 text
class MyClass : NSObject {
func callbackMethod(with notification: NSNotification){}
func setNotification() {
let center = NSNotificationCenter.defaultCenter()
center
.addObserver(self,
selector: #selector(callbackMethod),
name: NSApplicationWillResignActiveNotification,
object: NSApplication.sharedApplication())
}
}
Slide 133
Slide 133 text
class MyClass : NSObject {
func callbackMethod(with notification: NSNotification){}
func setNotification() {
let center = NSNotificationCenter.defaultCenter()
center
.addObserver(self,
selector: #selector(MyClass.callbackMethod),
name: NSApplicationWillResignActiveNotification,
object: NSApplication.sharedApplication())
}
}
Slide 134
Slide 134 text
class MyClass : NSObject {
func callbackMethod(){}
func callbackMethod(with notification: NSNotification){}
func setNotification() {
let center = NSNotificationCenter.defaultCenter()
center
.addObserver(self,
selector: #selector(MyClass.callbackMethod),
name: NSApplicationWillResignActiveNotification,
object: NSApplication.sharedApplication())
}
}
Slide 135
Slide 135 text
class MyClass : NSObject {
func callbackMethod(){}
func callbackMethod(with notification: NSNotification){}
func setNotification() {
let center = NSNotificationCenter.defaultCenter()
center
.addObserver(self,
selector: #selector(MyClass.callbackMethod),
name: NSApplicationWillResignActiveNotification,
object: NSApplication.sharedApplication())
}
}
Slide 136
Slide 136 text
class MyClass : NSObject {
func callbackMethod(){}
func callbackMethod(with notification: NSNotification){}
func setNotification() {
let center = NSNotificationCenter.defaultCenter()
center
.addObserver(self,
selector: #selector(MyClass.callbackMethod(with:)),
name: NSApplicationWillResignActiveNotification,
object: NSApplication.sharedApplication())
}
}
enum Currency {
case Dollars
case Euros
case Pounds
case Yen
}
Lower case imported types
Slide 173
Slide 173 text
enum Currency {
case Dollars
case Euros
case Pounds
case Yen
}
Lower case imported types
Slide 174
Slide 174 text
enum Currency {
case dollars
case euros
case pounds
case yen
}
Lower case imported types
Slide 175
Slide 175 text
0036 - Requiring Leading Dot Prefixes for
Enum Instance Member Implementations
Slide 176
Slide 176 text
enum Currency {
case dollars
case euros
case pounds
case yen
var symbol: String {
switch self {
case dollars:
return "$"
default:
return "I don't know"
}
}
}
Slide 177
Slide 177 text
enum Currency {
case dollars
case euros
case pounds
case yen
var symbol: String {
switch self {
case .dollars:
return "$"
default:
return "I don't know"
}
}
}
Slide 178
Slide 178 text
enum Currency {
case dollars
case euros
case pounds
case yen
var symbol: String {
switch self {
case dollars:
return "$"
default:
return "I don't know"
}
}
}
Slide 179
Slide 179 text
enum Currency {
case dollars
case euros
case pounds
case yen
var symbol: String {
switch self {
case .dollars:
return "$"
default:
return "I don't know"
}
}
}
Slide 180
Slide 180 text
enum Currency {
case dollars
case euros
case pounds
case yen
var symbol: String {
switch self {
case .dollars:
return "$"
default:
return "I don't know"
}
}
}
Slide 181
Slide 181 text
0043 - Declare variables in 'case' labels
with multiple patterns
Slide 182
Slide 182 text
enum MyEnum {
case case1(Int,Float)
case case2(Float,Int)
}
switch value {
case let .case1(x, 2), let .case2(2, x):
print(x)
case .case1, .case2:
break
}
Slide 183
Slide 183 text
enum MyEnum {
case case1(Int,Float)
case case2(Float,Int)
}
switch value {
case let .case1(x, 2), let .case2(2, x):
print(x)
case .case1, .case2:
break
}
Slide 184
Slide 184 text
enum MyEnum {
case case1(Int,Float)
case case2(Float,Int)
}
switch value {
case let .case1(x, 2), let .case2(2, x):
print(x)
case .case1, .case2:
break
}
Slide 185
Slide 185 text
enum MyEnum {
case case1(Int,Float)
case case2(Float,Int)
}
switch value {
case let .case1(x, 2), let .case2(2, x):
print(x)
case .case1, .case2:
break
}
Slide 186
Slide 186 text
enum MyEnum {
case case1(Int,Float)
case case2(Float,Int)
}
switch value {
case let .case1(x, 2), let .case2(2, x):
print(x)
case .case1, .case2:
break
}
Slide 187
Slide 187 text
enum MyEnum {
case case1(Int,Float)
case case2(Float,Int)
}
switch value {
case let .case1(x, 2), let .case2(2, x):
print(x)
case .case1, .case2:
break
}
Slide 188
Slide 188 text
enum MyEnum {
case case1(Int,Float)
case case2(Float,Int)
}
switch value {
case let .case1(x, 2), let .case2(2, x):
print(x)
case .case1, .case2:
break
}
Slide 189
Slide 189 text
0001 - Allow (most) keywords
as argument labels
Slide 190
Slide 190 text
calculateRevenue(for sales: Int,
in currency: Currency)
Slide 191
Slide 191 text
calculateRevenue(for sales: Int,
in currency: Currency)
Slide 192
Slide 192 text
calculateRevenue(for numberOfCopies,
in .dollars)
Slide 193
Slide 193 text
0009 - Require self for accessing
instance members
Slide 194
Slide 194 text
struct Friend {
let name: String
let location: String
func nameBadge() {
print("I'm", name,
"from", location)
}
}
Slide 195
Slide 195 text
struct Friend {
let name: String
let location: String
func nameBadge() {
print("I'm", name,
"from", location)
}
}
Slide 196
Slide 196 text
struct Friend {
let name: String
let location: String
func nameBadge() {
print("I'm", name,
"from", location)
}
}
Slide 197
Slide 197 text
struct Friend {
let name: String
let location: String
func nameBadge() {
print("I'm", self.name,
"from", self.location)
}
}
Slide 198
Slide 198 text
struct Friend {
let name: String
let location: String
func nameBadge() {
print("I'm", self.name,
"from", self.location)
}
}
Require self for accessing
instance members
REJECTED
Slide 199
Slide 199 text
0011 - Replace typealias keyword with
associatedtype for associated type
declarations
Slide 200
Slide 200 text
0011 - Replace typealias keyword with
associatedtype for associated type
declarations