Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

GlebRadchenko/JsonMapper

Open more actions menu

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

93 Commits
93 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

JsonMapper

Build Status

  • Simple JsonMapper, which maps JSON data to your models automatically.

  • You don't need to parse your JSON manually.

  • Mapper don't use reflection at all, so it's fast enough.

  • All you need is:

    let object: Object = try Mapper.map(json)

Requirements:

  • iOS 9.1+
  • XCode 8.0+
  • Swift 3.0+ (Actually, I didn't test it for other versions of iOS and macOS so, you can try :) )

Current features:

  • Mapping primitive types;
  • Mapping Mapable objects (classes, structs, enums);
  • Optional mapping;
  • Supporting of arrays mapping;
  • Supporting of nested types mapping;
  • Supporting speeding up mapping of single object by declaring helpingPath property;
  • Mapping custom types like Date.

Future features and plans:

  • Unit tests coverage(in process);
  • Simplify declaring of helpingPath property - done;
  • Extend all primitive types for AtomaryMapable protocol - done;

Usage:

  1. Import library as follows:
import JsonMapper
  1. Create your Class or Struct and extend it for Mapable protocol:
public protocol Mapable {
 init(_ wrapping: Wrapping) throws
 static var properties: [MapableProperty] { get }
 static var mappingPath: [TargetNode] { get }
}

for example:

class User: Mapable {
  var name: String
  var login: String
  var age: Int
  
  static var mappingPath: [TargetNode] = []
  static var properties: [MapableProperty] = [
      .value(type: String.self, key: "name", optional: false),
      .value(type: String.self, key: "login", optional: false),
      .value(type: Int.self, key: "age", optional: false)
  ]
  
  public required init(_ wrapping: Wrapping) throws {
      name = try wrapping.get("name")
      login = try wrapping.get("login")
      age = try wrapping.get("age")
  }
}

where mappingPath - array of values, which can help Mapper to find destination Object in JSON file. For example, you have json file:

{
  "response" : {
    "user" : {
      "name" : "Test",
      "login" : "Login", 
      "age" : 33
    }
  }
}

your helpingPath should be as follows:

public static var mappingPath: [TargetNode] = [.dictionaryNode(key: "response"),
                                               .dictionaryNode(key: "user", isDestination: true)]                                         

this property determines a valid way for "user" object, and Mapper won't search object recursively. You can delete this property or stay it like :

public static var mappingPath: [TargetNode] = []                                                    

to force recursive search (BFS) of object that you need to be mapped.

MapableProperty supports properties like :

public enum MapableProperty {
  
  case value(type: AtomaryMapable.Type, key: String, optional: Bool)
  case array(type: AtomaryMapable.Type, key: String, optional: Bool)
  case dictionary(type: AtomaryMapable.Type, key: String, optional: Bool)
  case object(type: Mapable.Type, key: String, optional: Bool)
  case objectsArray(type: Mapable.Type, key: String, optional: Bool)
  case objectsDictionary(type: Mapable.Type, key: String, optional: Bool)
  
}                                                 
  1. Then call with Data object or json:
  let dataUser: User = try Mapper.map(data)
  //or
  let jsonUser: User = try Mapper.map(json)  
  1. Also you can map arrays, nested types or primitive and custom types by call :
  let users: [User] = try Mapper.map([data or json])
  let stringValue: String = try Mapper.map([data or json], for: "[your key for needed String value]")
  let doubles: [String: Double] = try Mapper.map([data or json], for: "[your key for needed array of Double values]")
  
  let date: Date = try Mapper.map(for: "data", json, { (rawValue: String) -> Date in
      guard let date = DateFormatter().date(from: rawValue) else {
          throw SomeError
      }
  
      return date
})

For mapping array of Mapable objects it's recommended not to use mappingPath value (just for now :D), to prevent unexpected behavior.

About

Fast Json Mapper without using reflection

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages

Morty Proxy This is a proxified and sanitized view of the page, visit original site.