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
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
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
Assistive Access: Reinventing Your App for a New (sort of) Generation
basthomas
0
17
Roasting Your App's Accessibility
basthomas
0
56
Building an Accessibility Culture, One Step at a Time (Leeds)
basthomas
0
150
Building an Accessibility Culture, One Step at a Time
basthomas
1
130
Building a modern subscription experience on iOS
basthomas
0
230
Not an afterthought: accessibility from start to finish
basthomas
0
180
Accessibility on Apple Platforms: Beyond VoiceOver
basthomas
0
200
No Touch(screen) Required: Voice & Keyboard Accessibility
basthomas
0
190
Dancing with Dinosaurs: Objective-C and Swift Interop
basthomas
0
200
Other Decks in Programming
See All in Programming
引き算の組織 ― アウトカムとAIに全振りするために辞めたこと ― / Organization by Subtraction
hirokiyamamoto14
PRO
0
250
型も通る、synthも通る、それでも危ない 〜AIのCDKの権限とコストを機械で検証する〜 / It Passes Type Checks, It Passes Synth Checks, but It’s Still Risky — Automatically Verifying Permissions and Costs in AI’s CDK —
seike460
PRO
1
570
Cloudflare is Agents
chimame
0
170
改善しないと、タスクが回らない。 “てんこ盛りポジション” を引き継いだ情シスの、入社3ヶ月の業務改善録
krm963
0
270
php-fpmのプロセスが枯渇した日-調査・対処・そして本当にやるべきだったこと-
shibuchaaaan
0
310
PHP初心者セッション2026 〜生成AIでは見えない裏側を知る:今だからLAMPを通して仕組みを学ぶ〜
kashioka
0
960
「人を評価する AI」の設計と実装
ryoyanara
0
210
React本体のコードリーディング
high_g_engineer
1
150
生成AI導入の「期待外れ」を乗り越える ー 開発フロー改革が目指す、真の組織変革
starfish719
0
4.7k
2年かけて Deno に DOMMatrix を実装した話 / How I implemented DOMMatrix in Deno over two years
petamoriken
0
210
<title><a id="</title>君はこのHTMLをパースできるか"></a></title> #雑LT_study
pizzacat83
0
150
実装をデザインガイドラインに追従させるための取り組み / 260731-dip-mosh-design-system
dachi023
0
4.6k
Featured
See All Featured
Build your cross-platform service in a week with App Engine
jlugia
234
19k
Practical Orchestrator
shlominoach
191
12k
HTML-Aware ERB: The Path to Reactive Rendering @ RubyCon 2026, Rimini, Italy
marcoroth
3
450
Deep Space Network (abreviated)
tonyrice
0
260
Optimising Largest Contentful Paint
csswizardry
37
3.9k
Reflections from 52 weeks, 52 projects
jeffersonlam
356
21k
Rebuilding a faster, lazier Slack
samanthasiow
85
9.6k
世界の人気アプリ100個を分析して見えたペイウォール設計の心得
akihiro_kokubo
PRO
73
41k
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
The Invisible Side of Design
smashingmag
301
52k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
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