Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Daniel Steinberg: The Open World of Swift 3
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Realm
April 25, 2016
Programming
25k
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Daniel Steinberg: The Open World of Swift 3
Realm
April 25, 2016
More Decks by Realm
See All by Realm
WWDC 2017 Review
realm
0
2.2k
Xcode shortcuts
realm
0
4.8k
Self Branding with GitHub
realm
0
4.4k
Realm Mobile Platform overview and demo
realm
0
2.1k
Realm advanced topics and demo
realm
0
2k
Realm introduction Seoul meetup 10
realm
0
2.2k
Stuart Hall: How I got 2.3 Million App Downloads
realm
0
2k
James Majors: What the Swiftly Func?
realm
1
4.3k
Simina Pasat: Continuous everything for iOS apps
realm
0
670
Other Decks in Programming
See All in Programming
【DroidKaigi 2026】「アクセシビリティを利用するとき、 アクセシビリティもまたこちらを利用している」 〜マルウェアによる攻撃と防衛について〜
halunoyo
0
450
WebMCP Challenge に星空観察アプリで参加した話
okajun35
0
140
AWS Step Functions 大規模並列の壁を越える / jaws-sonic-2026-niigata-step-functions
kasacchiful
PRO
1
440
Vibes Containers 〜AIで変わるコンテナ設計と運用〜
tkikuc
3
530
XHTMLが残したもの
yosuke_furukawa
PRO
2
700
モバイル交通系ICへのチャージ実例から考える、クロスプラットフォーム開発におけるiOS実機テスト設計とCI運用
yusuga
1
350
AI × TiDD / 2026.09.05 Redmine 大阪
tokudiro
1
120
AIエージェント時代のコードレビューを設計する
nogu66
6
2.6k
Claude Codeを組織的に動かして月400PRを実現した話
happy_ryo
0
270
go-spidermonkeyでAIエージェントのCode Modeを実装する
syumai
3
1.5k
App Storeの外へ──日本のiOSサイドローディング入門 for iOSDC Japan 2026
yuukiw00w
0
180
App Intentsのビルドプロセスを支える技術
kntkymt
0
260
Featured
See All Featured
Context Engineering - Making Every Token Count
addyosmani
9
1.1k
Utilizing Notion as your number one productivity tool
mfonobong
4
590
Large-scale JavaScript Application Architecture
addyosmani
515
110k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
49
10k
What’s in a name? Adding method to the madness
productmarketing
PRO
24
4.2k
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
520
Jess Joyce - The Pitfalls of Following Frameworks
techseoconnect
PRO
1
410
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
2
4.3k
Rebuilding a faster, lazier Slack
samanthasiow
85
9.6k
Reality Check: Gamification 10 Years Later
codingconduct
0
2.3k
A brief & incomplete history of UX Design for the World Wide Web: 1989–2019
jct
2
500
AI Search: Implications for SEO and How to Move Forward - #ShenzhenSEOConference
aleyda
1
1.4k
Transcript
The Open World of Swift 3 AppBuilders 2016 Daniel H
Steinberg @dimsumthinking
Swift
Open
Open?
Open!
Future
Future?
Future!
What can we see?
0025 - Scoped Access Levels
public internal private
public internal private
public internal private
public internal private
public internal fileprivate
public internal fileprivate private
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) { myInternalMethod(numberOfTimes: times) } }
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) { myInternalMethod(numberOfTimes: times) } }
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) { myInternalMethod(numberOfTimes: times) } }
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) { myInternalMethod(numberOfTimes: times) } }
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) { myInternalMethod(numberOfTimes: times) } }
public internal fileprivate private
0004 - Remove ++ and —
while count < upperLimit { print( myArray[count++]) }
while count < upperLimit { print( myArray[count++]) }
while count < upperLimit { print( myArray[count]) count += 1
}
0007 - Remove C Style for loops with conditions and
incrementors
for (int i = 0; i < array.count; i++)
for (int i = 0; i < array.count; i++)
0053 - Remove explicit use of let from Function Parameters
func double(input: Int) -> Int { // ... }
func double(let input: Int) -> Int { // ... }
func double(let input: Int) -> Int { // ... }
0003 - Remove var from Function Parameters
func double(input: Int) -> Int { input = input *
2 return input }
func double(var input: Int) -> Int { input = input
* 2 return input }
func double(var input: Int) -> Int { input = input
* 2 return input }
func double(input: Int) -> Int { var localInput = input
localInput = localInput * 2 return localInput }
func double(input: Int) -> Int { var localInput = input
localInput = localInput * 2 return localInput }
func double(input: Int) -> Int { var input = input
input = input * 2 return input } Name Shadowing
func double(input: Int) -> Int { var input = input
input = input * 2 return input }
0031 - Adjusting inout Declarations for Type Decoration
func double(input: Int) { input = input * 2 }
func double(inout input: Int) { input = input * 2
}
func double(inout input: Int) { input = input * 2
}
func double(input: inout Int) { input = input * 2
}
0053 - Limiting inout capture to @noescape context
func escape(f: () -> ()) {} func example(inout x: Int)
{ escape { _ = x } }
func escape(f: () -> ()) {} func example(inout x: Int)
{ escape { _ = x } }
func escape(f: () -> ()) {} func example(inout x: Int)
{ escape { _ = x } }
func escape(f: () -> ()) {} func example(inout x: Int)
{ escape { _ = x } }
func escape(f: () -> ()) {} func example(inout x: Int)
{ escape { _ = x } }
func escape(f: () -> ()) {} func example(inout x: Int)
{ escape { _ = x } }
func escape(f: () -> ()) {} func example(inout x: Int)
{ escape { _ = x } }
func noEscape(@noescape f: () -> ()) {} func example(inout x:
Int) { noEscape { _ = x } }
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 } }
func escape(f: () -> ()) {} func example(inout x: Int)
{ escape {[x] in _ = x } }
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
0049 - Move @noescape and @autoclosure to be type attributes
func noEscape(@noescape f: () -> ()) {}
func noEscape(f: @noescape () -> ()) {}
func noEscape(f: @autoclosure () -> ()) {}
0002 - Remove currying func declaration syntax
0002 - Remove currying func declaration syntax
0002 - Remove currying func declaration syntax
func curried(x: Int)(y: Int) -> Int { return {(y: Int)
-> Int in return x * y } } curried(7)(8)
func curried(x: Int)(y: Int) -> Int { return {(y: Int)
-> Int in return x * y } } curried(7)(8)
func curried(x: Int)(y: Int) -> Int { return {(y: Int)
-> Int in return x * y } } curried(7)(8)
func curried(x: Int)(y: Int) -> Int { return {(y: Int)
-> Int in return x * y } } curried(7)(8)
func curried(x: Int)(y: Int) -> Int { return {(y: Int)
-> Int in return x * y } } curried(7)(8) 7 * y
func curried(x: Int)(y: Int) -> Int { return {(y: Int)
-> Int in return x * y } } curried(7)(8) 7 * 8
func curried(x: Int)(y: Int) -> Int { return {(y: Int)
-> Int in return x * y } } curried(7)(8)
func curried(x: Int)(y: Int) -> Int { return {(y: Int)
-> Int in return x * y } } curried(7)(8)
func curried(x: Int)(y: Int) -> Int { return {(y: Int)
-> Int in return x * y } } curried(7)(8)
func curried(x: Int) -> (y: Int) -> Int { return
{(y: Int) -> Int in return x * y } } curried(7)(8)
func curried(x: Int) -> (y: Int) -> Int { return
{(y: Int) -> Int in return x * y } } curried(7)(8)
func curried(x: Int) -> (y: Int) -> Int { return
{(y: Int) -> Int in return x * y } } curried(7)(8)
func curried(x: Int) -> (y: Int) -> Int { return
{(y: Int) -> Int in return x * y } } curried(7)(8)
func curried(x: Int) -> (y: Int) -> Int { return
{(y: Int) -> Int in return x * y } } curried(7)(8)
Testing
Playgrounds
Package Manager
Objective-C
0022 - Referencing the Obj-C selector of a method
class MyClass : NSObject { func callbackMethod(with notification: NSNotification){} func
setNotification() { let center = NSNotificationCenter.defaultCenter() center .addObserver(self, selector: "callbackMethod", name: NSApplicationWillResignActiveNotification, object: NSApplication.sharedApplication()) } }
class MyClass : NSObject { func callbackMethod(with notification: NSNotification){} func
setNotification() { let center = NSNotificationCenter.defaultCenter() center .addObserver(self, selector: "callbackMethod", name: NSApplicationWillResignActiveNotification, object: NSApplication.sharedApplication()) } }
class MyClass : NSObject { func callbackMethod(with notification: NSNotification){} func
setNotification() { let center = NSNotificationCenter.defaultCenter() center .addObserver(self, selector: "callbackMethod", name: NSApplicationWillResignActiveNotification, object: NSApplication.sharedApplication()) } }
class MyClass : NSObject { func callbackMethod(with notification: NSNotification){} func
setNotification() { let center = NSNotificationCenter.defaultCenter() center .addObserver(self, selector: "callbackMethod", name: NSApplicationWillResignActiveNotification, object: NSApplication.sharedApplication()) } }
class MyClass : NSObject { func callbackMethod(with notification: NSNotification){} func
setNotification() { let center = NSNotificationCenter.defaultCenter() center .addObserver(self, selector: "callbackMethod", name: NSApplicationWillResignActiveNotification, object: NSApplication.sharedApplication()) } }
class MyClass : NSObject { func callbackMethod(with notification: NSNotification){} func
setNotification() { let center = NSNotificationCenter.defaultCenter() center .addObserver(self, selector: "callbackMethod", name: NSApplicationWillResignActiveNotification, object: NSApplication.sharedApplication()) } }
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()) } }
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()) } }
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()) } }
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()) } }
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()) } }
0033 - Import Obj-C constants as Swift types
HK_EXTERN NSString * const HKQuantityTypeIdentifierBodyMassIndex; HK_EXTERN NSString * const HKQuantityTypeIdentifierBodyFatPercentage;
HK_EXTERN NSString * const HKQuantityTypeIdentifierHeight; HK_EXTERN NSString * const HKQuantityTypeIdentifierBodyMass; HK_EXTERN NSString * const HKQuantityTypeIdentifierLeanBodyMass;
HK_EXTERN NSString * const HKQuantityTypeIdentifierBodyMassIndex; HK_EXTERN NSString * const HKQuantityTypeIdentifierBodyFatPercentage;
HK_EXTERN NSString * const HKQuantityTypeIdentifierHeight; HK_EXTERN NSString * const HKQuantityTypeIdentifierBodyMass; HK_EXTERN NSString * const HKQuantityTypeIdentifierLeanBodyMass;
enum HKQuantityTypeIdentifier : String { case BodyMassIndex case BodyFatPercentage case
Height case BodyMass case LeanBodyMass }
enum HKQuantityTypeIdentifier : String { case BodyMassIndex case BodyFatPercentage case
Height case BodyMass case LeanBodyMass }
HK_EXTERN NSString * const HKQuantityTypeIdentifierBodyMassIndex; HK_EXTERN NSString * const HKQuantityTypeIdentifierBodyFatPercentage;
HK_EXTERN NSString * const HKQuantityTypeIdentifierHeight; HK_EXTERN NSString * const HKQuantityTypeIdentifierBodyMass; HK_EXTERN NSString * const HKQuantityTypeIdentifierLeanBodyMass;
enum HKQuantityTypeIdentifier : String { case BodyMassIndex case BodyFatPercentage case
Height case BodyMass case LeanBodyMass }
enum HKQuantityTypeIdentifier : String { case BodyMassIndex case BodyFatPercentage case
Height case BodyMass case LeanBodyMass }
0005 - Better translation of Obj-C APIs into Swift
let color = NSColor.blueColor()
let color = NSColor.blueColor()
let color = NSColor.blueColor() Prune redundant type names
let color = NSColor.blue()
rootViewController .presentViewController(alert, animated: true, completion: nil)
rootViewController .presentViewController(alert, animated: true, completion: nil) Add default arguments
rootViewController .presentViewController(alert, animated: true, completion: nil) Nullable trailing closures default
= nil
rootViewController .presentViewController(alert, animated: true)
rootViewController .presentViewController(alert, animated: true) Shouldn't animated default = true
rootViewController.presentViewController(alert)
rootViewController.presentViewController(alert) Prune redundant type names
rootViewController.present(alert)
var empty: Bool
var empty: Bool Prepend "is" to Bools
var isEmpty: Bool
addLineToPoint(myPoint)
addLineToPoint(myPoint) func addLineToPoint(_: CGPoint)
addLineToPoint(myPoint) func addLineToPoint(_: CGPoint) Add first argument labels
addLineToPoint(myPoint) func addLineToPoint(_: CGPoint) Add first argument labels
addLine(to: myPoint) func addLine(to point: CGPoint) Add first argument labels
addLine(to: myPoint) func addLine(to point: CGPoint) Add first argument labels
Add first argument labels
Add first argument labels
var URLHandler
var URLHandler Lower case imported types
var urlHandler Lower case imported types
enum Currency { case Dollars case Euros case Pounds case
Yen } Lower case imported types
enum Currency { case Dollars case Euros case Pounds case
Yen } Lower case imported types
enum Currency { case dollars case euros case pounds case
yen } Lower case imported types
0036 - Requiring Leading Dot Prefixes for Enum Instance Member
Implementations
enum Currency { case dollars case euros case pounds case
yen var symbol: String { switch self { case dollars: return "$" default: return "I don't know" } } }
enum Currency { case dollars case euros case pounds case
yen var symbol: String { switch self { case .dollars: return "$" default: return "I don't know" } } }
enum Currency { case dollars case euros case pounds case
yen var symbol: String { switch self { case dollars: return "$" default: return "I don't know" } } }
enum Currency { case dollars case euros case pounds case
yen var symbol: String { switch self { case .dollars: return "$" default: return "I don't know" } } }
enum Currency { case dollars case euros case pounds case
yen var symbol: String { switch self { case .dollars: return "$" default: return "I don't know" } } }
0043 - Declare variables in 'case' labels with multiple patterns
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 }
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 }
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 }
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 }
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 }
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 }
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 }
0001 - Allow (most) keywords as argument labels
calculateRevenue(for sales: Int, in currency: Currency)
calculateRevenue(for sales: Int, in currency: Currency)
calculateRevenue(for numberOfCopies, in .dollars)
0009 - Require self for accessing instance members
struct Friend { let name: String let location: String func
nameBadge() { print("I'm", name, "from", location) } }
struct Friend { let name: String let location: String func
nameBadge() { print("I'm", name, "from", location) } }
struct Friend { let name: String let location: String func
nameBadge() { print("I'm", name, "from", location) } }
struct Friend { let name: String let location: String func
nameBadge() { print("I'm", self.name, "from", self.location) } }
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
0011 - Replace typealias keyword with associatedtype for associated type
declarations
0011 - Replace typealias keyword with associatedtype for associated type
declarations
protocol Prot { typealias Container : SequenceType } extension Prot
{ typealias Element = Container.Generator.Element }
protocol Prot { typealias Container : SequenceType } extension Prot
{ typealias Element = Container.Generator.Element }
protocol Prot { associatedtype Container : SequenceType } extension Prot
{ typealias Element = Container.Generator.Element }
0046 Establish consistent label behavior across all parameters including first
labels
func increase(ourNumber: Int, delta: Int) -> Int { } increase(6,
delta: 3)
func increase(ourNumber: Int, delta: Int) -> Int { } increase(6,
delta: 3)
func increase(ourNumber: Int, delta: Int) -> Int { } increase(6,
delta: 3)
func increase(ourNumber: Int, delta: Int) -> Int { } increase(6,
delta: 3)
func increase(ourNumber: Int, delta: Int) -> Int { } increase(ourNumber:
6, delta: 3)
func increase(_ ourNumber: Int, delta: Int) -> Int { }
increase(6, delta: 3)
0023 - Swift API Guidelines
Swift API Design Guidelines
myArray.sort()
sort() sorted()
sortInPlace() sort()
sort() sorted()
sort() sorted() Name functions and methods according to their side-effects
x.distance(to: y) i.successor() Those without side-effects should read as noun
phrases
x.sort() x.append(y) Those with side-effects should read as imperative noun
phrases
sort() sorted()/sorting() Use the “ed/ing” rule to name the nonmutating
counterpart of a mutating method
Prefer methods to free functions
Prefer methods to free functions Protocol Extensions in Swift 2
Prefer methods to free functions Protocol Extensions in Swift 2
Except …
min(x, y, z) When there's no obvious self
print(x) When the function is an unconstrained generic
sin(x) When the function is part of the established domain
notation
Methods can share a base name
Methods can share a base name Good when they do
analogous things
Methods can share a base name Not good (tableView!) when
they don't
Choose good parameter names
func move(from startingIndex: Int, to endingIndex: Int) Choose good parameter
names
Take advantage of default values
Take advantage of default values func hello(name: String = "World")
Take advantage of default values init(name: String, hometown: String? =
nil)
Prefer to locate parameters with defaults at the end init(name:
String, hometown: String? = nil)
External Argument Labels func move(from startingIndex: Int, to endingIndex: Int)
move(from: here to: there)
Argument Labels Exceptions
min(number1, number2) Omit labels when arguments can't be distinguished
Double(someInt) Omit labels in full width inits
Double(_ anInt: someInt) Omit labels in full width inits
func move(from startingIndex: Int, to endingIndex: Int) When the preposition
applies to the whole
func moveTo(x: Int, y: Int) When the preposition applies to
the whole
x.removeBoxes(having Length: 12) When the preposition applies to the whole
None
The Open World of Swift 3 AppBuilders 2016 Daniel H
Steinberg @dimsumthinking