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
Swift 5's Custom String Interpolation in Practice
Search
Bas Broek
February 06, 2020
Programming
720
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Swift 5's Custom String Interpolation in Practice
Bas Broek
February 06, 2020
More Decks by Bas Broek
See All by Bas Broek
Roasting Your App's Accessibility
basthomas
0
51
Building an Accessibility Culture, One Step at a Time (Leeds)
basthomas
0
150
Building an Accessibility Culture, One Step at a Time
basthomas
1
120
Building a modern subscription experience on iOS
basthomas
0
220
Not an afterthought: accessibility from start to finish
basthomas
0
170
Accessibility on Apple Platforms: Beyond VoiceOver
basthomas
0
190
No Touch(screen) Required: Voice & Keyboard Accessibility
basthomas
0
190
Dancing with Dinosaurs: Objective-C and Swift Interop
basthomas
0
200
Effective Pull Request Reviews
basthomas
0
450
Other Decks in Programming
See All in Programming
えっ!!コードを読まずに開発を!?
hananouchi
0
220
PHP Application における Kubernetes 内 gRPC 通信
ganchiku
0
510
ビデオ通話が繋がる0.2秒で何が起きているのか
supurazako
2
150
フィードバックで育てるAI開発
kotaminato
1
120
LaravelLive Japan の裏方のすべて — 第188回 PHP勉強会@東京 (2026-06-24)
suguruooki
2
150
才能?センス?知らん、 続けたもん勝ちだ。-- 結婚・出産・癌を越えてなお、私がプロダクトを創り続ける理由
16bitidol
2
880
【やさしく解説 設計編・中級 #1】一つの車に、運転手は一人 ~ある倉庫システムの事例から~
panda728
PRO
0
180
Haskell/Servantを通してWebミドルウェアを捉え直す
pizzacat83
1
600
地域 SRE コミュニティ最前線 - ホンマでっかSRE勉強会
tk3fftk
0
260
「正の参照」と 「負の導出」で組む ハーネスエンジニアリング
cottpan
1
150
トークンをケチるな、設計しろ:GitHub Copilotを賢く使うコンテキスト戦略
ochtum
0
320
Built Our Own Background Agent at LayerX #aidevex_findy
layerx
PRO
4
1.4k
Featured
See All Featured
Facilitating Awesome Meetings
lara
57
7k
Rebuilding a faster, lazier Slack
samanthasiow
85
9.6k
How To Speak Unicorn (iThemes Webinar)
marktimemedia
1
510
What’s in a name? Adding method to the madness
productmarketing
PRO
24
4.1k
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
390
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
38
2.9k
Unlocking the hidden potential of vector embeddings in international SEO
frankvandijk
0
880
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3.5k
Un-Boring Meetings
codingconduct
0
350
Documentation Writing (for coders)
carmenintech
77
5.4k
Balancing Empowerment & Direction
lara
6
1.2k
How STYLIGHT went responsive
nonsquared
100
6.2k
Transcript
Using Swift 5's Custom String Interpolation in Practice @basthomas, Copenhagen
Cocoa, 06-02-2020 1
Who am I • Swift Weekly Brief • Contravariance (stickers)
• RayWenderlich tech editor • iOS Platform at XING @basthomas, Copenhagen Cocoa, 06-02-2020 2
Where do we come from? @basthomas, Copenhagen Cocoa, 06-02-2020 3
! @basthomas, Copenhagen Cocoa, 06-02-2020 4
NSString *name = @"Bas"; [NSString stringWithFormat:@"Hello, %@", name]; [NSString stringWithFormat:@"%.2f",
9.0234]; [NSString stringWithFormat: @"Hello %@, how are you doing this %@? %@", @"Bas", @"evening", @"Great!" ]; @basthomas, Copenhagen Cocoa, 06-02-2020 5
✨ @basthomas, Copenhagen Cocoa, 06-02-2020 6
let name = "Bas" "Hello, \(name)" String(format: "%.2f", 9.0234) //
"Hello \(name), how are you doing this \(timeOfDay)?" @basthomas, Copenhagen Cocoa, 06-02-2020 7
It is very good. @basthomas, Copenhagen Cocoa, 06-02-2020 8
Interlude @basthomas, Copenhagen Cocoa, 06-02-2020 9
Swift Evolution @basthomas, Copenhagen Cocoa, 06-02-2020 10
Multiline String Literals (SE-0168) """ Hello, how are you doing
this \(timeOfDay)? """ @basthomas, Copenhagen Cocoa, 06-02-2020 11
String Literal Delimiters (SE-0200) // before "\"Did you put your
name into the Goblet of Fire, Harry?\" he asked calmly." // after #""Harry! Did you put your name in the Goblet of Fire?!""# @basthomas, Copenhagen Cocoa, 06-02-2020 12
And then... @basthomas, Copenhagen Cocoa, 06-02-2020 13
Custom String Interpolation (aka Fix ExpressibleByStringInterpolation) @basthomas, Copenhagen Cocoa, 06-02-2020
14
Localization @basthomas, Copenhagen Cocoa, 06-02-2020 15
let message: LocalizableString = #"The document "\(name)" could not be
saved."# alert.messageText = String(localized: message) @basthomas, Copenhagen Cocoa, 06-02-2020 16
Errors @basthomas, Copenhagen Cocoa, 06-02-2020 17
extension String.StringInterpolation { mutating func appendInterpolation(_ error: Error) { appendLiteral(error.localizedDescription)
} } fatalError( "Something went wrong: \(ConnectionError.invalidRequest)" ) @basthomas, Copenhagen Cocoa, 06-02-2020 18
Number formatting @basthomas, Copenhagen Cocoa, 06-02-2020 19
extension String.StringInterpolation { mutating func appendInterpolation( number: Double, formatter: NumberFormatter
) { appendInterpolation( ifNotNil: formatter.string(from: NSNumber(value: number)) ) } } let priceFormatter = NumberFormatter() priceFormatter.numberStyle = .currency "\(number: 100.1234, formatter: priceFormatter)" @basthomas, Copenhagen Cocoa, 06-02-2020 20
Logging and privacy @basthomas, Copenhagen Cocoa, 06-02-2020 21
extension String.StringInterpolation { mutating func appendInterpolation(private: String) { #if DEBUG
appendLiteral(`private`) #else appendLiteral("@@@") #endif } } let name = "Bas" let password = "Broek" print("User \(name) has password \(private: password)") @basthomas, Copenhagen Cocoa, 06-02-2020 22
Other instances @basthomas, Copenhagen Cocoa, 06-02-2020 23
"\(properties == nil ? "nil" : String(describing: properties ?? [:]))"
@basthomas, Copenhagen Cocoa, 06-02-2020 24
extension String.StringInterpolation { mutating func appendInterpolation( dictionary: Dictionary<AnyHashable, Any>?, default:
@autoclosure () -> String = "nil" ) { if let dictionary = dictionary { appendLiteral(String(describing: dictionary)) } else { appendLiteral(`default`()) } } } "\(dictionary: properties)" @basthomas, Copenhagen Cocoa, 06-02-2020 25
123 > maxBadgeCount ? String("\(maxBadgeCount)+") : String(123) @basthomas, Copenhagen Cocoa,
06-02-2020 26
extension String.StringInterpolation { mutating func appendInterpolation( number: Int, maximum: @autoclosure
() -> Int ) { let max = maximum() if number > max { appendLiteral("\(max)+") } else { appendLiteral("\(number)") } } } "\(number: number, maximum: maxBadgeCount)" @basthomas, Copenhagen Cocoa, 06-02-2020 27
! @basthomas, Copenhagen Cocoa, 06-02-2020 28
Polluting a namespace @basthomas, Copenhagen Cocoa, 06-02-2020 29
Code, documentation, tests @basthomas, Copenhagen Cocoa, 06-02-2020 30
struct BadgeCount: CustomStringConvertible { let value: Int var maximum =
99 var description: String { if value > maximum { return "\(maximum)+" } else { return "\(value)" } } } "\(BadgeCount(value: 123, maximum: 99))" "\(BadgeCount(value: 123))" @basthomas, Copenhagen Cocoa, 06-02-2020 31
Going all in @basthomas, Copenhagen Cocoa, 06-02-2020 32
struct HTMLComponent: ExpressibleByStringLiteral, ExpressibleByStringInterpolation, CustomStringConvertible { struct StringInterpolation: StringInterpolationProtocol {
var output = "" init(literalCapacity: Int, interpolationCount: Int) { output.reserveCapacity(literalCapacity * 2) } mutating func appendLiteral(_ literal: String) { output.append(literal) } mutating func appendInterpolation(twitter: String) { output.append("<a href=\"https://twitter.com/\(twitter)\">@\(twitter)</a>") } mutating func appendInterpolation(email: String) { output.append("<a href=\"mailto:\(email)\">\(email)</a>") } } let description: String init(stringLiteral value: String) { description = "<p>\(value)</p>" } init(stringInterpolation: StringInterpolation) { self.init(stringLiteral: stringInterpolation.output) } } @basthomas, Copenhagen Cocoa, 06-02-2020 33
struct StringInterpolation: StringInterpolationProtocol { var output = "" init(literalCapacity: Int,
interpolationCount: Int) { output.reserveCapacity(literalCapacity * 2) } mutating func appendLiteral(_ literal: String) { output.append(literal) } mutating func appendInterpolation(twitter: String) { output.append("<a href=\"https://twitter.com/\(twitter)\">@\(twitter)</a>") } mutating func appendInterpolation(email: String) { output.append("<a href=\"mailto:\(email)\">\(email)</a>") } } let html: HTMLComponent = "Find me on \(twitter: "basthomas") or send an email to \(email: "
[email protected]
")" // <p>Find me on <a href="https://twitter.com/basthomas">@basthomas</a> // or send an email to <a href="mailto:
[email protected]
">
[email protected]
</a></p> @basthomas, Copenhagen Cocoa, 06-02-2020 34
Optimize code for reading, not writing @basthomas, Copenhagen Cocoa, 06-02-2020
35
Communication is hard @basthomas, Copenhagen Cocoa, 06-02-2020 36
Thanks! @basthomas @basthomas, Copenhagen Cocoa, 06-02-2020 37