Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Swift 4 Highlights
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Jonathan Lehr
March 05, 2018
Programming
390
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Swift 4 Highlights
Presentation given at Capital One in McLean, VA, March 5, 2018
Jonathan Lehr
March 05, 2018
More Decks by Jonathan Lehr
See All by Jonathan Lehr
Transitioning to Swift
jonathanlehr
0
170
Other Decks in Programming
See All in Programming
新卒PdEのリアル
ryu1013
1
470
thread_parallel_with_free-threaded_Python_and_NumPy.pdf
riku_sakamoto
0
200
思考垂れ流し開発 ~音声入力 × AIエージェント × 開発ハーネスによる試行錯誤~
npostring
0
1k
XP祭りでしか伝わらないフリップネタ #xpjug
murabayashi
0
110
標準パッケージに uuid が追加された 背景から見る Go らしい意思決定 / go_127_uuid_decision
convto
4
3.6k
まだ間に合う!今年の夏こそSchemeのマクロ展開器を完全理解!
omasanori
0
640
AIは賢い。でも実行環境は? CLIおじさんがAI時代に伝えたいこと ~ CLIおじさんがAI時代に伝えたいこと ~
curekoshimizu
1
210
Omarchy Tokyo やると聞いて UMPC 買ってセットアップしてきた
mtsmfm
0
110
typoなんかねぇよ
raspython3
0
680
デプロイ直後のレイテンシスパイクを調べたら、 Railsの仕様にたどり着いた
nhsykym
0
110
Laravelのアプリケーションをどこにデプロイするか #ツナギメオフライン.9
akase244
0
120
フロントエンドUIフレームワークのこれまでとこれから
ssssota
2
1.3k
Featured
See All Featured
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.8k
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
230
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
123
22k
The Anti-SEO Checklist Checklist. Pubcon Cyber Week
ryanjones
0
230
New Earth Scene 8
popppiees
3
2.5k
Making the Leap to Tech Lead
cromwellryan
135
10k
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
370
エンジニアに許された特別な時間の終わり
watany
108
250k
Typedesign – Prime Four
hannesfritz
42
3.2k
How People are Using Generative and Agentic AI to Supercharge Their Products, Projects, Services and Value Streams Today
helenjbeal
1
310
Building a Scalable Design System with Sketch
lauravandoore
463
34k
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
1
510
Transcript
ABOUTOBJECTS Swi$ 4 Highlights Jonathan Lehr, Founder and VP, Training
1
About Objects • Reston, VA • Full-stack consul3ng (NFL, Marrio;,
Chicos, etc.) and training • Strong focus on iOS and middleware • Roots in NeXT, OpenStep, WebObjects + enterprise backends 2
Resources GitHub.com/AboutObjectsTraining • Swi% 4 Highlights • Swi% 3 Lowlights
Ole Begemann (oleb.net/blog) • Playground: What's new in Swi7 4 Copyright © 2018, About Objects, Inc. 3
Swi$ 4 Overview Copyright © 2018, About Objects, Inc. 4
New/Enhanced in Swi. 4 • Strings and One-Sided Ranges •
Collec4ons • Dictionary • Set • Key-Value Coding • Codable Protocol and JSON Support Copyright © 2018, About Objects, Inc. 5
Migra&ng From Swi. 3 • Explicit @obj direc-ves required on
a per-method basis to enable dynamic dispatch • Some Swi< 4 String APIs now return a new type, Substring Copyright © 2018, About Objects, Inc. 6
Strings 7
Strings in Swi* 2 and Swi* 3 • Dropped Collection
conformance • Added characters property containing collec4on of Character (extended grapheme cluster) • Substrings referred to original string's storage • ✅ Very efficient • ❌ Poten4al memory leak Copyright © 2018, About Objects, Inc. 8
Swi$ 3 String API Clutziness let stars = "✭✭✭✭✭✩✩✩✩✩" let
charView1 = stars.characters.dropFirst(2) print(charView1) // CharacterView(_core: // Swift._StringCore(_baseAddress: Optional(0x0000000101362454), // _countAndFlags: 9223372036854775816, _owner: nil), _coreOffset: 2) let charView2 = charView1.dropLast(3) // Still a CharacterView ! print(String(charView2)) // ✭✭✭✩✩ // Swift 4 print(stars.dropFirst(2).dropLast(3)) // ✭✭✭✩✩ Copyright © 2018, About Objects, Inc. 9
Swi$ 3 String API Clutziness let stars = "✭✭✭✭✭✩✩✩✩✩" let
charView1 = stars.characters.dropFirst(2) print(charView1) // CharacterView(_core: // Swift._StringCore(_baseAddress: Optional(0x0000000101362454), // _countAndFlags: 9223372036854775816, _owner: nil), _coreOffset: 2) let charView2 = charView1.dropLast(3) // Still a CharacterView ! print(String(charView2)) // ✭✭✭✩✩ // Swift 4 print(stars.dropFirst(2).dropLast(3)) // ✭✭✭✩✩ Copyright © 2018, About Objects, Inc. 10
Swi$ 3 String API Clutziness let stars = "✭✭✭✭✭✩✩✩✩✩" let
charView1 = stars.characters.dropFirst(2) print(charView1) // CharacterView(_core: // Swift._StringCore(_baseAddress: Optional(0x0000000101362454), // _countAndFlags: 9223372036854775816, _owner: nil), _coreOffset: 2) let charView2 = charView1.dropLast(3) // Still a CharacterView ! print(String(charView2)) // ✭✭✭✩✩ // Swift 4 print(stars.dropFirst(2).dropLast(3)) // ✭✭✭✩✩ Copyright © 2018, About Objects, Inc. 11
Swi$ 4 Strings (SE-0163) • Adds back Collection conformance and
deprecates characters property • Adds Substring type • Prevents leaks by helping developers avoid accidental storage of Substring instances • String and Substring share API by conforming to StringProtocol Copyright © 2018, About Objects, Inc. 12
String Collec-on API Examples // Looping through a string's characters:
let s = "abc" for c in s { print(c) } // a // b // c // Inserting characters: var name = "Fred Smith" let index = name.index(of: " ") ?? name.endIndex name.insert(contentsOf: " W.", at: index) // Fred W. Smith Copyright © 2018, About Objects, Inc. 13
String Collec-on API Examples // Looping through a string's characters:
let s = "abc" for c in s { print(c) } // a // b // c // Inserting characters: var name = "Fred Smith" let index = name.index(of: " ") ?? name.endIndex name.insert(contentsOf: " W.", at: index) // Fred W. Smith Copyright © 2018, About Objects, Inc. 14
Substring Example let name = "Fred Smith" let last: Substring
= name.dropFirst(5) // type ^^^^^^^^^^^ shown for clarity print(last) // "Smith" struct Dude { var name: String? } var dude = Dude() dude.name = name // ! Doesn't compile Copyright © 2018, About Objects, Inc. 15
Substring Example let name = "Fred Smith" let last: Substring
= name.dropFirst(5) // type ^^^^^^^^^^^ shown for clarity print(last) // "Smith" struct Dude { var name: String? } var dude = Dude() dude.name = name // ! Doesn't compile Copyright © 2018, About Objects, Inc. 16
Mul$-Line String Literals (SE-168) • Enclosed in triple-quotes • Whitespace
up to trailing quotes ignored let year = 2017 let numPages = 240 let jsonText = """ { "title": "War of the Worlds", "author": "H. G. Wells", "publication_year": \(year), "number_of_pages": \(numPages) } """ Copyright © 2018, About Objects, Inc. 17
One-Sided Ranges (SE-172) • Ranges can be expressed without explicit
star6ng or ending values let s = "Hello !!" // Compute an index relative to start of string. let index = s.index(s.startIndex, offsetBy: 6) let head = s[..<index] print(head) // "Hello " let tail = s[index...] print(tail) // "!!" Copyright © 2018, About Objects, Inc. 18
Collec&ons 19
Dic$onary Keys and Values (SE-154) • Adds type-specific collec0ons for
keys and values • Faster key lookups • More effecient value muta0on let books = ["Emma": 11.95, "Henry V": 14.99, "1984": 14.99, "Utopia": 11.95] guard let index = books.index(forKey: "Emma") else { return } print(books.values[index]) // 11.95 Copyright © 2018, About Objects, Inc. 20
Dic$onary & Set Enhancements(SE-165) • Dic%onary-specific map and filter •
Grouping sequence elements • Default values for subscripts • Merging dic%onaries Copyright © 2018, About Objects, Inc. 21
Dic$onary-Specific Filter let books = ["Emma": 11.95, "Henry V": 14.99,
"1984": 14.99, "Utopia": 11.95] // In Swift 3, Dictionary's `filter` method returned an // array of key-value tuples instead of a dictionary. let cheapBooks = books.filter { $0.value < 12.00 } // [(key: "Utopia", value: 11.95), (key: "Emma", value: 11.95)] // If you need a Dictionary result, you have to produce one manually let cheapBooksDict = cheapBooks.reduce([:]) { var dict = $0 dict[$1.key] = $1.value return dict } // ["Utopia": 11.95, "Emma": 11.95] Copyright © 2018, About Objects, Inc. 22
Dic$onary-Specific Filter let books = ["Emma": 11.95, "Henry V": 14.99,
"1984": 14.99, "Utopia": 11.95] // In Swift 3, Dictionary's `filter` method returned an // array of key-value tuples instead of a dictionary. let cheapBooks = books.filter { $0.value < 12.00 } // ["Utopia": 11.95, "Emma": 11.95] // If you need a Dictionary result, you have to produce one manually let cheapBooksDict = cheapBooks.reduce([:]) { var dict = $0 dict[$1.key] = $1.value return dict } // ["Utopia": 11.95, "Emma": 11.95] Copyright © 2018, About Objects, Inc. 23
Dic$onary-Specific Map let books = ["Emma": 11.95, "Henry V": 14.99,
"1984": 14.99, "Utopia": 11.95] // Similarly, Dictionary's `map` method returns an array of values let discount = 0.10 let discountedPrices = books.map { $0.value * (1 - discount) } // [10.75, 13.49, 10.75, 13.49] // That's fine if you simply want to sum the values, but suppose // you want to produce a list of discounted prices? // Swift 4 adds `mapValues`, which returns a Dictionary let discount = 0.10 let discountedBooks = books.mapValues { $0 * (1 - discount) } // ["Utopia": 10.75, "1984": 13.49, "Emma": 10.75, "Henry V": 13.49] Copyright © 2018, About Objects, Inc. 24
Dic$onary-Specific Map let books = ["Emma": 11.95, "Henry V": 14.99,
"1984": 14.99, "Utopia": 11.95] // Similarly, Dictionary's `map` method returns an array of values let discount = 0.10 let discountedPrices = books.map { $0.value * (1 - discount) } // [10.75, 13.49, 10.75, 13.49] // That's fine if you simply want to sum the values, but suppose // you want to produce a list of discounted prices? // Swift 4 adds `mapValues`, which returns a Dictionary let discount = 0.10 let discountedBooks = books.mapValues { $0 * (1 - discount) } // ["Utopia": 10.75, "1984": 13.49, "Emma": 10.75, "Henry V": 13.49] Copyright © 2018, About Objects, Inc. 25
Dic$onary-Specific Map let books = ["Emma": 11.95, "Henry V": 14.99,
"1984": 14.99, "Utopia": 11.95] // Similarly, Dictionary's `map` method returns an array of values let discount = 0.10 let discountedPrices = books.map { $0.value * (1 - discount) } // [10.75, 13.49, 10.75, 13.49] // That's fine if you simply want to sum the values, but suppose // you want to produce a list of discounted prices? // Swift 4 adds `mapValues`, which returns a Dictionary let discount = 0.10 let discountedBooks = books.mapValues { $0 * (1 - discount) } // ["Utopia": 10.75, "1984": 13.49, "Emma": 10.75, "Henry V": 13.49] Copyright © 2018, About Objects, Inc. 26
Grouping Sequence Elements • Swi% 4 adds a new ini-alizer
for grouping sequences of values. ! let books = ["Emma": 11.95, "Henry V": 14.99, "1984": 14.99, "Utopia": 11.95] let booksByPrice = Dictionary(grouping: books, by: { $0.value }) // [11.95: [(key: "Utopia", value: 11.95), // (key: "Emma", value: 11.95)], // 14.99: [(key: "1984", value: 14.99), // (key: "Henry V", value: 14.99)]] Copyright © 2018, About Objects, Inc. 27
Default Values for Subscripts // Access with default value may
not seem like a huge win let books = ["Emma": 11.95, "Henry V": 14.99, "1984": 14.99, "Utopia": 11.95] // Swift 3: let price = books["Foo"] ?? 0 // Swift 4: let price2 = books["Foo", default: 0] // ...but mutation with a default value is ! var discountedBooks = books let keys = ["Emma", "1984", "Foo"] for key in keys { discountedBooks[key, default: 0] *= 0.9 } // ["Utopia": 11.95, "1984": 13.49, "Foo": 0.0, "Emma": 10.75, "Henry V": 14.99] Copyright © 2018, About Objects, Inc. 28
Default Values for Subscripts // Access with default value may
not seem like a huge win let books = ["Emma": 11.95, "Henry V": 14.99, "1984": 14.99, "Utopia": 11.95] // Swift 3: let price = books["Foo"] ?? 0 // Swift 4: let price2 = books["Foo", default: 0] // ...but mutation with a default value is ! var discountedBooks = books let keys = ["Emma", "1984", "Foo"] for key in keys { discountedBooks[key, default: 0] *= 0.9 } // ["Utopia": 11.95, "1984": 13.49, "Foo": 0.0, "Emma": 10.75, "Henry V": 14.99] Copyright © 2018, About Objects, Inc. 29
Merging Dic*onaries let personal = ["home": "703-333-4567", "cell": "202-444-1234"] let
work = ["main": "571-222-9876", "cell": "703-987-5678"] // If keys match, replaces the current value with the newer value var phones1 = personal phones1.merge(work) { _, new in new } ["main": "571-222-9876", "cell": "703-987-5678", "home": "703-333-4567"] // If keys match, replaces the current value with a tuple of both values var phones2: [String: Any] = personal phones2.merge(work) { (personal: $0, work: $1) } ["main": "571-222-9876", "cell": (personal: "202-444-1234", work: "703-987-5678"), "home": "703-333-4567"] Copyright © 2018, About Objects, Inc. 30
Merging Dic*onaries let personal = ["home": "703-333-4567", "cell": "202-444-1234"] let
work = ["main": "571-222-9876", "cell": "703-987-5678"] // If keys match, replaces the current value with the newer value var phones1 = personal phones1.merge(work) { _, new in new } ["main": "571-222-9876", "cell": "703-987-5678", "home": "703-333-4567"] // If keys match, replaces the current value with a tuple of both values var phones2: [String: Any] = personal phones2.merge(work) { (personal: $0, work: $1) } ["main": "571-222-9876", "cell": (personal: "202-444-1234", work: "703-987-5678"), "home": "703-333-4567"] Copyright © 2018, About Objects, Inc. 31
Key-Value Coding 32
Smart KeyPaths (SE-161) • Allows key paths to be used
with non-objc types • New expression syntax for key paths • Similar to property reference, but prefixed with \ for example, \Book.rating • Expression result is an instance of KeyPath Copyright © 2018, About Objects, Inc. 33
Smart KeyPaths Example (1) struct Person { var name: String
var address: Address } struct Address: CustomStringConvertible { var street: String var city: String } let address = Address(street: "21 Elm", city: "Reston") let person = Person(name: "Jo", address: address) let name = person[keyPath: \Person.name] // "Jo" let city = person[keyPath: \Person.address.city] // "Reston" Copyright © 2018, About Objects, Inc. 34
Smart KeyPaths Example (2) • Instances of KeyPath can be
stored let address = Address(street: "21 Elm", city: "Reston") let person = Person(name: "Jo", address: address) // Initialize an array of KeyPaths let keyPaths = [\Person.name, \Person.address.city, \Person.address.street] // Map KeyPaths to an array of property values let values = keyPaths.map { person[keyPath: $0] } // ["Jo", "Reston", "21 Elm"] Copyright © 2018, About Objects, Inc. 35
Smart KeyPaths Example (3) • You can use KeyPaths to
mutate proper3es of non- ObjC types // KeyPaths allow you to mutate properties of Swift types let address = Address(street: "21 Elm", city: "Reston") var mutablePerson = Person(name: "Jo", address: address) mutablePerson[keyPath: \Person.name] = "Kay" mutablePerson[keyPath: \Person.address.city] = "Herndon" // Person(name: "Kay", address: // Address(street: "21 Elm", city: "Herndon")) Copyright © 2018, About Objects, Inc. 36
Codable 37
Swi$ Archival and Serializa1on (SE-166) • Adds protocols for •
Encoders and decoders • Encodable and decodable types • Property keys • User info keys Copyright © 2018, About Objects, Inc. 38
Codable Protocols • Compiler can synthesize default implementa6ons /// A
type that can encode values into a native format /// for external representation. public protocol Encodable { public func encode(to encoder: Encoder) throws } /// A type that can decode itself from an external representation. public protocol Decodable { public init(from decoder: Decoder) throws } public typealias Codable = Decodable & Encodable Copyright © 2018, About Objects, Inc. 39
Standard Library Codable Types • Optional • Array, Dictionary •
String, Int, Double • Date, Data, URL Copyright © 2018, About Objects, Inc. 40
Declaring Codable Types // Declare Person and Dog structs conforming
to Codable struct Person: Codable { var name: String var age: Int var dog: Dog } struct Dog: Codable { var name: String var breed: Breed // Codable has built-in support for enums with raw values. enum Breed: String, Codable { case collie = "Collie" case beagle = "Beagle" case greatDane = "Great Dane" } } Copyright © 2018, About Objects, Inc. 41
Swi$ Encoders (SE-167) • Founda(on framework classes are bridged across
as Swi7 types Swi$ Standard Library Founda1on JSONEncoder NSJSONSerialization JSONDecoder NSJSONSerialization PropertyListEncoder NSPropertyListSerialization PropertyListDecoder NSPropertyListSerialization Copyright © 2018, About Objects, Inc. 42
Encoding to JSON let encoder = JSONEncoder() encoder.outputFormatting = .prettyPrinted
let fred = Person(name: "Fred", age: 30, dog: Dog(name: "Spot", breed: .beagle)) let data = try! encoder.encode(fred) { "name" : "Fred", "age" : 30, "dog" : { "name" : "Spot", "breed" : "Beagle" } } Copyright © 2018, About Objects, Inc. 43
Encoding to JSON let encoder = JSONEncoder() encoder.outputFormatting = .prettyPrinted
let fred = Person(name: "Fred", age: 30, dog: Dog(name: "Spot", breed: .beagle)) let data = try! encoder.encode(fred) { "name" : "Fred", "age" : 30, "dog" : { "name" : "Spot", "breed" : "Beagle" } } Copyright © 2018, About Objects, Inc. 44
Encoding to JSON let encoder = JSONEncoder() encoder.outputFormatting = .prettyPrinted
let fred = Person(name: "Fred", age: 30, dog: Dog(name: "Spot", breed: .beagle)) let data = try! encoder.encode(fred) { "name" : "Fred", "age" : 30, "dog" : { "name" : "Spot", "breed" : "Beagle" } } Copyright © 2018, About Objects, Inc. 45
Decoding from JSON let decoder = JSONDecoder() let fredsClone =
try! decoder.decode(Person.self, from: data) // Person(name: "Fred", // age: 30, // dog: Dog(name: "Spot", // breed: Dog.Breed.beagle)) Copyright © 2018, About Objects, Inc. 46
Decoding from JSON let decoder = JSONDecoder() let fredsClone =
try! decoder.decode(Person.self, from: data) // Person(name: "Fred", // age: 30, // dog: Dog(name: "Spot", // breed: Dog.Breed.beagle)) !" Copyright © 2018, About Objects, Inc. 47
Codable Demo 48
ABOUTOBJECTS 49
Upcoming Classes View online: Public schedule Date Title Mar 12
– 14 Transi-oning to Swi3 Apr 14 – Apr 20 iOS Development in Swi3: Comprehensive Apr 30 – May 4 Advanced iOS Development 50
Q & A 51