SlideShare ist ein Scribd-Unternehmen logo
1 von 57
Downloaden Sie, um offline zu lesen
Hi, I’m Donny.
I build iOS apps.
Hi, I’m Donny.
I build iOS apps.
JSON and Swift…
JSON and Swift…
Still A Better Love Story Than Twilight
Topics
• Pre-Swift 4.0 JSON handling

• Some things I learned about JSON pre-Swift 4.0

• Handling JSON in Swift 4.0

• Concluding remarks
Pre-Swift 4.0 JSON Handling
{
"items": [{
"line_up": [{
"artist": {
"name": "Foo"
}
}]
}]
}
JSON File:
Pre-Swift 4.0 JSON Handling
{
"items": [{
"line_up": [{
"artist": {
"name": "Foo"
}
}]
}]
}
JSON File: Swift 1.0:
if let items = json["items"] as? [[String: AnyObject]] {
if let rstItem = items.rst {
if let item = rstItem as? [String: AnyObject] {
if let lineUp = item["line_up"] as? [[String: AnyObject]] {
if let rstLineupItem = lineUp.rst {
if let artist = rstLineupItem["artist"] as? [String: AnyObject] {
if let name = artist["name"] as? String {
print(name)
}
}
}
}
}
}
}
Pre-Swift 4.0 JSON Handling
{
"items": [{
"line_up": [{
"artist": {
"name": "Foo"
}
}]
}]
}
JSON File: Swift 2.0:
guard let items = json["items"] as? [String: Any],
let rstItem = items.rst,
let item = rstItem as? [String: Any],
let lineUp = rstItem["line_up"] as? [[String: Any]],
let rstLineUpItem = lineUp.rst,
let artist = rstLineUpItem["artist"] as? [String: Any],
let name = artist["name"] as? String
else { return }
print(name)
Pre-Swift 4.0 JSON Handling
{
"items": [{
"line_up": [{
"artist": {
"name": "Foo"
}
}]
}]
}
JSON File: SwiftyJSON
guard let item = json["items"].arrayValue.rst,
let lineUpItem = item["line_up"].arrayValue.rst,
let name = lineUpItem["artist"]["name"].string
else { return }
print(name)
SwiftyJSON is amazing!
guard let item = json["items"].arrayValue.rst,
let lineUpItem = item["line_up"].arrayValue.rst,
let name = lineUpItem["artist"]["name"].string
else { return }
print(name)
😍
SwiftyJSON is amazing!
guard let item = json["items"].arrayValue.rst,
let lineUpItem = item["line_up"].arrayValue.rst,
let name = lineUpItem["artist"]["name"].string
else { return }
print(name)
😍
A performance test
A performance test
{ id: 260,
name: 'DAS Foute Oktoberfest 20171',
start: '2017-02-20T16:00:00+0000',
end: '2017-10-07T23:59:00+0000',
publish_from: '2016-11-09T08:00:00+0000',
publish_to: '2017-10-07T23:59:00+0000',
categories: [ { id: 2, name: 'NAME GOES HERE' } ],
location:
{ name: 'Goffertpark, Nijmegen (NL)',
address: '',
zipcode: '1234AB',
city: 'Nijmegen',
state: 'Noord-whateverland',
country: 'NL',
latitude: 51.82548,
longitude: 5.836629,
url: 'https://www.google.nl/maps/place/Goffertpark/@52.2576689,5.2644167,8.25z/data=!4m5!3m4!
1s0x47c7089b2ce7dff1:0xfd37f35c5b91b9c8!8m2!3d51.8255586!4d5.8366532',
email: 'random@email.com',
id: 169,
radius: 500 },
line_up:
[ { id: 1, name: 'nino' },
{ id: 2, name: 'lisa' },
{ id: 7, name: 'kees' },
{ id: 4, name: 'Rodney' },
{ id: 8, name: 'Oscar' },
{ id: 9, name: 'Dick' } ],
description: 'Matrixx presenteert Het Foute Oktoberfest 2017!rnrnZaterdag 7 oktober in een grote feesttent op de Goffertweide in Nijmegen.
rnrnBinnenkort meer info!',
image_url: 'http://app.appimin.com/lelib/storage/events/58246fa620305_het-foute-oktoberfest-2017.jpg' }
A performance test
{ id: 260,
name: 'DAS Foute Oktoberfest 20171',
start: '2017-02-20T16:00:00+0000',
end: '2017-10-07T23:59:00+0000',
publish_from: '2016-11-09T08:00:00+0000',
publish_to: '2017-10-07T23:59:00+0000',
categories: [ { id: 2, name: 'NAME GOES HERE' } ],
location:
{ name: 'Goffertpark, Nijmegen (NL)',
address: '',
zipcode: '1234AB',
city: 'Nijmegen',
state: 'Noord-whateverland',
country: 'NL',
latitude: 51.82548,
longitude: 5.836629,
url: 'https://www.google.nl/maps/place/Goffertpark/@52.2576689,5.2644167,8.25z/data=!4m5!3m4!
1s0x47c7089b2ce7dff1:0xfd37f35c5b91b9c8!8m2!3d51.8255586!4d5.8366532',
email: 'random@email.com',
id: 169,
radius: 500 },
line_up:
[ { id: 1, name: 'nino' },
{ id: 2, name: 'lisa' },
{ id: 7, name: 'kees' },
{ id: 4, name: 'Rodney' },
{ id: 8, name: 'Oscar' },
{ id: 9, name: 'Dick' } ],
description: 'Matrixx presenteert Het Foute Oktoberfest 2017!rnrnZaterdag 7 oktober in een grote feesttent op de Goffertweide in Nijmegen.
rnrnBinnenkort meer info!',
image_url: 'http://app.appimin.com/lelib/storage/events/58246fa620305_het-foute-oktoberfest-2017.jpg' }
• 2080 events
A performance test
{ id: 260,
name: 'DAS Foute Oktoberfest 20171',
start: '2017-02-20T16:00:00+0000',
end: '2017-10-07T23:59:00+0000',
publish_from: '2016-11-09T08:00:00+0000',
publish_to: '2017-10-07T23:59:00+0000',
categories: [ { id: 2, name: 'NAME GOES HERE' } ],
location:
{ name: 'Goffertpark, Nijmegen (NL)',
address: '',
zipcode: '1234AB',
city: 'Nijmegen',
state: 'Noord-whateverland',
country: 'NL',
latitude: 51.82548,
longitude: 5.836629,
url: 'https://www.google.nl/maps/place/Goffertpark/@52.2576689,5.2644167,8.25z/data=!4m5!3m4!
1s0x47c7089b2ce7dff1:0xfd37f35c5b91b9c8!8m2!3d51.8255586!4d5.8366532',
email: 'random@email.com',
id: 169,
radius: 500 },
line_up:
[ { id: 1, name: 'nino' },
{ id: 2, name: 'lisa' },
{ id: 7, name: 'kees' },
{ id: 4, name: 'Rodney' },
{ id: 8, name: 'Oscar' },
{ id: 9, name: 'Dick' } ],
description: 'Matrixx presenteert Het Foute Oktoberfest 2017!rnrnZaterdag 7 oktober in een grote feesttent op de Goffertweide in Nijmegen.
rnrnBinnenkort meer info!',
image_url: 'http://app.appimin.com/lelib/storage/events/58246fa620305_het-foute-oktoberfest-2017.jpg' }
• 2080 events
• Nested objects
A performance test
{ id: 260,
name: 'DAS Foute Oktoberfest 20171',
start: '2017-02-20T16:00:00+0000',
end: '2017-10-07T23:59:00+0000',
publish_from: '2016-11-09T08:00:00+0000',
publish_to: '2017-10-07T23:59:00+0000',
categories: [ { id: 2, name: 'NAME GOES HERE' } ],
location:
{ name: 'Goffertpark, Nijmegen (NL)',
address: '',
zipcode: '1234AB',
city: 'Nijmegen',
state: 'Noord-whateverland',
country: 'NL',
latitude: 51.82548,
longitude: 5.836629,
url: 'https://www.google.nl/maps/place/Goffertpark/@52.2576689,5.2644167,8.25z/data=!4m5!3m4!
1s0x47c7089b2ce7dff1:0xfd37f35c5b91b9c8!8m2!3d51.8255586!4d5.8366532',
email: 'random@email.com',
id: 169,
radius: 500 },
line_up:
[ { id: 1, name: 'nino' },
{ id: 2, name: 'lisa' },
{ id: 7, name: 'kees' },
{ id: 4, name: 'Rodney' },
{ id: 8, name: 'Oscar' },
{ id: 9, name: 'Dick' } ],
description: 'Matrixx presenteert Het Foute Oktoberfest 2017!rnrnZaterdag 7 oktober in een grote feesttent op de Goffertweide in Nijmegen.
rnrnBinnenkort meer info!',
image_url: 'http://app.appimin.com/lelib/storage/events/58246fa620305_het-foute-oktoberfest-2017.jpg' }
• 2080 events
• Nested objects
• Tested on iPhone 5c
A performance test
A performance test
func loadSwifty() {
guard let data = getFileData()
else { return }
let jsonFile = JSON(data: data)
for eventJSON in jsonFile["events"].arrayValue {
let location = Location(id: eventJSON["location"]["id"].intValue,
name: eventJSON["location"]["name"].stringValue,
lat: eventJSON["location"]["latitude"].double,
lon: eventJSON[“location"]["longitude"].double,
address: eventJSON["location"]["address"].stringValue,
zipcode: eventJSON[“location"]["zipcode"].stringValue)
// etc.
}
showCompletion()
}
A performance test
func loadSwifty() {
guard let data = getFileData()
else { return }
let jsonFile = JSON(data: data)
for eventJSON in jsonFile["events"].arrayValue {
let location = Location(id: eventJSON["location"]["id"].intValue,
name: eventJSON["location"]["name"].stringValue,
lat: eventJSON["location"]["latitude"].double,
lon: eventJSON[“location"]["longitude"].double,
address: eventJSON["location"]["address"].stringValue,
zipcode: eventJSON[“location"]["zipcode"].stringValue)
// etc.
}
showCompletion()
}
6.76 seconds to complete
A performance test
func loadSwifty() {
guard let data = getFileData()
else { return }
let jsonFile = JSON(data: data)
for eventJSON in jsonFile["events"].arrayValue {
let location = Location(id: eventJSON["location"]["id"].intValue,
name: eventJSON["location"]["name"].stringValue,
lat: eventJSON["location"]["latitude"].double,
lon: eventJSON[“location"]["longitude"].double,
address: eventJSON["location"]["address"].stringValue,
zipcode: eventJSON[“location"]["zipcode"].stringValue)
// etc.
}
showCompletion()
}
6.76 seconds to complete
"😭
A performance test
A performance test
func loadNormal() {
guard let data = getFileData(),
let jsonObject = try? JSONSerialization.jsonObject(with: data, options: []),
let json = jsonObject as? DWJSON,
let events = json["events"] as? [DWJSON]
else { return }
for eventJSON in events {
guard let locationJSON = eventJSON["location"] as? DWJSON,
let categoriesJSON = eventJSON["categories"] as? [DWJSON],
let lineUpJSON = eventJSON["line_up"] as? [DWJSON]
else { return }
// etc.
}
showCompletion()
}
A performance test
func loadNormal() {
guard let data = getFileData(),
let jsonObject = try? JSONSerialization.jsonObject(with: data, options: []),
let json = jsonObject as? DWJSON,
let events = json["events"] as? [DWJSON]
else { return }
for eventJSON in events {
guard let locationJSON = eventJSON["location"] as? DWJSON,
let categoriesJSON = eventJSON["categories"] as? [DWJSON],
let lineUpJSON = eventJSON["line_up"] as? [DWJSON]
else { return }
// etc.
}
showCompletion()
}
1.84 seconds to complete
A performance test
func loadNormal() {
guard let data = getFileData(),
let jsonObject = try? JSONSerialization.jsonObject(with: data, options: []),
let json = jsonObject as? DWJSON,
let events = json["events"] as? [DWJSON]
else { return }
for eventJSON in events {
guard let locationJSON = eventJSON["location"] as? DWJSON,
let categoriesJSON = eventJSON["categories"] as? [DWJSON],
let lineUpJSON = eventJSON["line_up"] as? [DWJSON]
else { return }
// etc.
}
showCompletion()
}
1.84 seconds to complete
$😍
What did I learn?
What did I learn?
• Be careful about libraries that make things easy; they might be (very) slow.
What did I learn?
• Be careful about libraries that make things easy; they might be (very) slow.
• Sometimes uglier code is faster (unfortunately).
What did I learn?
• Be careful about libraries that make things easy; they might be (very) slow.
• Sometimes uglier code is faster (unfortunately).
• Working with JSON isn’t as bad as it seems in Swift 2.0+.
What about Swift 4.0?
❓&❓
Introducing Codable
Introducing Codable
struct Category {
let id: Int
let name: String
}
let category = Category(id: categoryJSON["id"] as? Int ?? 0,
name: categoryJSON["name"] as? String ?? "")
< Swift 4.0
Introducing Codable
struct Category {
let id: Int
let name: String
}
let category = Category(id: categoryJSON["id"] as? Int ?? 0,
name: categoryJSON["name"] as? String ?? "")
< Swift 4.0
struct Category: Codable {
let id: Int
let name: String
}
Swift 4.0
let decoder = JSONDecoder()
let category = try? decoder.decode(Category.self, from: data)
Introducing Codable
struct Category {
let id: Int
let name: String
}
let category = Category(id: categoryJSON["id"] as? Int ?? 0,
name: categoryJSON["name"] as? String ?? "")
< Swift 4.0
struct Category: Codable {
let id: Int
let name: String
}
Swift 4.0
let decoder = JSONDecoder()
let category = try? decoder.decode(Category.self, from: data)
Property names are directly mapped to JSON keys
Introducing Codable
But what if the keys don’t match?
Introducing Codable
location:
{ name: 'Goffertpark, Nijmegen (NL)',
address: '',
zipcode: '1234AB',
city: 'Nijmegen',
state: 'Noord-whateverland',
country: 'NL',
latitude: 51.82548,
longitude: 5.836629,
url: ‘https://www.google.nl/',
email: 'random@email.com',
id: 169,
radius: 500 }
But what if the keys don’t match?
Introducing Codable
location:
{ name: 'Goffertpark, Nijmegen (NL)',
address: '',
zipcode: '1234AB',
city: 'Nijmegen',
state: 'Noord-whateverland',
country: 'NL',
latitude: 51.82548,
longitude: 5.836629,
url: ‘https://www.google.nl/',
email: 'random@email.com',
id: 169,
radius: 500 }
But what if the keys don’t match?
Introducing Codable
location:
{ name: 'Goffertpark, Nijmegen (NL)',
address: '',
zipcode: '1234AB',
city: 'Nijmegen',
state: 'Noord-whateverland',
country: 'NL',
latitude: 51.82548,
longitude: 5.836629,
url: ‘https://www.google.nl/',
email: 'random@email.com',
id: 169,
radius: 500 }
struct Location {
let id: Int
let name: String
let lat: Double?
let lon: Double?
let address: String
let zipcode: String
}
But what if the keys don’t match?
Introducing Codable
location:
{ name: 'Goffertpark, Nijmegen (NL)',
address: '',
zipcode: '1234AB',
city: 'Nijmegen',
state: 'Noord-whateverland',
country: 'NL',
latitude: 51.82548,
longitude: 5.836629,
url: ‘https://www.google.nl/',
email: 'random@email.com',
id: 169,
radius: 500 }
struct Location: Codable {
enum CodingKeys: String, CodingKey {
case id, name, address, zipcode
case lat = "latitude"
case lon = "longitude"
}
let id: Int
let name: String
let lat: Double?
let lon: Double?
let address: String
let zipcode: String
}
But what if the keys don’t match?
Codable Performance
Codable Performance
func loadCodable() {
guard let data = getFileData()
else { return }
do {
let decoder = JSONDecoder()
let eventsResponse = try decoder.decode(EventsResponse.self, from: data)
showCompletion()
} catch {
print(error)
}
}
Codable Performance
func loadCodable() {
guard let data = getFileData()
else { return }
do {
let decoder = JSONDecoder()
let eventsResponse = try decoder.decode(EventsResponse.self, from: data)
showCompletion()
} catch {
print(error)
}
}
1.82 seconds to complete
Codable Performance
func loadCodable() {
guard let data = getFileData()
else { return }
do {
let decoder = JSONDecoder()
let eventsResponse = try decoder.decode(EventsResponse.self, from: data)
showCompletion()
} catch {
print(error)
}
}
1.82 seconds to complete
$😍
Codable and Date
struct DWDate: Codable {
let date: Date?
}
let jsonString = "{"date": "31-08-2017 +0000"}"
let json = jsonString.data(using: .utf8)!
do {
let decoder = JSONDecoder()
let formatter = DateFormatter()
formatter.dateFormat = "dd-MM-yyyy Z"
decoder.dateDecodingStrategy = .formatted(formatter)
let response = try decoder.decode(DWDate.self, from: json)
} catch {
print(error)
}
Codable and Date
struct DWDate: Codable {
let date: Date?
}
let jsonString = "{"date": ""}" //' ' '
let json = jsonString.data(using: .utf8)!
do {
let decoder = JSONDecoder()
let formatter = DateFormatter()
formatter.dateFormat = "dd-MM-yyyy Z"
decoder.dateDecodingStrategy = .formatted(formatter)
let response = try decoder.decode(DWDate.self, from: json)
} catch {
print(error)
}
Codable and Date
struct DWDate: Codable {
let date: Date?
}
let jsonString = "{"date": ""}" //' ' '
let json = jsonString.data(using: .utf8)!
do {
let decoder = JSONDecoder()
let formatter = DateFormatter()
formatter.dateFormat = "dd-MM-yyyy Z"
decoder.dateDecodingStrategy = .formatted(formatter)
let response = try decoder.decode(DWDate.self, from: json)
} catch {
print(error)
}
dataCorrupted(Swift.DecodingError.Context(codingPath:
[__lldb_expr_156.DWDate.(CodingKeys in
_995AD5D014A8F9E1965F4BEEB81F4E38).date], debugDescription: "Date
string does not match format expected by formatter.", underlyingError: nil))
Codable and Date
struct DWDate: Codable {
let date: Date?
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.date = try? container.decode(Date.self, forKey: .date)
}
}
What else should you know?
struct Prize: Codable {
enum PrizeType: Int, Codable {
case ticket = 1, voucher = 2
}
let name: String
let type: PrizeType
}
{
"name" : "Test",
"type" : 1
}
What else should you know?
let prize = Prize(name: "Test", type: .ticket)
let encoder = JSONEncoder()
let result = try! encoder.encode(prize)
{
"name" : "Test",
"type" : 1
}
What else should you know?
struct EventsResponse: Codable {
let events: [Event]
}
let eventsResponse = try decoder.decode([String: [Event]].self, from: data)
let eventsResponse = try decoder.decode(EventsResponse.self, from: data)
Concluding remarks
Concluding remarks
• Handling JSON with libraries can be convenient yet slow
Concluding remarks
• Handling JSON with libraries can be convenient yet slow
• The Codable protocol performs really well
Concluding remarks
• Handling JSON with libraries can be convenient yet slow
• The Codable protocol performs really well
• Optional date handling is a bit too strict IMO
Concluding remarks
• Handling JSON with libraries can be convenient yet slow
• The Codable protocol performs really well
• Optional date handling is a bit too strict IMO
• You can do really powerful things with Codable
Concluding remarks
• Handling JSON with libraries can be convenient yet slow
• The Codable protocol performs really well
• Optional date handling is a bit too strict IMO
• You can do really powerful things with Codable
http://benscheirman.com/2017/06/ultimate-guide-to-json-parsing-with-swift-4/
Thanks!

Weitere ähnliche Inhalte

Was ist angesagt?

PostgreSQL Open SV 2018
PostgreSQL Open SV 2018PostgreSQL Open SV 2018
PostgreSQL Open SV 2018artgillespie
 
Design how your objects talk through mocking
Design how your objects talk through mockingDesign how your objects talk through mocking
Design how your objects talk through mockingKonstantin Kudryashov
 
jQuery%20on%20Rails%20Presentation
jQuery%20on%20Rails%20PresentationjQuery%20on%20Rails%20Presentation
jQuery%20on%20Rails%20Presentationguestcf600a
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICKonstantin Kudryashov
 
Getting physical with web bluetooth in the browser
Getting physical with web bluetooth in the browserGetting physical with web bluetooth in the browser
Getting physical with web bluetooth in the browserDan Jenkins
 
Getting started with Elasticsearch and .NET
Getting started with Elasticsearch and .NETGetting started with Elasticsearch and .NET
Getting started with Elasticsearch and .NETTomas Jansson
 
Symfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worldsSymfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worldsIgnacio MartĂ­n
 
MongoDB .local Paris 2020: La puissance du Pipeline d'AgrĂŠgation de MongoDB
MongoDB .local Paris 2020: La puissance du Pipeline d'AgrĂŠgation de MongoDBMongoDB .local Paris 2020: La puissance du Pipeline d'AgrĂŠgation de MongoDB
MongoDB .local Paris 2020: La puissance du Pipeline d'AgrĂŠgation de MongoDBMongoDB
 
Url programming
Url programmingUrl programming
Url programmingvantinhkhuc
 
Is HTML5 Ready? (workshop)
Is HTML5 Ready? (workshop)Is HTML5 Ready? (workshop)
Is HTML5 Ready? (workshop)Remy Sharp
 
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you needDutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you needKacper Gunia
 
Guard Authentication: Powerful, Beautiful Security
Guard Authentication: Powerful, Beautiful SecurityGuard Authentication: Powerful, Beautiful Security
Guard Authentication: Powerful, Beautiful SecurityRyan Weaver
 
BDD, ATDD, Page Objects: The Road to Sustainable Web Testing
BDD, ATDD, Page Objects: The Road to Sustainable Web TestingBDD, ATDD, Page Objects: The Road to Sustainable Web Testing
BDD, ATDD, Page Objects: The Road to Sustainable Web TestingJohn Ferguson Smart Limited
 
The Ring programming language version 1.5.2 book - Part 39 of 181
The Ring programming language version 1.5.2 book - Part 39 of 181The Ring programming language version 1.5.2 book - Part 39 of 181
The Ring programming language version 1.5.2 book - Part 39 of 181Mahmoud Samir Fayed
 
The IoC Hydra
The IoC HydraThe IoC Hydra
The IoC HydraKacper Gunia
 
Beyond the DOM: Sane Structure for JS Apps
Beyond the DOM: Sane Structure for JS AppsBeyond the DOM: Sane Structure for JS Apps
Beyond the DOM: Sane Structure for JS AppsRebecca Murphey
 
Php sql-android
Php sql-androidPhp sql-android
Php sql-androidmaamir farooq
 

Was ist angesagt? (18)

PostgreSQL Open SV 2018
PostgreSQL Open SV 2018PostgreSQL Open SV 2018
PostgreSQL Open SV 2018
 
JQuery
JQueryJQuery
JQuery
 
Design how your objects talk through mocking
Design how your objects talk through mockingDesign how your objects talk through mocking
Design how your objects talk through mocking
 
jQuery%20on%20Rails%20Presentation
jQuery%20on%20Rails%20PresentationjQuery%20on%20Rails%20Presentation
jQuery%20on%20Rails%20Presentation
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DIC
 
Getting physical with web bluetooth in the browser
Getting physical with web bluetooth in the browserGetting physical with web bluetooth in the browser
Getting physical with web bluetooth in the browser
 
Getting started with Elasticsearch and .NET
Getting started with Elasticsearch and .NETGetting started with Elasticsearch and .NET
Getting started with Elasticsearch and .NET
 
Symfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worldsSymfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worlds
 
MongoDB .local Paris 2020: La puissance du Pipeline d'AgrĂŠgation de MongoDB
MongoDB .local Paris 2020: La puissance du Pipeline d'AgrĂŠgation de MongoDBMongoDB .local Paris 2020: La puissance du Pipeline d'AgrĂŠgation de MongoDB
MongoDB .local Paris 2020: La puissance du Pipeline d'AgrĂŠgation de MongoDB
 
Url programming
Url programmingUrl programming
Url programming
 
Is HTML5 Ready? (workshop)
Is HTML5 Ready? (workshop)Is HTML5 Ready? (workshop)
Is HTML5 Ready? (workshop)
 
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you needDutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
 
Guard Authentication: Powerful, Beautiful Security
Guard Authentication: Powerful, Beautiful SecurityGuard Authentication: Powerful, Beautiful Security
Guard Authentication: Powerful, Beautiful Security
 
BDD, ATDD, Page Objects: The Road to Sustainable Web Testing
BDD, ATDD, Page Objects: The Road to Sustainable Web TestingBDD, ATDD, Page Objects: The Road to Sustainable Web Testing
BDD, ATDD, Page Objects: The Road to Sustainable Web Testing
 
The Ring programming language version 1.5.2 book - Part 39 of 181
The Ring programming language version 1.5.2 book - Part 39 of 181The Ring programming language version 1.5.2 book - Part 39 of 181
The Ring programming language version 1.5.2 book - Part 39 of 181
 
The IoC Hydra
The IoC HydraThe IoC Hydra
The IoC Hydra
 
Beyond the DOM: Sane Structure for JS Apps
Beyond the DOM: Sane Structure for JS AppsBeyond the DOM: Sane Structure for JS Apps
Beyond the DOM: Sane Structure for JS Apps
 
Php sql-android
Php sql-androidPhp sql-android
Php sql-android
 

Ähnlich wie JSON and Swift, Still A Better Love Story Than Twilight

Is html5-ready-workshop-110727181512-phpapp02
Is html5-ready-workshop-110727181512-phpapp02Is html5-ready-workshop-110727181512-phpapp02
Is html5-ready-workshop-110727181512-phpapp02PL dream
 
Typescript - why it's awesome
Typescript - why it's awesomeTypescript - why it's awesome
Typescript - why it's awesomePiotr Miazga
 
Data analysis and visualization with mongo db [mongodb world 2016]
Data analysis and visualization with mongo db [mongodb world 2016]Data analysis and visualization with mongo db [mongodb world 2016]
Data analysis and visualization with mongo db [mongodb world 2016]Alexander Hendorf
 
Persisting Data on SQLite using Room
Persisting Data on SQLite using RoomPersisting Data on SQLite using Room
Persisting Data on SQLite using RoomNelson Glauber Leal
 
CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on AndroidSven Haiges
 
Realm.io par Clement Sauvage
Realm.io par Clement SauvageRealm.io par Clement Sauvage
Realm.io par Clement SauvageCocoaHeads France
 
CSV JSON and XML files in Python.pptx
CSV JSON and XML files in Python.pptxCSV JSON and XML files in Python.pptx
CSV JSON and XML files in Python.pptxRamakrishna Reddy Bijjam
 
Browsers with Wings
Browsers with WingsBrowsers with Wings
Browsers with WingsRemy Sharp
 
Data mangling with mongo db the right way [pyconit 2016]
Data mangling with mongo db the right way [pyconit 2016]Data mangling with mongo db the right way [pyconit 2016]
Data mangling with mongo db the right way [pyconit 2016]Alexander Hendorf
 
Cross Domain Web
Mashups with JQuery and Google App Engine
Cross Domain Web
Mashups with JQuery and Google App EngineCross Domain Web
Mashups with JQuery and Google App Engine
Cross Domain Web
Mashups with JQuery and Google App EngineAndy McKay
 
Introduction to ECMAScript 2015
Introduction to ECMAScript 2015Introduction to ECMAScript 2015
Introduction to ECMAScript 2015Tomasz Dziuda
 
SFScon17 - Patrick Puecher: "Exploring data with Elasticsearch and Kibana"
SFScon17 - Patrick Puecher: "Exploring data with Elasticsearch and Kibana"SFScon17 - Patrick Puecher: "Exploring data with Elasticsearch and Kibana"
SFScon17 - Patrick Puecher: "Exploring data with Elasticsearch and Kibana"South Tyrol Free Software Conference
 
Trivadis TechEvent 2016 Polybase challenges Hive relational access to non-rel...
Trivadis TechEvent 2016 Polybase challenges Hive relational access to non-rel...Trivadis TechEvent 2016 Polybase challenges Hive relational access to non-rel...
Trivadis TechEvent 2016 Polybase challenges Hive relational access to non-rel...Trivadis
 
Eve - REST API for Humans™
Eve - REST API for Humans™Eve - REST API for Humans™
Eve - REST API for Humans™Nicola Iarocci
 
Working with the Web: 
Decoding JSON
Working with the Web: 
Decoding JSONWorking with the Web: 
Decoding JSON
Working with the Web: 
Decoding JSONSV.CO
 
Leveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHPLeveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHPJeremy Kendall
 
Functional programming using underscorejs
Functional programming using underscorejsFunctional programming using underscorejs
Functional programming using underscorejs偉格 高
 
Swipe 2011 - iOS Gems
Swipe 2011 - iOS GemsSwipe 2011 - iOS Gems
Swipe 2011 - iOS GemsKevin O'Neill
 
Das Web Wird Mobil - Geolocation und Location Based Services
Das Web Wird Mobil - Geolocation und Location Based ServicesDas Web Wird Mobil - Geolocation und Location Based Services
Das Web Wird Mobil - Geolocation und Location Based ServicesStephan Schmidt
 

Ähnlich wie JSON and Swift, Still A Better Love Story Than Twilight (20)

Is html5-ready-workshop-110727181512-phpapp02
Is html5-ready-workshop-110727181512-phpapp02Is html5-ready-workshop-110727181512-phpapp02
Is html5-ready-workshop-110727181512-phpapp02
 
Typescript - why it's awesome
Typescript - why it's awesomeTypescript - why it's awesome
Typescript - why it's awesome
 
Data analysis and visualization with mongo db [mongodb world 2016]
Data analysis and visualization with mongo db [mongodb world 2016]Data analysis and visualization with mongo db [mongodb world 2016]
Data analysis and visualization with mongo db [mongodb world 2016]
 
Persisting Data on SQLite using Room
Persisting Data on SQLite using RoomPersisting Data on SQLite using Room
Persisting Data on SQLite using Room
 
CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on Android
 
Realm.io par Clement Sauvage
Realm.io par Clement SauvageRealm.io par Clement Sauvage
Realm.io par Clement Sauvage
 
CSV JSON and XML files in Python.pptx
CSV JSON and XML files in Python.pptxCSV JSON and XML files in Python.pptx
CSV JSON and XML files in Python.pptx
 
Browsers with Wings
Browsers with WingsBrowsers with Wings
Browsers with Wings
 
Data mangling with mongo db the right way [pyconit 2016]
Data mangling with mongo db the right way [pyconit 2016]Data mangling with mongo db the right way [pyconit 2016]
Data mangling with mongo db the right way [pyconit 2016]
 
Cross Domain Web
Mashups with JQuery and Google App Engine
Cross Domain Web
Mashups with JQuery and Google App EngineCross Domain Web
Mashups with JQuery and Google App Engine
Cross Domain Web
Mashups with JQuery and Google App Engine
 
Introduction to ECMAScript 2015
Introduction to ECMAScript 2015Introduction to ECMAScript 2015
Introduction to ECMAScript 2015
 
SFScon17 - Patrick Puecher: "Exploring data with Elasticsearch and Kibana"
SFScon17 - Patrick Puecher: "Exploring data with Elasticsearch and Kibana"SFScon17 - Patrick Puecher: "Exploring data with Elasticsearch and Kibana"
SFScon17 - Patrick Puecher: "Exploring data with Elasticsearch and Kibana"
 
Trivadis TechEvent 2016 Polybase challenges Hive relational access to non-rel...
Trivadis TechEvent 2016 Polybase challenges Hive relational access to non-rel...Trivadis TechEvent 2016 Polybase challenges Hive relational access to non-rel...
Trivadis TechEvent 2016 Polybase challenges Hive relational access to non-rel...
 
Eve - REST API for Humans™
Eve - REST API for Humans™Eve - REST API for Humans™
Eve - REST API for Humans™
 
Working with the Web: 
Decoding JSON
Working with the Web: 
Decoding JSONWorking with the Web: 
Decoding JSON
Working with the Web: 
Decoding JSON
 
Leveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHPLeveraging the Power of Graph Databases in PHP
Leveraging the Power of Graph Databases in PHP
 
Functional programming using underscorejs
Functional programming using underscorejsFunctional programming using underscorejs
Functional programming using underscorejs
 
Swipe 2011 - iOS Gems
Swipe 2011 - iOS GemsSwipe 2011 - iOS Gems
Swipe 2011 - iOS Gems
 
Das Web Wird Mobil - Geolocation und Location Based Services
Das Web Wird Mobil - Geolocation und Location Based ServicesDas Web Wird Mobil - Geolocation und Location Based Services
Das Web Wird Mobil - Geolocation und Location Based Services
 
Parse.com
Parse.comParse.com
Parse.com
 

Mehr von Donny Wals

Your 🧠 on Swift Concurrency
Your 🧠 on Swift ConcurrencyYour 🧠 on Swift Concurrency
Your 🧠 on Swift ConcurrencyDonny Wals
 
Using Combine, SwiftUI and callAsFunction to build an experimental localizati...
Using Combine, SwiftUI and callAsFunction to build an experimental localizati...Using Combine, SwiftUI and callAsFunction to build an experimental localizati...
Using Combine, SwiftUI and callAsFunction to build an experimental localizati...Donny Wals
 
The combine triad
The combine triadThe combine triad
The combine triadDonny Wals
 
Building reusable components with generics and protocols
Building reusable components with generics and protocolsBuilding reusable components with generics and protocols
Building reusable components with generics and protocolsDonny Wals
 
Adopting tdd in the workplace
Adopting tdd in the workplaceAdopting tdd in the workplace
Adopting tdd in the workplaceDonny Wals
 
Me and my importers
Me and my importersMe and my importers
Me and my importersDonny Wals
 
Adopting tdd in the workplace
Adopting tdd in the workplaceAdopting tdd in the workplace
Adopting tdd in the workplaceDonny Wals
 
In Defense Of Core Data
In Defense Of Core DataIn Defense Of Core Data
In Defense Of Core DataDonny Wals
 
Effectively Producing And Shipping Frameworks For Multiple Platforms
Effectively Producing And Shipping Frameworks For Multiple PlatformsEffectively Producing And Shipping Frameworks For Multiple Platforms
Effectively Producing And Shipping Frameworks For Multiple PlatformsDonny Wals
 
Talk - git task managers and ci
Talk - git task managers and ciTalk - git task managers and ci
Talk - git task managers and ciDonny Wals
 
Developing in the Fastlane -> How LookLive uses Fastlane to automate and spee...
Developing in the Fastlane -> How LookLive uses Fastlane to automate and spee...Developing in the Fastlane -> How LookLive uses Fastlane to automate and spee...
Developing in the Fastlane -> How LookLive uses Fastlane to automate and spee...Donny Wals
 
Marketing strategie Arto
Marketing strategie ArtoMarketing strategie Arto
Marketing strategie ArtoDonny Wals
 
Hoorcollege Flash 9-2-2012
Hoorcollege Flash 9-2-2012Hoorcollege Flash 9-2-2012
Hoorcollege Flash 9-2-2012Donny Wals
 

Mehr von Donny Wals (13)

Your 🧠 on Swift Concurrency
Your 🧠 on Swift ConcurrencyYour 🧠 on Swift Concurrency
Your 🧠 on Swift Concurrency
 
Using Combine, SwiftUI and callAsFunction to build an experimental localizati...
Using Combine, SwiftUI and callAsFunction to build an experimental localizati...Using Combine, SwiftUI and callAsFunction to build an experimental localizati...
Using Combine, SwiftUI and callAsFunction to build an experimental localizati...
 
The combine triad
The combine triadThe combine triad
The combine triad
 
Building reusable components with generics and protocols
Building reusable components with generics and protocolsBuilding reusable components with generics and protocols
Building reusable components with generics and protocols
 
Adopting tdd in the workplace
Adopting tdd in the workplaceAdopting tdd in the workplace
Adopting tdd in the workplace
 
Me and my importers
Me and my importersMe and my importers
Me and my importers
 
Adopting tdd in the workplace
Adopting tdd in the workplaceAdopting tdd in the workplace
Adopting tdd in the workplace
 
In Defense Of Core Data
In Defense Of Core DataIn Defense Of Core Data
In Defense Of Core Data
 
Effectively Producing And Shipping Frameworks For Multiple Platforms
Effectively Producing And Shipping Frameworks For Multiple PlatformsEffectively Producing And Shipping Frameworks For Multiple Platforms
Effectively Producing And Shipping Frameworks For Multiple Platforms
 
Talk - git task managers and ci
Talk - git task managers and ciTalk - git task managers and ci
Talk - git task managers and ci
 
Developing in the Fastlane -> How LookLive uses Fastlane to automate and spee...
Developing in the Fastlane -> How LookLive uses Fastlane to automate and spee...Developing in the Fastlane -> How LookLive uses Fastlane to automate and spee...
Developing in the Fastlane -> How LookLive uses Fastlane to automate and spee...
 
Marketing strategie Arto
Marketing strategie ArtoMarketing strategie Arto
Marketing strategie Arto
 
Hoorcollege Flash 9-2-2012
Hoorcollege Flash 9-2-2012Hoorcollege Flash 9-2-2012
Hoorcollege Flash 9-2-2012
 

KĂźrzlich hochgeladen

Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...kalichargn70th171
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplatePresentation.STUDIO
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionSolGuruz
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE9953056974 Low Rate Call Girls In Saket, Delhi NCR
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesVictorSzoltysek
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfWilly Marroquin (WillyDevNET)
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension AidPhilip Schwarz
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsJhone kinadey
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxComplianceQuest1
 
How to Choose the Right Laravel Development Partner in New York City_compress...
How to Choose the Right Laravel Development Partner in New York City_compress...How to Choose the Right Laravel Development Partner in New York City_compress...
How to Choose the Right Laravel Development Partner in New York City_compress...software pro Development
 
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfAzure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfryanfarris8
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionOnePlan Solutions
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech studentsHimanshiGarg82
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 

KĂźrzlich hochgeladen (20)

Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM TechniquesAI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
AI Mastery 201: Elevating Your Workflow with Advanced LLM Techniques
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
How to Choose the Right Laravel Development Partner in New York City_compress...
How to Choose the Right Laravel Development Partner in New York City_compress...How to Choose the Right Laravel Development Partner in New York City_compress...
How to Choose the Right Laravel Development Partner in New York City_compress...
 
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfAzure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
 
8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students8257 interfacing 2 in microprocessor for btech students
8257 interfacing 2 in microprocessor for btech students
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 

JSON and Swift, Still A Better Love Story Than Twilight

  • 1.
  • 2. Hi, I’m Donny. I build iOS apps.
  • 3. Hi, I’m Donny. I build iOS apps.
  • 5. JSON and Swift… Still A Better Love Story Than Twilight
  • 6. Topics • Pre-Swift 4.0 JSON handling • Some things I learned about JSON pre-Swift 4.0 • Handling JSON in Swift 4.0 • Concluding remarks
  • 7. Pre-Swift 4.0 JSON Handling { "items": [{ "line_up": [{ "artist": { "name": "Foo" } }] }] } JSON File:
  • 8. Pre-Swift 4.0 JSON Handling { "items": [{ "line_up": [{ "artist": { "name": "Foo" } }] }] } JSON File: Swift 1.0: if let items = json["items"] as? [[String: AnyObject]] { if let rstItem = items.rst { if let item = rstItem as? [String: AnyObject] { if let lineUp = item["line_up"] as? [[String: AnyObject]] { if let rstLineupItem = lineUp.rst { if let artist = rstLineupItem["artist"] as? [String: AnyObject] { if let name = artist["name"] as? String { print(name) } } } } } } }
  • 9. Pre-Swift 4.0 JSON Handling { "items": [{ "line_up": [{ "artist": { "name": "Foo" } }] }] } JSON File: Swift 2.0: guard let items = json["items"] as? [String: Any], let rstItem = items.rst, let item = rstItem as? [String: Any], let lineUp = rstItem["line_up"] as? [[String: Any]], let rstLineUpItem = lineUp.rst, let artist = rstLineUpItem["artist"] as? [String: Any], let name = artist["name"] as? String else { return } print(name)
  • 10. Pre-Swift 4.0 JSON Handling { "items": [{ "line_up": [{ "artist": { "name": "Foo" } }] }] } JSON File: SwiftyJSON guard let item = json["items"].arrayValue.rst, let lineUpItem = item["line_up"].arrayValue.rst, let name = lineUpItem["artist"]["name"].string else { return } print(name)
  • 11. SwiftyJSON is amazing! guard let item = json["items"].arrayValue.rst, let lineUpItem = item["line_up"].arrayValue.rst, let name = lineUpItem["artist"]["name"].string else { return } print(name) 😍
  • 12. SwiftyJSON is amazing! guard let item = json["items"].arrayValue.rst, let lineUpItem = item["line_up"].arrayValue.rst, let name = lineUpItem["artist"]["name"].string else { return } print(name) 😍
  • 14. A performance test { id: 260, name: 'DAS Foute Oktoberfest 20171', start: '2017-02-20T16:00:00+0000', end: '2017-10-07T23:59:00+0000', publish_from: '2016-11-09T08:00:00+0000', publish_to: '2017-10-07T23:59:00+0000', categories: [ { id: 2, name: 'NAME GOES HERE' } ], location: { name: 'Goffertpark, Nijmegen (NL)', address: '', zipcode: '1234AB', city: 'Nijmegen', state: 'Noord-whateverland', country: 'NL', latitude: 51.82548, longitude: 5.836629, url: 'https://www.google.nl/maps/place/Goffertpark/@52.2576689,5.2644167,8.25z/data=!4m5!3m4! 1s0x47c7089b2ce7dff1:0xfd37f35c5b91b9c8!8m2!3d51.8255586!4d5.8366532', email: 'random@email.com', id: 169, radius: 500 }, line_up: [ { id: 1, name: 'nino' }, { id: 2, name: 'lisa' }, { id: 7, name: 'kees' }, { id: 4, name: 'Rodney' }, { id: 8, name: 'Oscar' }, { id: 9, name: 'Dick' } ], description: 'Matrixx presenteert Het Foute Oktoberfest 2017!rnrnZaterdag 7 oktober in een grote feesttent op de Goffertweide in Nijmegen. rnrnBinnenkort meer info!', image_url: 'http://app.appimin.com/lelib/storage/events/58246fa620305_het-foute-oktoberfest-2017.jpg' }
  • 15. A performance test { id: 260, name: 'DAS Foute Oktoberfest 20171', start: '2017-02-20T16:00:00+0000', end: '2017-10-07T23:59:00+0000', publish_from: '2016-11-09T08:00:00+0000', publish_to: '2017-10-07T23:59:00+0000', categories: [ { id: 2, name: 'NAME GOES HERE' } ], location: { name: 'Goffertpark, Nijmegen (NL)', address: '', zipcode: '1234AB', city: 'Nijmegen', state: 'Noord-whateverland', country: 'NL', latitude: 51.82548, longitude: 5.836629, url: 'https://www.google.nl/maps/place/Goffertpark/@52.2576689,5.2644167,8.25z/data=!4m5!3m4! 1s0x47c7089b2ce7dff1:0xfd37f35c5b91b9c8!8m2!3d51.8255586!4d5.8366532', email: 'random@email.com', id: 169, radius: 500 }, line_up: [ { id: 1, name: 'nino' }, { id: 2, name: 'lisa' }, { id: 7, name: 'kees' }, { id: 4, name: 'Rodney' }, { id: 8, name: 'Oscar' }, { id: 9, name: 'Dick' } ], description: 'Matrixx presenteert Het Foute Oktoberfest 2017!rnrnZaterdag 7 oktober in een grote feesttent op de Goffertweide in Nijmegen. rnrnBinnenkort meer info!', image_url: 'http://app.appimin.com/lelib/storage/events/58246fa620305_het-foute-oktoberfest-2017.jpg' } • 2080 events
  • 16. A performance test { id: 260, name: 'DAS Foute Oktoberfest 20171', start: '2017-02-20T16:00:00+0000', end: '2017-10-07T23:59:00+0000', publish_from: '2016-11-09T08:00:00+0000', publish_to: '2017-10-07T23:59:00+0000', categories: [ { id: 2, name: 'NAME GOES HERE' } ], location: { name: 'Goffertpark, Nijmegen (NL)', address: '', zipcode: '1234AB', city: 'Nijmegen', state: 'Noord-whateverland', country: 'NL', latitude: 51.82548, longitude: 5.836629, url: 'https://www.google.nl/maps/place/Goffertpark/@52.2576689,5.2644167,8.25z/data=!4m5!3m4! 1s0x47c7089b2ce7dff1:0xfd37f35c5b91b9c8!8m2!3d51.8255586!4d5.8366532', email: 'random@email.com', id: 169, radius: 500 }, line_up: [ { id: 1, name: 'nino' }, { id: 2, name: 'lisa' }, { id: 7, name: 'kees' }, { id: 4, name: 'Rodney' }, { id: 8, name: 'Oscar' }, { id: 9, name: 'Dick' } ], description: 'Matrixx presenteert Het Foute Oktoberfest 2017!rnrnZaterdag 7 oktober in een grote feesttent op de Goffertweide in Nijmegen. rnrnBinnenkort meer info!', image_url: 'http://app.appimin.com/lelib/storage/events/58246fa620305_het-foute-oktoberfest-2017.jpg' } • 2080 events • Nested objects
  • 17. A performance test { id: 260, name: 'DAS Foute Oktoberfest 20171', start: '2017-02-20T16:00:00+0000', end: '2017-10-07T23:59:00+0000', publish_from: '2016-11-09T08:00:00+0000', publish_to: '2017-10-07T23:59:00+0000', categories: [ { id: 2, name: 'NAME GOES HERE' } ], location: { name: 'Goffertpark, Nijmegen (NL)', address: '', zipcode: '1234AB', city: 'Nijmegen', state: 'Noord-whateverland', country: 'NL', latitude: 51.82548, longitude: 5.836629, url: 'https://www.google.nl/maps/place/Goffertpark/@52.2576689,5.2644167,8.25z/data=!4m5!3m4! 1s0x47c7089b2ce7dff1:0xfd37f35c5b91b9c8!8m2!3d51.8255586!4d5.8366532', email: 'random@email.com', id: 169, radius: 500 }, line_up: [ { id: 1, name: 'nino' }, { id: 2, name: 'lisa' }, { id: 7, name: 'kees' }, { id: 4, name: 'Rodney' }, { id: 8, name: 'Oscar' }, { id: 9, name: 'Dick' } ], description: 'Matrixx presenteert Het Foute Oktoberfest 2017!rnrnZaterdag 7 oktober in een grote feesttent op de Goffertweide in Nijmegen. rnrnBinnenkort meer info!', image_url: 'http://app.appimin.com/lelib/storage/events/58246fa620305_het-foute-oktoberfest-2017.jpg' } • 2080 events • Nested objects • Tested on iPhone 5c
  • 19. A performance test func loadSwifty() { guard let data = getFileData() else { return } let jsonFile = JSON(data: data) for eventJSON in jsonFile["events"].arrayValue { let location = Location(id: eventJSON["location"]["id"].intValue, name: eventJSON["location"]["name"].stringValue, lat: eventJSON["location"]["latitude"].double, lon: eventJSON[“location"]["longitude"].double, address: eventJSON["location"]["address"].stringValue, zipcode: eventJSON[“location"]["zipcode"].stringValue) // etc. } showCompletion() }
  • 20. A performance test func loadSwifty() { guard let data = getFileData() else { return } let jsonFile = JSON(data: data) for eventJSON in jsonFile["events"].arrayValue { let location = Location(id: eventJSON["location"]["id"].intValue, name: eventJSON["location"]["name"].stringValue, lat: eventJSON["location"]["latitude"].double, lon: eventJSON[“location"]["longitude"].double, address: eventJSON["location"]["address"].stringValue, zipcode: eventJSON[“location"]["zipcode"].stringValue) // etc. } showCompletion() } 6.76 seconds to complete
  • 21. A performance test func loadSwifty() { guard let data = getFileData() else { return } let jsonFile = JSON(data: data) for eventJSON in jsonFile["events"].arrayValue { let location = Location(id: eventJSON["location"]["id"].intValue, name: eventJSON["location"]["name"].stringValue, lat: eventJSON["location"]["latitude"].double, lon: eventJSON[“location"]["longitude"].double, address: eventJSON["location"]["address"].stringValue, zipcode: eventJSON[“location"]["zipcode"].stringValue) // etc. } showCompletion() } 6.76 seconds to complete "😭
  • 23. A performance test func loadNormal() { guard let data = getFileData(), let jsonObject = try? JSONSerialization.jsonObject(with: data, options: []), let json = jsonObject as? DWJSON, let events = json["events"] as? [DWJSON] else { return } for eventJSON in events { guard let locationJSON = eventJSON["location"] as? DWJSON, let categoriesJSON = eventJSON["categories"] as? [DWJSON], let lineUpJSON = eventJSON["line_up"] as? [DWJSON] else { return } // etc. } showCompletion() }
  • 24. A performance test func loadNormal() { guard let data = getFileData(), let jsonObject = try? JSONSerialization.jsonObject(with: data, options: []), let json = jsonObject as? DWJSON, let events = json["events"] as? [DWJSON] else { return } for eventJSON in events { guard let locationJSON = eventJSON["location"] as? DWJSON, let categoriesJSON = eventJSON["categories"] as? [DWJSON], let lineUpJSON = eventJSON["line_up"] as? [DWJSON] else { return } // etc. } showCompletion() } 1.84 seconds to complete
  • 25. A performance test func loadNormal() { guard let data = getFileData(), let jsonObject = try? JSONSerialization.jsonObject(with: data, options: []), let json = jsonObject as? DWJSON, let events = json["events"] as? [DWJSON] else { return } for eventJSON in events { guard let locationJSON = eventJSON["location"] as? DWJSON, let categoriesJSON = eventJSON["categories"] as? [DWJSON], let lineUpJSON = eventJSON["line_up"] as? [DWJSON] else { return } // etc. } showCompletion() } 1.84 seconds to complete $😍
  • 26. What did I learn?
  • 27. What did I learn? • Be careful about libraries that make things easy; they might be (very) slow.
  • 28. What did I learn? • Be careful about libraries that make things easy; they might be (very) slow. • Sometimes uglier code is faster (unfortunately).
  • 29. What did I learn? • Be careful about libraries that make things easy; they might be (very) slow. • Sometimes uglier code is faster (unfortunately). • Working with JSON isn’t as bad as it seems in Swift 2.0+.
  • 30. What about Swift 4.0? ❓&❓
  • 32. Introducing Codable struct Category { let id: Int let name: String } let category = Category(id: categoryJSON["id"] as? Int ?? 0, name: categoryJSON["name"] as? String ?? "") < Swift 4.0
  • 33. Introducing Codable struct Category { let id: Int let name: String } let category = Category(id: categoryJSON["id"] as? Int ?? 0, name: categoryJSON["name"] as? String ?? "") < Swift 4.0 struct Category: Codable { let id: Int let name: String } Swift 4.0 let decoder = JSONDecoder() let category = try? decoder.decode(Category.self, from: data)
  • 34. Introducing Codable struct Category { let id: Int let name: String } let category = Category(id: categoryJSON["id"] as? Int ?? 0, name: categoryJSON["name"] as? String ?? "") < Swift 4.0 struct Category: Codable { let id: Int let name: String } Swift 4.0 let decoder = JSONDecoder() let category = try? decoder.decode(Category.self, from: data) Property names are directly mapped to JSON keys
  • 35. Introducing Codable But what if the keys don’t match?
  • 36. Introducing Codable location: { name: 'Goffertpark, Nijmegen (NL)', address: '', zipcode: '1234AB', city: 'Nijmegen', state: 'Noord-whateverland', country: 'NL', latitude: 51.82548, longitude: 5.836629, url: ‘https://www.google.nl/', email: 'random@email.com', id: 169, radius: 500 } But what if the keys don’t match?
  • 37. Introducing Codable location: { name: 'Goffertpark, Nijmegen (NL)', address: '', zipcode: '1234AB', city: 'Nijmegen', state: 'Noord-whateverland', country: 'NL', latitude: 51.82548, longitude: 5.836629, url: ‘https://www.google.nl/', email: 'random@email.com', id: 169, radius: 500 } But what if the keys don’t match?
  • 38. Introducing Codable location: { name: 'Goffertpark, Nijmegen (NL)', address: '', zipcode: '1234AB', city: 'Nijmegen', state: 'Noord-whateverland', country: 'NL', latitude: 51.82548, longitude: 5.836629, url: ‘https://www.google.nl/', email: 'random@email.com', id: 169, radius: 500 } struct Location { let id: Int let name: String let lat: Double? let lon: Double? let address: String let zipcode: String } But what if the keys don’t match?
  • 39. Introducing Codable location: { name: 'Goffertpark, Nijmegen (NL)', address: '', zipcode: '1234AB', city: 'Nijmegen', state: 'Noord-whateverland', country: 'NL', latitude: 51.82548, longitude: 5.836629, url: ‘https://www.google.nl/', email: 'random@email.com', id: 169, radius: 500 } struct Location: Codable { enum CodingKeys: String, CodingKey { case id, name, address, zipcode case lat = "latitude" case lon = "longitude" } let id: Int let name: String let lat: Double? let lon: Double? let address: String let zipcode: String } But what if the keys don’t match?
  • 41. Codable Performance func loadCodable() { guard let data = getFileData() else { return } do { let decoder = JSONDecoder() let eventsResponse = try decoder.decode(EventsResponse.self, from: data) showCompletion() } catch { print(error) } }
  • 42. Codable Performance func loadCodable() { guard let data = getFileData() else { return } do { let decoder = JSONDecoder() let eventsResponse = try decoder.decode(EventsResponse.self, from: data) showCompletion() } catch { print(error) } } 1.82 seconds to complete
  • 43. Codable Performance func loadCodable() { guard let data = getFileData() else { return } do { let decoder = JSONDecoder() let eventsResponse = try decoder.decode(EventsResponse.self, from: data) showCompletion() } catch { print(error) } } 1.82 seconds to complete $😍
  • 44. Codable and Date struct DWDate: Codable { let date: Date? } let jsonString = "{"date": "31-08-2017 +0000"}" let json = jsonString.data(using: .utf8)! do { let decoder = JSONDecoder() let formatter = DateFormatter() formatter.dateFormat = "dd-MM-yyyy Z" decoder.dateDecodingStrategy = .formatted(formatter) let response = try decoder.decode(DWDate.self, from: json) } catch { print(error) }
  • 45. Codable and Date struct DWDate: Codable { let date: Date? } let jsonString = "{"date": ""}" //' ' ' let json = jsonString.data(using: .utf8)! do { let decoder = JSONDecoder() let formatter = DateFormatter() formatter.dateFormat = "dd-MM-yyyy Z" decoder.dateDecodingStrategy = .formatted(formatter) let response = try decoder.decode(DWDate.self, from: json) } catch { print(error) }
  • 46. Codable and Date struct DWDate: Codable { let date: Date? } let jsonString = "{"date": ""}" //' ' ' let json = jsonString.data(using: .utf8)! do { let decoder = JSONDecoder() let formatter = DateFormatter() formatter.dateFormat = "dd-MM-yyyy Z" decoder.dateDecodingStrategy = .formatted(formatter) let response = try decoder.decode(DWDate.self, from: json) } catch { print(error) } dataCorrupted(Swift.DecodingError.Context(codingPath: [__lldb_expr_156.DWDate.(CodingKeys in _995AD5D014A8F9E1965F4BEEB81F4E38).date], debugDescription: "Date string does not match format expected by formatter.", underlyingError: nil))
  • 47. Codable and Date struct DWDate: Codable { let date: Date? init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) self.date = try? container.decode(Date.self, forKey: .date) } }
  • 48. What else should you know? struct Prize: Codable { enum PrizeType: Int, Codable { case ticket = 1, voucher = 2 } let name: String let type: PrizeType } { "name" : "Test", "type" : 1 }
  • 49. What else should you know? let prize = Prize(name: "Test", type: .ticket) let encoder = JSONEncoder() let result = try! encoder.encode(prize) { "name" : "Test", "type" : 1 }
  • 50. What else should you know? struct EventsResponse: Codable { let events: [Event] } let eventsResponse = try decoder.decode([String: [Event]].self, from: data) let eventsResponse = try decoder.decode(EventsResponse.self, from: data)
  • 52. Concluding remarks • Handling JSON with libraries can be convenient yet slow
  • 53. Concluding remarks • Handling JSON with libraries can be convenient yet slow • The Codable protocol performs really well
  • 54. Concluding remarks • Handling JSON with libraries can be convenient yet slow • The Codable protocol performs really well • Optional date handling is a bit too strict IMO
  • 55. Concluding remarks • Handling JSON with libraries can be convenient yet slow • The Codable protocol performs really well • Optional date handling is a bit too strict IMO • You can do really powerful things with Codable
  • 56. Concluding remarks • Handling JSON with libraries can be convenient yet slow • The Codable protocol performs really well • Optional date handling is a bit too strict IMO • You can do really powerful things with Codable http://benscheirman.com/2017/06/ultimate-guide-to-json-parsing-with-swift-4/