Last active
August 29, 2016 15:13
-
-
Save colourful987/f9239a73044f10d090ab9865fcf29c6e to your computer and use it in GitHub Desktop.
Decoding JSON In Swift (一)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// From Soroush Khanlou ,URL: [Decoding JSON in Swift](http://khanlou.com/2016/04/decoding-json/) | |
import Foundation | |
struct ParserError:Error{ | |
let message:String | |
} | |
struct Parser { | |
let dictionary : [String:AnyObject]? | |
init(dictionary:[String:AnyObject]?) { | |
self.dictionary = dictionary | |
} | |
func fetch<T>(key:String) throws -> T{ | |
let fetchOptional = dictionary?[key] // 这里存在nil的情况 | |
guard let fetched = fetchOptional else { | |
throw ParserError(message:"The key \(key) wa not found.") | |
} | |
// 由于开始是AnyObject 所以还要类型cast | |
guard let typed = fetched as? T else { | |
throw ParserError(message: "The key \"\(key)\" was not the correct type. It had value \"\(fetched).\"") | |
} | |
return typed | |
} | |
func fetch<T,U>(key:String,transformation:((T)->U?))throws -> U { | |
let fetched:T = try fetch(key: key) | |
guard let transformed = transformation(fetched) else { | |
throw ParserError(message: "The value \"\(fetched)\" at key \"\(key)\" could not be transformed.") | |
} | |
return transformed | |
} | |
// 有些情况是后台配置不同 可选的 即有时候有 有时候没有 | |
func fetchOptional<T>(key: String) throws -> T? { | |
let fetchedOptional = dictionary?[key] | |
guard let fetched = fetchedOptional else { | |
return nil | |
} | |
guard let typed = fetched as? T else { | |
throw ParserError(message: "The key \"\(key)\" was not the right type. It had value \"\(fetched).\"") | |
} | |
return typed | |
} | |
func fetchOptional<T, U>(key: String, transformation: (T) -> U?) -> U? { | |
return (dictionary?[key] as? T).flatMap(transformation) | |
} | |
func fetchArray<T, U>(key: String, transformation: (T) -> U?) throws -> [U] { | |
let fetched: [T] = try fetch(key:key) | |
return fetched.flatMap(transformation) | |
} | |
} | |
enum SomeEnum: String { | |
case FirstCase = "first_case" | |
case SecondCase = "second_case" | |
} | |
struct InnerType { | |
let aString: String | |
let anInt: Int | |
let stringArray: [String] | |
let anOptionalValue: String? | |
init?(dictionary: [String: AnyObject]?) { | |
let parser = Parser(dictionary: dictionary) | |
do { | |
self.aString = try parser.fetch(key: "a_string") | |
self.anInt = try parser.fetch(key: "an_int") | |
self.stringArray = try parser.fetch(key: "string_array") | |
self.anOptionalValue = try parser.fetchOptional(key: "bingo") | |
} catch let error { | |
print(error) | |
return nil | |
} | |
} | |
} | |
class OuterType { | |
let inner: InnerType | |
let enums: [SomeEnum] | |
init?(dictionary: [String: AnyObject]?) { | |
let parser = Parser(dictionary: dictionary) | |
do { | |
// $0 其实inner 数据啦 当前是AnyObject | |
self.inner = try parser.fetch(key: "inner") { InnerType(dictionary: $0) } | |
self.enums = try parser.fetchArray(key: "enums") { SomeEnum(rawValue: $0) } | |
} catch let error { | |
print(error) | |
return nil | |
} | |
} | |
} | |
// 这里构造一个解析好的字典 | |
var innerDictionary = [String: AnyObject]() | |
innerDictionary["a_string"] = "some_string" as? AnyObject | |
innerDictionary["an_int"] = 3 as? AnyObject | |
innerDictionary["string_array"] = ["a", "bunch", "of", "strings"] as? AnyObject | |
// 注意这里没有anOptionalValue 假定这里为nil 所以没有赋值 | |
InnerType(dictionary: innerDictionary) | |
var outerDictionary = [String: AnyObject]() | |
outerDictionary["inner"] = innerDictionary as? AnyObject | |
outerDictionary["enums"] = ["first_case", "second_case"] as? AnyObject | |
let outer = OuterType(dictionary: outerDictionary) | |
print(outer?.inner.stringArray) | |
print(outer?.enums) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment