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
Assistive Access: Reinventing Your App for a New (sort of) Generation
basthomas
0
11
Roasting Your App's Accessibility
basthomas
0
54
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
為什麼你並不需要ViewModel / No, you don't need a ViewModel
lovee
1
490
<title><a id="</title>君はこのHTMLをパースできるか"></a></title> #雑LT_study
pizzacat83
0
140
PHP Application における Kubernetes 内 gRPC 通信
ganchiku
0
590
PHP初心者セッション2026 〜生成AIでは見えない裏側を知る:今だからLAMPを通して仕組みを学ぶ〜
kashioka
0
900
仕様駆動開発の消費期限
watany
20
8k
複数の Claude Code が"放置"されてしまう問題をCLI ダッシュボードを自作して解決した話
sumihiro3
1
680
ここ半年くらいでAIに作らせたR用ツール
eitsupi
0
370
jsmini JavaScript Engine を作ってみた話
yosuke_furukawa
PRO
0
310
AWS DevOps AgentのAzure接続機能を検証して見えた活用法/Use Cases Verified for the AWS DevOps Agent's Azure Connectivity Feature
masakiokuda
1
230
JAWS-UG横浜 #102 AWSサ終供養LT会 成仏できない AWS サービスたち 〜本日、三体供養します〜
maroon1st
0
350
ドリフトを絶対に許さない(?)CDK運用 / CDK Ops with Zero Tolerance for Drifts (?)
akihisaikeda
1
180
生成AIで帳票OCRが「簡単に」作れる時代になった?
kon_shou
0
740
Featured
See All Featured
The Invisible Side of Design
smashingmag
301
52k
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
450
Statistics for Hackers
jakevdp
799
230k
世界の人気アプリ100個を分析して見えたペイウォール設計の心得
akihiro_kokubo
PRO
73
41k
The Mindset for Success: Future Career Progression
greggifford
PRO
0
440
Product Roadmaps are Hard
iamctodd
55
12k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
17k
Have SEOs Ruined the Internet? - User Awareness of SEO in 2025
akashhashmi
0
410
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.6k
The AI Search Optimization Roadmap by Aleyda Solis
aleyda
1
6k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
28
3.6k
What's in a price? How to price your products and services
michaelherold
247
13k
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