Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Statically-typed Swifty APIs
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Radek Pietruszewski
September 15, 2016
Programming
98
0
Share
Statically-typed Swifty APIs
A talk from NSSpain 2016
Radek Pietruszewski
September 15, 2016
More Decks by Radek Pietruszewski
See All by Radek Pietruszewski
Dependent Types
radex
0
44
Other Decks in Programming
See All in Programming
「なんか〇〇ライブラリで脆弱性あるみたいなんだけど。。。」から始める脆弱性対応 / First Steps in Vulnerability Response
mackey0225
2
120
JCON - Create Agentic AI Apps, The Easy Way!
kdubois
1
110
AlarmKitで明後日起きれるアラームアプリを作る
trickart
0
130
Lightning-Fast Method Calls with Ruby 4.1 ZJIT / RubyKaigi 2026
k0kubun
3
3k
ハーネスエンジニアリングにどう向き合うか 〜ルールファイルを超えて開発プロセスを設計する〜 / How to approach harness engineering
rkaga
28
22k
ソフトウェア設計の結合バランス #phperkaigi
kajitack
0
510
GitHubCopilotCLIをはじめよう.pdf
htkym
0
330
AI時代になぜ書くのか
mutsumix
0
390
[RubyKaigi 2026] Require Hooks
palkan
1
320
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
330
Structured Concurrency, Scoped Values and Joiners in the JDK 25 26 27
josepaumard
1
150
なぜあなたのコードには「コシ」がないのか?〜AI時代に問う、最後まで美味しい設計と戦略〜 #phpconkagawa / phpconkagawa2026
shogogg
0
200
Featured
See All Featured
Highjacked: Video Game Concept Design
rkendrick25
PRO
1
350
Ethics towards AI in product and experience design
skipperchong
2
270
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
270
Kristin Tynski - Automating Marketing Tasks With AI
techseoconnect
PRO
0
240
Building a Scalable Design System with Sketch
lauravandoore
463
34k
Claude Code のすすめ
schroneko
67
220k
Visualization
eitanlees
151
17k
We Analyzed 250 Million AI Search Results: Here's What I Found
joshbly
1
1.3k
Design in an AI World
tapps
1
210
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
62k
Side Projects
sachag
455
43k
Deep Space Network (abreviated)
tonyrice
0
140
Transcript
Statically-typed Swifty APIs Radek Pietruszewski @radexp • radex.io
@radexp • radex.io Dynamic vs static
@radexp • radex.io Modern static typing
@radexp • radex.io
@radexp • radex.io NSUserDefaults Case study
@radexp • radex.io NSUserDefaults.standardUserDefaults() .stringForKey("color") NSUserDefaults.standardUserDefaults() .setObject(NSDate(), forKey: "updatedAt")
@radexp • radex.io let Defaults = NSUserDefaults.standardUserDefaults() Defaults.integer(forKey: "launchCount") #Courage
@radexp • radex.io Defaults.integer(forKey: "launchCount") Defaults.set("red", forKey: "color") let dictionary
= ["launchCount": 10] dictionary["launchCount"] dictionary["color"] = "red"
@radexp • radex.io extension UserDefaults { subscript(key: String) -> AnyObject?
{ get { return object(forKey: key) } set { set(newValue, forKey: key) } } } Defaults["color"] Defaults["color"] = "red"
@radexp • radex.io Defaults["color"] // AnyObject?
@radexp • radex.io Defaults["color"] // AnyObject?
@radexp • radex.io extension UserDefaults { subscript(key: String) -> Proxy
{ return Proxy(self, key) } }
@radexp • radex.io class Proxy { var string: String? {
return defaults.string(forKey: key) } var int: Int { return defaults.integer(forKey: key) } }
@radexp • radex.io Defaults["color"].string Defaults["launchCount"].int
@radexp • radex.io extension UserDefaults { subscript(key: String) -> Any?
{ set { if let v = newValue as? String { set(v, forKey: key) } else if let v = newValue as? Int { set(v, forKey: key) } } } }
@radexp • radex.io Common use cases
@radexp • radex.io Defaults["launchCount"] = Defaults["launchCount"].intValue + 1
@radexp • radex.io Defaults["launchCount"] += 1
@radexp • radex.io func += (proxy: UserDefaults.Proxy, b: Int) {
let a = proxy.defaults[proxy.key].intValue proxy.defaults[proxy.key] = a + b }
@radexp • radex.io postfix func ++ (proxy: UserDefaults.Proxy) { proxy
+= 1 }
@radexp • radex.io Defaults["launchCount"]++
@radexp • radex.io Defaults["launchCount"]++
@radexp • radex.io Defaults["launchCount"] += 1
@radexp • radex.io let defaults = NSUserDefaults.standardUserDefaults() defaults.setInteger( defaults.integerForKey("launchCount") +
1, forKey: "launchCount")
@radexp • radex.io Defaults["launchCount"] += 1
@radexp • radex.io Initial results
@radexp • radex.io Defaults["color"].string Defaults["launchCount"].int ?? 0 Defaults["launchCount"].intValue
@radexp • radex.io Defaults["color"] = "red" Defaults["totalTime"] += 3600
@radexp • radex.io But is this really Swifty?
@radexp • radex.io Defaults["color"] = "red"
@radexp • radex.io Defaults["color"] = "red" Defaults["colour"].string // => nil
@radexp • radex.io Defaults["deadline"] = Date.distantFuture Defaults["deadline"].data // => nil
@radexp • radex.io Defaults["deadline"] = Data() Defaults["deadline"].date // => nil
@radexp • radex.io Defaults["magic"] = 3.14 Defaults["magic"] += 10 Defaults["magic"]
// => 13
@radexp • radex.io Happens all the time!
@radexp • radex.io Fast feedback
@radexp • radex.io Refactoring
@radexp • radex.io The power of static typing
@radexp • radex.io let colorKey = "color"
@radexp • radex.io class DefaultsKey<ValueType> { let key: String }
@radexp • radex.io class DefaultsKey<ValueType> { let key: String }
let colorKey = DefaultsKey<String?>("color")
@radexp • radex.io let colorKey = DefaultsKey<String?>("color") extension UserDefaults {
subscript(key: DefaultsKey<String?>) -> String? { get { return string(forKey: key.key) } set { set(newValue, forKey: key.key) } } }
@radexp • radex.io Defaults[colorKey] = "green" Defaults[colorKey] // => "green"
: String? let colorKey = DefaultsKey<String?>("color")
@radexp • radex.io Defaults[colorKey] = "green" Defaults[colorKey] // => "green"
: String? let colorKey = DefaultsKey<String?>("color")
@radexp • radex.io Subscripts are awesome
@radexp • radex.io var array = [1, 2, 3] array.first!
+= 10
@radexp • radex.io var array = [1, 2, 3] array[0]
+= 10 array // => [11, 2, 3]
@radexp • radex.io var array = [1, 2, 3] array[0]
+= 10 array // => [11, 2, 3]
@radexp • radex.io subscript(...) -> ... { get { ...
} set { ... } }
@radexp • radex.io array[0] += 10
@radexp • radex.io var temp = array[0] temp += 10
array[0] = temp
@radexp • radex.io Defaults[launchCountKey] += 1 Defaults[volumeKey] -= 0.1 Defaults[favoriteColorsKey].append("green")
Defaults[stringKey] += "… can be extended!"
@radexp • radex.io Defaults["color"] Defaults[Keys.color]
@radexp • radex.io Implicit member expressions
@radexp • radex.io turn(Direction.left) turn(.left)
@radexp • radex.io CGRect.zero -> .zero
@radexp • radex.io DefaultsKey.color -> .color
@radexp • radex.io extension DefaultsKeys { static let color =
DefaultsKey<String>("color") }
@radexp • radex.io extension DefaultsKeys { static let color =
DefaultsKey<String>("color") } Defaults[.color] = "red"
@radexp • radex.io Defaults[.color] = "red"
@radexp • radex.io let key = DefaultsKey<[String]>("colors") Defaults[key].append("red") let red
= Defaults[key][0]
@radexp • radex.io extension DefaultsKeys { static let color =
DefaultsKey<NSColor?>("color") } Defaults[.color] // => nil Defaults[.color] = .white Defaults[.color] // => w 1.0, a 1.0 Defaults[.color]?.whiteComponent // => 1.0
@radexp • radex.io Result: SwiftyUserDefaults
@radexp • radex.io extension DefaultsKeys { static let username =
DefaultsKey<String?>("username") static let launchCount = DefaultsKey<Int>("launchCount") static let libraries = DefaultsKey<[String]>("libraries") static let color = DefaultsKey<NSColor?>("color") }
@radexp • radex.io Defaults[.username] Defaults[.username] = "radex" Defaults[.launchCount] // Int,
defaults to 0
@radexp • radex.io Defaults[.launchCount] += 1 Defaults[.volume] -= 0.1 Defaults[.strings]
+= "… can be extended!"
@radexp • radex.io Defaults[.libraries].append("SwiftyUserDefaults") Defaults[.libraries][0] += " 2.0"
@radexp • radex.io Defaults[.color] = .white Defaults[.color]?.whiteComponent // => 1.0
@radexp • radex.io Static typing doesn't hurt in Swift
@radexp • radex.io Small price to opt in
@radexp • radex.io Free gifts from the compiler
@radexp • radex.io Compile-time checks
@radexp • radex.io Autocompletion
@radexp • radex.io Inferred types
@radexp • radex.io Plays nicely with value types
@radexp • radex.io Swifty APIs use static typing
@radexp • radex.io Modern type systems are nice
@radexp • radex.io github.com/radex/ SwiftyUserDefaults