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
710
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
42
Building an Accessibility Culture, One Step at a Time (Leeds)
basthomas
0
140
Building an Accessibility Culture, One Step at a Time
basthomas
1
110
Building a modern subscription experience on iOS
basthomas
0
210
Not an afterthought: accessibility from start to finish
basthomas
0
160
Accessibility on Apple Platforms: Beyond VoiceOver
basthomas
0
190
No Touch(screen) Required: Voice & Keyboard Accessibility
basthomas
0
180
Dancing with Dinosaurs: Objective-C and Swift Interop
basthomas
0
190
Effective Pull Request Reviews
basthomas
0
440
Other Decks in Programming
See All in Programming
PHPで使える日時の表現と、その知り方 #frontend_phpcon_do
o0h
PRO
0
230
AIとASP.NET Coreで雑Webアプリを作った話
mayuki
0
500
AIチームを指揮するOSS「TAKT」活用術 / How to Use “TAKT,” an OSS Tool for Orchestrating AI Teams
nrslib
6
880
The NotImplementedError Problem in Ruby
koic
1
710
「AIで開発し、AIを届ける」をEvalでつなぐ 〜AIネイティブに始めるプロダクト開発の実践〜 / Connecting "Develop with AI, deliver AI" with Eval
rkaga
4
4.9k
TAKTでAI駆動開発の品質を設計する
j5ik2o
6
1.2k
正しくソフトウェアを作る、前提を疑うための認知の視点 / doubt-premise
minodriven
20
6.5k
Spec Driven Development | AI Summit Lisbon
danielsogl
PRO
0
180
スマートグラスで並列バイブコーディング
hyshu
0
120
Java × distroless で 軽量なコンテナイメージを / Java on Distroless
contour_gara
0
530
脅威をエンジニアリングの糧にして――現場編 / Turning Threats into Engineering Fuel — Field Edition
nrslib
0
270
エージェンティックRAGにAWSで入門しよう!
har1101
8
1.4k
Featured
See All Featured
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
2.9k
We Are The Robots
honzajavorek
0
240
Typedesign – Prime Four
hannesfritz
42
3.1k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3.2k
Why Our Code Smells
bkeepers
PRO
340
58k
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
420
Navigating Algorithm Shifts & AI Overviews - #SMXNext
aleyda
1
1.3k
Fireside Chat
paigeccino
42
3.9k
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.3k
Measuring & Analyzing Core Web Vitals
bluesmoon
9
860
Discover your Explorer Soul
emna__ayadi
2
1.1k
First, design no harm
axbom
PRO
2
1.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