SlideShare a Scribd company logo
1 of 42
Download to read offline
ABOUTOBJECTS
Streamlining
JSON Mapping
Jonathan Lehr, Founder and VP, Training
Copyright © 2016, About Objects, Inc. 1
About Objects
• Reston, VA
• Full-stack consulting and training
• Roots in NeXT, OpenStep, WebObjects +
enterprise middleware and backend
• iOS from day one
Copyright © 2016, About Objects, Inc. 2
So Many Frameworks
Number of hits yielded by a recent Github
search for swift json:
576Seems it's on a lot of peoples' radar.
Copyright © 2016, About Objects, Inc. 3
Automating Encode/Decode
{ "book_id": 42,
"title": "The Time Machine",
"rating": 3 }
public class Book: NSObject {
public var bookId: Int
public var title: String?
public var rating: Rating?
}
1. Map keys to property names
2. Perform value transformations
3. Encode and decode model objects
Copyright © 2016, About Objects, Inc. 4
book n
author
array
…book 1
JSON <--> Object Graph
{ "author_id": 98,
"first_name": "H. G.",
"last_name": "Wells",
"books": [
{ "book_id": 42,
"title": "The Time Machine",
"rating": 3 },
...
Copyright © 2016, About Objects, Inc. 5
Mapping Frameworks
You define mappings programmatically by:
• Defining mappings per property in code
(ObjectMapper, SwiftJSON)
• Providing dictionaries of mappings per class
(RestKit)
Copyright © 2016, About Objects, Inc. 6
RestKit Example
RKObjectMapping *bookMapping = [RKObjectMapping mappingForClass:Book.class];
[bookMapping addAttributeMappingsFromDictionary:@{
@"book_id": @"bookId",
@"title": @"title",
@"rating": @"rating",
}];
RKResponseDescriptor *descriptor = [RKResponseDescriptor
responseDescriptorWithMapping:bookMapping
method:RKRequestMethodAny
pathPattern:nil
keyPath:@"books"
statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
Copyright © 2016, About Objects, Inc. 7
ObjectMapper Example
class Book: Mappable {
public var bookId: Int
public var title: String?
public var rating: Rating?
required init?(_ map: Map) {
}
// Mappable
func mapping(map: Map) {
bookId <- map["book_id"]
title <- map["title"]
rating <- map["rating"]
}
}
Copyright © 2016, About Objects, Inc. 8
Issues
• Maintenance is awkward
• Model hard to visualize
• Strings in code reduce safety
Copyright © 2016, About Objects, Inc. 9
The
Modelmatic
Framework
www.github.com/AboutObjects/modelmatic
Copyright © 2016, About Objects, Inc. 10
Model Needs to Capture:
• Relationship info: to-many, target type
• Nice to have: inverse relationships
• Mapping keys to property names
• Value transformations
Copyright © 2016, About Objects, Inc. 11
Framework Needs to:
• Traverse relationships defined in model
• Construct nested objects
• Use introspection to get and set values
• Map keys and transform values
Do all the above without manual coding
(except for custom transformations)
Copyright © 2016, About Objects, Inc. 12
Core Data Model Editor
• Awesome tool for data modeling
• Defines mappings in a visual format
• Framework-level programmatic access
But wait, it's only for Core Data, right?
Heh, heh
Copyright © 2016, About Objects, Inc. 13
Managed Object Model (MOM)
• Defines mappings between model objects
and their external data representation
• Designed to support relational databases
(object-relational mapping)
• Can be loaded as NSManagedObjectModel
instance at runtime
Copyright © 2016, About Objects, Inc. 14
Entities
• Metadata description of domain object
• Lists two kinds of properties: attributes and
relationships
• Defines mapping between JSON dictionary
and Swift class
• Instances of NSEntityDescription in
NSManagedObjectModel
Copyright © 2016, About Objects, Inc. 15
Attributes
• Metadata descriptions of individual values
• Define mappings between data elements and
Swift properties
• Instances of NSAttributeDescription in
NSEntityDescription
Copyright © 2016, About Objects, Inc. 16
Relationships
• Describe properties that refer to model
objects
• Specify destination entity name, and optional
inverse relationship
• Can be to-one or to-many
• Instances of NSRelationshipDescripton in
NSEntityDescription
Copyright © 2016, About Objects, Inc. 17
Demo: Xcode Model Editor
Copyright © 2016, About Objects, Inc. 18
Encode/Decode Via KVC
Quick definition:
KVC is built-in NSObject behavior that allows you
to treat an object like a dictionary.
Quick example:
// Set author's 'firstName' property to "Fred"
author.setValue("Fred", forKey: "firstName")
// Initialize 'name' with the value of the author's 'firstName' property
let name = author.value(forKey: "firstName")
Copyright © 2016, About Objects, Inc. 19
The Modelmatic
Framework
Copyright © 2016, About Objects, Inc. 20
Modelmatic Cocoapod
• ModelObject base class
• Uses MOM + KVC to encode/decode
• Simple API
• Example app + unit tests show usage
Copyright © 2016, About Objects, Inc. 21
Subclassing
@objc (MDLAuthor)
class Author: ModelObject
{
static let entityName = "Author"
var authorId: NSNumber?
var firstName: String?
var lastName: String?
// Strong reference to children, to-many relationship
var books: [Book]?
}
Copyright © 2016, About Objects, Inc. 22
Basic Usage
// Decoding
let author = Author(dictionary: json, entity: entity)
// Encoding
let jsonDict = author.dictionaryRepresentation
Copyright © 2016, About Objects, Inc. 23
Modelmatic Example
// Assume we fetched JSON and deserialized it:
let json = ["author_id": 123, "first_name": "Fred", "last_name": "Smith", "books": [
["book_id": 234, "title": "Yadda, Yadda", "rating": 3],
["book_id": 456, "title": "Whee!", "rating": 5]
]
]
// Encode
let author = Author(dictionary: json, entity: entity)
// Work with the objects
author.firstName = "Frederick"
author.books[0]?.title = "War and Peace"
// Decode
let newJson = author.dictionaryRepresentation
// Contents of newJson:
{ "author_id": 123, "first_name": "Frederick", "last_name": "Smith", "books": [
{ "book_id": 234, "title": "War and Peace", "rating": 3 },
{ "book_id": 456, "title": "Whee!", "rating": 5 }
]
}
Copyright © 2016, About Objects, Inc. 24
Managing Relationships
Setting to-one relationships
public func set(modelObject: ModelObject, forKey: String) throws
Adding objects to to-many relationships
public func add(modelObject: ModelObject, forKey: String) throws
public func add(modelObjects: [ModelObject], forKey: String) throws
Copyright © 2016, About Objects, Inc. 25
KVC and Swift Types
KVC handles automatically:
• ObjC types, even if wrapped in Optionals !
• Bridged Swift types (String, Int, etc.) !
KVC needs a little help with:
• Bridged Swift types wrapped in Optionals !
• Non-bridged Swift types !
Copyright © 2016, About Objects, Inc. 26
Working with Swift Types
For non-Objc properties, add a computed
property prefixed with _kvc, as shown below:
var retailPrice: Double?
var kvc_retailPrice: Double {
get { return retailPrice ?? 0.0 }
set { retailPrice = Optional(newValue) }
}
Copyright © 2016, About Objects, Inc. 27
Transforming
Values
To define custom
transformation:
• Subclass
NSValueTransformer
• Register subclass
NSValueTransformer.setValueTransformer(
MyTransformer(),
forName: MyTransformer.transformerName)
Apply to attributes by setting
type to Transformable
Copyright © 2016, About Objects, Inc. 28
Value Transformer Example
private let delimiterString = ","
@objc (MDLStringArrayTransformer)
class StringArrayTransformer: NSValueTransformer
{
static let transformerName = "StringArray"
override class func transformedValueClass() -> AnyClass { return NSString.self }
override class func allowsReverseTransformation() -> Bool { return true }
override func transformedValue(value: AnyObject?) -> AnyObject? {
guard let values = value as? NSArray else { return value }
return values.componentsJoinedByString(delimiterString)
}
override func reverseTransformedValue(value: AnyObject?) -> AnyObject? {
guard let stringVal = value as? String else { return nil }
return stringVal.componentsSeparatedByString(delimiterString)
}
}
Copyright © 2016, About Objects, Inc. 29
Mapping
Key Paths
Set value for key jsonKeyPath
in attribute's UserInfo
dictionary
Copyright © 2016, About Objects, Inc. 30
Flattened
Attributes
Preserving JSON structure
during encoding requires
modeled relationship.
Copyright © 2016, About Objects, Inc. 31
Example App
Copyright © 2016, About Objects, Inc. 32
Object Store
• Accesses JSON via NSURLSessionDataTask
• Uses NSURLProtocol to intercept and access
locally stored JSON
• Can switch modes to directly access local
storage
Copyright © 2016, About Objects, Inc. 33
Example App Data Model
Copyright © 2016, About Objects, Inc. 34
Sample JSON
"version" : 0,
"authors" : [
{
"books" : [
{
"title" : "The Tempest",
"year" : "2013",
"tags" : "drama,fantasy",
"pricing" : {
"retail_price" : 14.99
},
"favorite" : true,
"book_id" : "3001",
"rating" : 4
},
Copyright © 2016, About Objects, Inc. 35
Demo: Example App
Copyright © 2016, About Objects, Inc. 36
Modelmatic
• Comprehensive visual model
• Automates:
• Object graph construction
• Value transformation
• Key path mappings
• Flattening attributes
• Built-in model versioning
Copyright © 2016, About Objects, Inc. 37
Modelmatic +
mogenerator
• mogenerator — command-line tool that
generates base classes for Core Data entities
• Base classes can be regenerated whenever
model changes
• Allows templates used for generating classes
to be customized
Copyright © 2016, About Objects, Inc. 38
To Do:
• Testing and documentation
• Fully automate non-bridged types
(dependent on Swift introspection)
• Add support for NSManagedObject subclasses
• Do clever things with model versions (TBD)
• Proposed: auto generate model from JSON
Contributors welcome!
Copyright © 2016, About Objects, Inc. 39
Q & A
Copyright © 2016, About Objects, Inc. 40
We're Hiring
consultants with backgrounds in:
• iOS
• Android
• Middleware – Ruby and Java
• Backend – Java
Copyright © 2016, About Objects, Inc. 41
Upcoming Classes
Reston
10/3 – 10/7 • Advanced iOS Development
10/22 – 10/28 • iOS Development in Swift: Comprehensive
12/10 – 12/16 • iOS Development in Objective-C: Comprehensive
Cupertino
11/21 – 11/22 • WatchKit Development
1/30 – 2/3 • iOS Development in Swift: Comprehensive
• View online: Public schedule
Copyright © 2016, About Objects, Inc. 42

More Related Content

What's hot

GraphConnect Europe 2016 - Building Spring Data Neo4j 4.1 Applications Like A...
GraphConnect Europe 2016 - Building Spring Data Neo4j 4.1 Applications Like A...GraphConnect Europe 2016 - Building Spring Data Neo4j 4.1 Applications Like A...
GraphConnect Europe 2016 - Building Spring Data Neo4j 4.1 Applications Like A...
Neo4j
 
CouchDB at JAOO Århus 2009
CouchDB at JAOO Århus 2009CouchDB at JAOO Århus 2009
CouchDB at JAOO Århus 2009
Jason Davies
 
MongoDB + Java + Spring Data
MongoDB + Java + Spring DataMongoDB + Java + Spring Data
MongoDB + Java + Spring Data
Anton Sulzhenko
 
The openCypher Project - An Open Graph Query Language
The openCypher Project - An Open Graph Query LanguageThe openCypher Project - An Open Graph Query Language
The openCypher Project - An Open Graph Query Language
Neo4j
 

What's hot (20)

GraphConnect Europe 2016 - Building Spring Data Neo4j 4.1 Applications Like A...
GraphConnect Europe 2016 - Building Spring Data Neo4j 4.1 Applications Like A...GraphConnect Europe 2016 - Building Spring Data Neo4j 4.1 Applications Like A...
GraphConnect Europe 2016 - Building Spring Data Neo4j 4.1 Applications Like A...
 
Data perisistence in iOS
Data perisistence in iOSData perisistence in iOS
Data perisistence in iOS
 
MongoDB and Hadoop: Driving Business Insights
MongoDB and Hadoop: Driving Business InsightsMongoDB and Hadoop: Driving Business Insights
MongoDB and Hadoop: Driving Business Insights
 
MSFT Dumaguete 061616 - Building High Performance Apps
MSFT Dumaguete 061616 - Building High Performance AppsMSFT Dumaguete 061616 - Building High Performance Apps
MSFT Dumaguete 061616 - Building High Performance Apps
 
Connecting to a REST API in iOS
Connecting to a REST API in iOSConnecting to a REST API in iOS
Connecting to a REST API in iOS
 
Using Neo4j from Java
Using Neo4j from JavaUsing Neo4j from Java
Using Neo4j from Java
 
JSLT: JSON querying and transformation
JSLT: JSON querying and transformationJSLT: JSON querying and transformation
JSLT: JSON querying and transformation
 
OSCON 2011 Learning CouchDB
OSCON 2011 Learning CouchDBOSCON 2011 Learning CouchDB
OSCON 2011 Learning CouchDB
 
Elasticsearch first-steps
Elasticsearch first-stepsElasticsearch first-steps
Elasticsearch first-steps
 
MongoDB, E-commerce and Transactions
MongoDB, E-commerce and TransactionsMongoDB, E-commerce and Transactions
MongoDB, E-commerce and Transactions
 
CouchDB at JAOO Århus 2009
CouchDB at JAOO Århus 2009CouchDB at JAOO Århus 2009
CouchDB at JAOO Århus 2009
 
MongoDB + Java + Spring Data
MongoDB + Java + Spring DataMongoDB + Java + Spring Data
MongoDB + Java + Spring Data
 
Relational to Graph - Import
Relational to Graph - ImportRelational to Graph - Import
Relational to Graph - Import
 
Requery overview
Requery overviewRequery overview
Requery overview
 
The openCypher Project - An Open Graph Query Language
The openCypher Project - An Open Graph Query LanguageThe openCypher Project - An Open Graph Query Language
The openCypher Project - An Open Graph Query Language
 
Designing and Building a Graph Database Application – Architectural Choices, ...
Designing and Building a Graph Database Application – Architectural Choices, ...Designing and Building a Graph Database Application – Architectural Choices, ...
Designing and Building a Graph Database Application – Architectural Choices, ...
 
No sql way_in_pg
No sql way_in_pgNo sql way_in_pg
No sql way_in_pg
 
MongoDB Basics
MongoDB BasicsMongoDB Basics
MongoDB Basics
 
Spring Data, Jongo & Co.
Spring Data, Jongo & Co.Spring Data, Jongo & Co.
Spring Data, Jongo & Co.
 
Elasticsearch in 15 minutes
Elasticsearch in 15 minutesElasticsearch in 15 minutes
Elasticsearch in 15 minutes
 

Similar to Streamlining JSON mapping

Mongo db eveningschemadesign
Mongo db eveningschemadesignMongo db eveningschemadesign
Mongo db eveningschemadesign
MongoDB APAC
 
MongoDB and Ruby on Rails
MongoDB and Ruby on RailsMongoDB and Ruby on Rails
MongoDB and Ruby on Rails
rfischer20
 

Similar to Streamlining JSON mapping (20)

Building your first app with mongo db
Building your first app with mongo dbBuilding your first app with mongo db
Building your first app with mongo db
 
MongoDB Introduction talk at Dr Dobbs Conference, MongoDB Evenings at Bangalo...
MongoDB Introduction talk at Dr Dobbs Conference, MongoDB Evenings at Bangalo...MongoDB Introduction talk at Dr Dobbs Conference, MongoDB Evenings at Bangalo...
MongoDB Introduction talk at Dr Dobbs Conference, MongoDB Evenings at Bangalo...
 
MongoDB .local London 2019: Fast Machine Learning Development with MongoDB
MongoDB .local London 2019: Fast Machine Learning Development with MongoDBMongoDB .local London 2019: Fast Machine Learning Development with MongoDB
MongoDB .local London 2019: Fast Machine Learning Development with MongoDB
 
MongoDB .local London 2019: Fast Machine Learning Development with MongoDB
MongoDB .local London 2019: Fast Machine Learning Development with MongoDBMongoDB .local London 2019: Fast Machine Learning Development with MongoDB
MongoDB .local London 2019: Fast Machine Learning Development with MongoDB
 
Cappuccino - A Javascript Application Framework
Cappuccino - A Javascript Application FrameworkCappuccino - A Javascript Application Framework
Cappuccino - A Javascript Application Framework
 
Polaris presentation ioc - code conference
Polaris presentation   ioc - code conferencePolaris presentation   ioc - code conference
Polaris presentation ioc - code conference
 
Mongo db eveningschemadesign
Mongo db eveningschemadesignMongo db eveningschemadesign
Mongo db eveningschemadesign
 
AWS CloudFormation under the Hood (DMG303) | AWS re:Invent 2013
AWS CloudFormation under the Hood (DMG303) | AWS re:Invent 2013AWS CloudFormation under the Hood (DMG303) | AWS re:Invent 2013
AWS CloudFormation under the Hood (DMG303) | AWS re:Invent 2013
 
Vital AI MetaQL: Queries Across NoSQL, SQL, Sparql, and Spark
Vital AI MetaQL: Queries Across NoSQL, SQL, Sparql, and SparkVital AI MetaQL: Queries Across NoSQL, SQL, Sparql, and Spark
Vital AI MetaQL: Queries Across NoSQL, SQL, Sparql, and Spark
 
Managing Social Content with MongoDB
Managing Social Content with MongoDBManaging Social Content with MongoDB
Managing Social Content with MongoDB
 
Introduction to MongoDB
Introduction to MongoDBIntroduction to MongoDB
Introduction to MongoDB
 
MongoDB at FrozenRails
MongoDB at FrozenRailsMongoDB at FrozenRails
MongoDB at FrozenRails
 
MongoDB World 2019: Fast Machine Learning Development with MongoDB
MongoDB World 2019: Fast Machine Learning Development with MongoDBMongoDB World 2019: Fast Machine Learning Development with MongoDB
MongoDB World 2019: Fast Machine Learning Development with MongoDB
 
MongoDB and Ruby on Rails
MongoDB and Ruby on RailsMongoDB and Ruby on Rails
MongoDB and Ruby on Rails
 
Javascript analysis
Javascript analysisJavascript analysis
Javascript analysis
 
REST easy with API Platform
REST easy with API PlatformREST easy with API Platform
REST easy with API Platform
 
Building your first app with MongoDB
Building your first app with MongoDBBuilding your first app with MongoDB
Building your first app with MongoDB
 
React-Native Lecture 11: In App Storage
React-Native Lecture 11: In App StorageReact-Native Lecture 11: In App Storage
React-Native Lecture 11: In App Storage
 
Webinar: What's new in the .NET Driver
Webinar: What's new in the .NET DriverWebinar: What's new in the .NET Driver
Webinar: What's new in the .NET Driver
 
MongoDB World 2018: Tutorial - MongoDB & NodeJS: Zero to Hero in 80 Minutes
MongoDB World 2018: Tutorial - MongoDB & NodeJS: Zero to Hero in 80 MinutesMongoDB World 2018: Tutorial - MongoDB & NodeJS: Zero to Hero in 80 Minutes
MongoDB World 2018: Tutorial - MongoDB & NodeJS: Zero to Hero in 80 Minutes
 

Recently uploaded

Recently uploaded (20)

Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu SubbuApidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 

Streamlining JSON mapping

  • 1. ABOUTOBJECTS Streamlining JSON Mapping Jonathan Lehr, Founder and VP, Training Copyright © 2016, About Objects, Inc. 1
  • 2. About Objects • Reston, VA • Full-stack consulting and training • Roots in NeXT, OpenStep, WebObjects + enterprise middleware and backend • iOS from day one Copyright © 2016, About Objects, Inc. 2
  • 3. So Many Frameworks Number of hits yielded by a recent Github search for swift json: 576Seems it's on a lot of peoples' radar. Copyright © 2016, About Objects, Inc. 3
  • 4. Automating Encode/Decode { "book_id": 42, "title": "The Time Machine", "rating": 3 } public class Book: NSObject { public var bookId: Int public var title: String? public var rating: Rating? } 1. Map keys to property names 2. Perform value transformations 3. Encode and decode model objects Copyright © 2016, About Objects, Inc. 4
  • 5. book n author array …book 1 JSON <--> Object Graph { "author_id": 98, "first_name": "H. G.", "last_name": "Wells", "books": [ { "book_id": 42, "title": "The Time Machine", "rating": 3 }, ... Copyright © 2016, About Objects, Inc. 5
  • 6. Mapping Frameworks You define mappings programmatically by: • Defining mappings per property in code (ObjectMapper, SwiftJSON) • Providing dictionaries of mappings per class (RestKit) Copyright © 2016, About Objects, Inc. 6
  • 7. RestKit Example RKObjectMapping *bookMapping = [RKObjectMapping mappingForClass:Book.class]; [bookMapping addAttributeMappingsFromDictionary:@{ @"book_id": @"bookId", @"title": @"title", @"rating": @"rating", }]; RKResponseDescriptor *descriptor = [RKResponseDescriptor responseDescriptorWithMapping:bookMapping method:RKRequestMethodAny pathPattern:nil keyPath:@"books" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]; Copyright © 2016, About Objects, Inc. 7
  • 8. ObjectMapper Example class Book: Mappable { public var bookId: Int public var title: String? public var rating: Rating? required init?(_ map: Map) { } // Mappable func mapping(map: Map) { bookId <- map["book_id"] title <- map["title"] rating <- map["rating"] } } Copyright © 2016, About Objects, Inc. 8
  • 9. Issues • Maintenance is awkward • Model hard to visualize • Strings in code reduce safety Copyright © 2016, About Objects, Inc. 9
  • 11. Model Needs to Capture: • Relationship info: to-many, target type • Nice to have: inverse relationships • Mapping keys to property names • Value transformations Copyright © 2016, About Objects, Inc. 11
  • 12. Framework Needs to: • Traverse relationships defined in model • Construct nested objects • Use introspection to get and set values • Map keys and transform values Do all the above without manual coding (except for custom transformations) Copyright © 2016, About Objects, Inc. 12
  • 13. Core Data Model Editor • Awesome tool for data modeling • Defines mappings in a visual format • Framework-level programmatic access But wait, it's only for Core Data, right? Heh, heh Copyright © 2016, About Objects, Inc. 13
  • 14. Managed Object Model (MOM) • Defines mappings between model objects and their external data representation • Designed to support relational databases (object-relational mapping) • Can be loaded as NSManagedObjectModel instance at runtime Copyright © 2016, About Objects, Inc. 14
  • 15. Entities • Metadata description of domain object • Lists two kinds of properties: attributes and relationships • Defines mapping between JSON dictionary and Swift class • Instances of NSEntityDescription in NSManagedObjectModel Copyright © 2016, About Objects, Inc. 15
  • 16. Attributes • Metadata descriptions of individual values • Define mappings between data elements and Swift properties • Instances of NSAttributeDescription in NSEntityDescription Copyright © 2016, About Objects, Inc. 16
  • 17. Relationships • Describe properties that refer to model objects • Specify destination entity name, and optional inverse relationship • Can be to-one or to-many • Instances of NSRelationshipDescripton in NSEntityDescription Copyright © 2016, About Objects, Inc. 17
  • 18. Demo: Xcode Model Editor Copyright © 2016, About Objects, Inc. 18
  • 19. Encode/Decode Via KVC Quick definition: KVC is built-in NSObject behavior that allows you to treat an object like a dictionary. Quick example: // Set author's 'firstName' property to "Fred" author.setValue("Fred", forKey: "firstName") // Initialize 'name' with the value of the author's 'firstName' property let name = author.value(forKey: "firstName") Copyright © 2016, About Objects, Inc. 19
  • 20. The Modelmatic Framework Copyright © 2016, About Objects, Inc. 20
  • 21. Modelmatic Cocoapod • ModelObject base class • Uses MOM + KVC to encode/decode • Simple API • Example app + unit tests show usage Copyright © 2016, About Objects, Inc. 21
  • 22. Subclassing @objc (MDLAuthor) class Author: ModelObject { static let entityName = "Author" var authorId: NSNumber? var firstName: String? var lastName: String? // Strong reference to children, to-many relationship var books: [Book]? } Copyright © 2016, About Objects, Inc. 22
  • 23. Basic Usage // Decoding let author = Author(dictionary: json, entity: entity) // Encoding let jsonDict = author.dictionaryRepresentation Copyright © 2016, About Objects, Inc. 23
  • 24. Modelmatic Example // Assume we fetched JSON and deserialized it: let json = ["author_id": 123, "first_name": "Fred", "last_name": "Smith", "books": [ ["book_id": 234, "title": "Yadda, Yadda", "rating": 3], ["book_id": 456, "title": "Whee!", "rating": 5] ] ] // Encode let author = Author(dictionary: json, entity: entity) // Work with the objects author.firstName = "Frederick" author.books[0]?.title = "War and Peace" // Decode let newJson = author.dictionaryRepresentation // Contents of newJson: { "author_id": 123, "first_name": "Frederick", "last_name": "Smith", "books": [ { "book_id": 234, "title": "War and Peace", "rating": 3 }, { "book_id": 456, "title": "Whee!", "rating": 5 } ] } Copyright © 2016, About Objects, Inc. 24
  • 25. Managing Relationships Setting to-one relationships public func set(modelObject: ModelObject, forKey: String) throws Adding objects to to-many relationships public func add(modelObject: ModelObject, forKey: String) throws public func add(modelObjects: [ModelObject], forKey: String) throws Copyright © 2016, About Objects, Inc. 25
  • 26. KVC and Swift Types KVC handles automatically: • ObjC types, even if wrapped in Optionals ! • Bridged Swift types (String, Int, etc.) ! KVC needs a little help with: • Bridged Swift types wrapped in Optionals ! • Non-bridged Swift types ! Copyright © 2016, About Objects, Inc. 26
  • 27. Working with Swift Types For non-Objc properties, add a computed property prefixed with _kvc, as shown below: var retailPrice: Double? var kvc_retailPrice: Double { get { return retailPrice ?? 0.0 } set { retailPrice = Optional(newValue) } } Copyright © 2016, About Objects, Inc. 27
  • 28. Transforming Values To define custom transformation: • Subclass NSValueTransformer • Register subclass NSValueTransformer.setValueTransformer( MyTransformer(), forName: MyTransformer.transformerName) Apply to attributes by setting type to Transformable Copyright © 2016, About Objects, Inc. 28
  • 29. Value Transformer Example private let delimiterString = "," @objc (MDLStringArrayTransformer) class StringArrayTransformer: NSValueTransformer { static let transformerName = "StringArray" override class func transformedValueClass() -> AnyClass { return NSString.self } override class func allowsReverseTransformation() -> Bool { return true } override func transformedValue(value: AnyObject?) -> AnyObject? { guard let values = value as? NSArray else { return value } return values.componentsJoinedByString(delimiterString) } override func reverseTransformedValue(value: AnyObject?) -> AnyObject? { guard let stringVal = value as? String else { return nil } return stringVal.componentsSeparatedByString(delimiterString) } } Copyright © 2016, About Objects, Inc. 29
  • 30. Mapping Key Paths Set value for key jsonKeyPath in attribute's UserInfo dictionary Copyright © 2016, About Objects, Inc. 30
  • 31. Flattened Attributes Preserving JSON structure during encoding requires modeled relationship. Copyright © 2016, About Objects, Inc. 31
  • 32. Example App Copyright © 2016, About Objects, Inc. 32
  • 33. Object Store • Accesses JSON via NSURLSessionDataTask • Uses NSURLProtocol to intercept and access locally stored JSON • Can switch modes to directly access local storage Copyright © 2016, About Objects, Inc. 33
  • 34. Example App Data Model Copyright © 2016, About Objects, Inc. 34
  • 35. Sample JSON "version" : 0, "authors" : [ { "books" : [ { "title" : "The Tempest", "year" : "2013", "tags" : "drama,fantasy", "pricing" : { "retail_price" : 14.99 }, "favorite" : true, "book_id" : "3001", "rating" : 4 }, Copyright © 2016, About Objects, Inc. 35
  • 36. Demo: Example App Copyright © 2016, About Objects, Inc. 36
  • 37. Modelmatic • Comprehensive visual model • Automates: • Object graph construction • Value transformation • Key path mappings • Flattening attributes • Built-in model versioning Copyright © 2016, About Objects, Inc. 37
  • 38. Modelmatic + mogenerator • mogenerator — command-line tool that generates base classes for Core Data entities • Base classes can be regenerated whenever model changes • Allows templates used for generating classes to be customized Copyright © 2016, About Objects, Inc. 38
  • 39. To Do: • Testing and documentation • Fully automate non-bridged types (dependent on Swift introspection) • Add support for NSManagedObject subclasses • Do clever things with model versions (TBD) • Proposed: auto generate model from JSON Contributors welcome! Copyright © 2016, About Objects, Inc. 39
  • 40. Q & A Copyright © 2016, About Objects, Inc. 40
  • 41. We're Hiring consultants with backgrounds in: • iOS • Android • Middleware – Ruby and Java • Backend – Java Copyright © 2016, About Objects, Inc. 41
  • 42. Upcoming Classes Reston 10/3 – 10/7 • Advanced iOS Development 10/22 – 10/28 • iOS Development in Swift: Comprehensive 12/10 – 12/16 • iOS Development in Objective-C: Comprehensive Cupertino 11/21 – 11/22 • WatchKit Development 1/30 – 2/3 • iOS Development in Swift: Comprehensive • View online: Public schedule Copyright © 2016, About Objects, Inc. 42