Swift 的一个非常简单的 JSON 解析器
无依赖。如果您想的话,可以将 JJ.swift
复制到您的项目中。
import UIKit
struct Branch {
let branch: String
}
struct MyRepository {
let name: String
let desc: String
let stargazersCount: Int
let language: String?
let sometimesMissingKey: String?
let defaultBranch: Branch
init(anyObject: AnyObject?) throws {
let obj = try jj(anyObject).obj()
self.name = try obj["name"].string()
self.desc = try obj["description"].string()
self.stargazersCount = try obj["stargazersCount"].int()
self.language = obj["language"].asString
self.sometimesMissingKey = obj["sometimesMissingKey"].asString
self.defaultBranch = Branch(branch: obj["branch"].toString())
}
}
let json = [
"name" : "JJ",
"description" : "Super simple json parser for Swift",
"stargazersCount" : 999999,
"language" : "RU",
"sometimesMissingKey" : NSNull(),
"branch" : "master"
]
do {
let r = try MyRepository(anyObject: json)
} catch {
debugPrint(error)
}
class RepositoryAuthor: NSCoding {
var name: String!
var headquarters: String!
init(name: String, headquarters: String) {
super.init()
self.name = name
self.headquarters = headquarters
}
required convenience init?(coder aDecoder: NSCoder) {
let dec = jj(decoder: aDecoder)
do {
let name = try dec["name"].string()
let headquarters = try dec["headquarters"].string()
self.init(name: name, headquarters: headquarters)
} catch {
debugPrint(error)
return nil
}
}
func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeObject(self.name, forKey: "name")
aCoder.encodeObject(self.headquarters, forKey: "headquarters")
}
}
let data = NSMutableData()
let coder = NSKeyedArchiver(forWritingWithMutableData: data)
let enc = jj(encoder: coder)
enc.put("Yury", at: "name")
enc.put("AnjLab", at: "headquarters")
coder.finishEncoding()
let decoder = NSKeyedUnarchiver(forReadingWithData: data)
let author = RepositoryAuthor(coder: decoder)
NSCoding
的类Bool
Int
& UInt
Float
Double
NSNumber
String
NSDate
NSURL
NSTimeZone
AnyObject
]String
: AnyObject
]遵循 ErrorType
的 JJError
,目前有两个错误结构符合它
WrongType
抛出NotFound
抛出let arr = ["element"]
do {
let _ = try jj(arr).obj()
} catch {
print(error)
}
// JJError.WrongType: Can't convert Optional(<_TtCs21_SwiftDeferredNSArray 0x7fa3be4acb40>(
// element
// )
// ) at path: '<root>' to type '[String: AnyObject]'
类似 .<Type>()
的表达式会直接抛出,可以使用 catch 语句创建最复杂的错误处理行为。这也意味着可以使用 try?
返回 nil 以替代抛出错误。
对于必填值,最有用的方法是 .to<Type>(defaultValue)
。如果值缺失或不匹配其类型,将使用默认值。
对于可选值,有方法 .as<Type>
。
方法 | 示例 | 空值行为 | 缺失键行为 | 类型不匹配行为 |
---|---|---|---|---|
.<Type>() | .int() | 抛出 | 抛出 | 抛出 |
.to<Type>(defaultValue) | .toString() 或 .toString("默认") | 默认值 | 默认值 | 默认值 |
.as<类型> | .asObj | nil | nil | nil |
.decode() | .decode() as NSNumber | 抛出 | 抛出 | 抛出 |
.decodeAs() | .decodeAs() | nil | nil | nil |
尤里·柯罗列夫, [email protected]
JJ 可在 MIT 许可协议下使用。有关更多信息,请参阅 LICENSE 文件。