Latest | 0.3 |
---|---|
Homepage | https://github.com/robertpalmer/JSONMapper |
License | MIT |
Platforms | ios 8.0 |
Authors |
JSONMapper is a simple way deal with json data in swift.
Requirements
- Swift 2
- Xcode 7 beta 6
Playground
Open the ‘Playground/Playground.xcworkspace’ file in Xcode to try JSONMapper.
Example:
import Foundation
import JSONMapper
let json = "["
+ "{"
+ ""id": 1296269,"
+ ""owner": {"
+ ""login": "octocat","
+ ""id": 1,"
+ ""avatar_url": "https://github.com/images/error/octocat_happy.gif","
+ ""type": "User","
+ ""site_admin": false"
+ "},"
+ ""name": "Hello-World","
+ ""private": false,"
+ ""url": "https://api.github.com/repos/octocat/Hello-World","
+ "}]"
let data = json.dataUsingEncoding(NSUTF8StringEncoding)
let reposObject = try? NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions(rawValue: 0))
let repos = Decode(content: reposObject)
Access values
var name: String
name = try! repos[0]["name"].decode() // Hello-World
name = try! repos[0]["name"]~ // Hello-World
Values can be accessed through the subscript methods. The return type of the subscript is a DecodeValue. The decode() method or the ‘~’ postfix oparator decode the the value to the inferred type.
let ownerId: Int = try! repos[0]["owner"]["id"]~ // 1
let privateRepo: Bool = try! repos[0]["private"]~ // false
let urlString: String = try! repos[0]["url"]~ // https://api.github.com/repos/octocat/Hello-World
The return type is inferred from the type of the variable it is assigned to. The type must implement the Decodable protocol.
JSONMapper implements the protocol for String, Int, Bool and Float.
Structs, classes and enum types can be extended to be ‘Decodable’.
Class from the Foundation.framework:
extension NSURL: Decodable {
public static func decode(value: DecodeValue) throws -> Self? {
return self.init(string: try value.decode())
}
}
let url: NSURL = try! repos[0]["url"]~ // NSURL(string: https://api.github.com/repos/octocat/Hello-World)
Enums
enum OwnerType: String {
case User = "User"
case Admin = "Admin"
}
extension OwnerType: Decodable {
static func decode(value: DecodeValue) throws -> OwnerType? {
return OwnerType(rawValue: try value.decode())
}
}
let type: OwnerType = try! repos[0]["owner"]["type"]~
Structs
struct Owner {
let login: String
let id: Int
let avatarURL: NSURL
let type: OwnerType
let siteAdmin: Bool
}
extension Owner: Decodable {
static func decode(value: DecodeValue) throws -> Owner? {
return try Owner(login: value["login"]~,
id: value["id"]~,
avatarURL: value["avatar_url"]~,
type: value["type"]~,
siteAdmin: value["site_admin"]~)
}
}
struct Repo {
let id: Int
let owner: Owner
let name: String
let isPrivate: Bool
let url: NSURL
}
extension Repo: Decodable {
static func decode(value: DecodeValue) throws -> Repo? {
return try Repo(id: value["id"]~,
owner: value["owner"]~,
name: value["name"]~,
isPrivate: value["private"]~,
url: value["url"]~)
}
}
let r: [Repo] = try! repos~
print(r[0].name) // Hello-World
print(r[0].owner.avatarURL) // https://github.com/images/error/octocat_happy.gif
Errors
When the expected return type is not a ‘Decodable’ the code will not compile.
// will not compile
let s: UIView = Decode(content: "a string").decode()
When a value can not be decoded to a specific type or, the decode method throws an error.
let s: String = try repos[0]["private"]~
// Expected 'String' for key '[0][private]', got '__NSCFBoolean'.
let s: String = try repos["name"]~
// Expected 'Dictionary<String, AnyObject>' for key '', got '__NSCFArray'.
let s: String = try repos[0][0]~
// Expected 'Array<AnyObject>' for key '[0]', got '__NSCFDictionary'.
Also when a key can not be found in the dictionary or array, the decode methods will throw an error.
let s: String = try repos[0]["not_defined"]~
// Value for '[0][not_defined]' not found.
let s: String = try repos[1]~
// Value for '[1]' not found.
When the inferred return type is an optional, the error is ignored and the return value is nil.
let s: String? = try repos[1]~ // s == nil
If the inferred type is an optional, but an error should be thrown nevertheless, the return type can be casted to a non optional.
let s: String? = try repos[1]~ as String
// Value for '[1]' not found.
On the other hand, if the inferred type is not an optional, but may fail, it is possible to provide a default value using the ?? operator.
let s2: String = try repos[1]~ ?? "default" // s2 == "default"
If the return type is an array, the values that cannot be decoded are omitted from the array.
let arrayValue = Decode(content: [ 1, 2, "3", 4])
let intArray: [Int] = try! arrayValue~ // [1, 2, 4]
let stringArray: [String] = try! arrayValue~ // ["3"]
let ownerTypeArray: [OwnerType] = try! arrayValue~ // []
Installation
Carthage
github "robertpalmer/JSONMapper"
Cocoapods
platform :ios, '8.0'
use_frameworks!
pod 'JSONMapper'
Some other json libraries and inspiration:
- https://cocoapods.org/pods/Argo
- https://github.com/matthewcheok/JSONCodable
- https://cocoapods.org/pods/ObjectMapper
- https://github.com/Anviking/Decodable
- https://github.com/SwiftyJSON/SwiftyJSON
- https://github.com/hkellaway/Gloss
Latest podspec
{ "name": "JSONMapper", "version": "0.3", "summary": "JSONMapper is a simple way deal with json data in swift.", "description": "JSONMapper is a simple way deal with json data in swift. It requires Xcode 7 beta 6 or newer.", "homepage": "https://github.com/robertpalmer/JSONMapper", "license": "MIT", "authors": { "Robert Palmer": "[email protected]" }, "platforms": { "ios": "8.0" }, "source": { "git": "https://github.com/robertpalmer/JSONMapper.git", "tag": "0.3" }, "source_files": [ "JSONMapper", "JSONMapper/**/*.{h,m}" ], "exclude_files": "JSONMapperTests" }
Tue, 01 Mar 2016 08:44:03 +0000