0001 // 0002 // Decoder.swift 0003 // Gloss 0004 // 0005 // Copyright (c) 2015 Harlan Kellaway 0006 // 0007 // Permission is hereby granted, free of charge, to any person obtaining a copy 0008 // of this software and associated documentation files (the "Software"), to deal 0009 // in the Software without restriction, including without limitation the rights 0010 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 0011 // copies of the Software, and to permit persons to whom the Software is 0012 // furnished to do so, subject to the following conditions: 0013 // 0014 // The above copyright notice and this permission notice shall be included in 0015 // all copies or substantial portions of the Software. 0016 // 0017 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 0018 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 0019 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 0020 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 0021 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 0022 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 0023 // THE SOFTWARE. 0024 // 0025 0026 import Foundation 0027 0028 /** 0029 Set of functions used to decode JSON to objects 0030 */ 0031 public struct Decoder{ 0032 0033 // MARK: - Decoders 0034 0035 /** 0036 Returns function to decode JSON to value type 0037 0038 :parameter: key JSON key used to set value 0039 :parameter: keyPathDelimiter Delimiter used for nested keypath keys 0040 0041 :returns: Function decoding JSON to an optional value type 0042 */ 0043 public static func decode
Decoder.swift:112 return Decoder.decodeDate(key, dateFormatter: dateFormatter, keyPathDelimiter: keyPathDelimiter)Decoder.swift:284 return Decoder.decodeDateArray(key, dateFormatter: dateFormatter, keyPathDelimiter: keyPathDelimiter)Operators.swift:39 return Decoder.decode(key)(json)Operators.swift:46 return Decoder.decodeDecodable(key)(json)Operators.swift:53 return Decoder.decodeEnum(key)(json)Operators.swift:60 return Decoder.decodeURL(key)(json)Operators.swift:67 return Decoder.decodeEnumArray(key)(json)Operators.swift:74 return Decoder.decodeDecodableArray(key)(json)Operators.swift:81 return Decoder.decodeURLArray(key)(json)Operators.swift:88 return Decoder.decodeDecodableDictionary(key)(json)<T>(key: String, keyPathDelimiter: String = GlossKeyPathDelimiter()) -> JSON -> T? { 0044 return { 0045 json in 0046 0047 if let value = json.valueForKeyPath(key, withDelimiter: keyPathDelimiter) as? T { 0048 return value 0049 } 0050 0051 return nil 0052 } 0053 } 0054 0055 /** 0056 Returns function to decode JSON to value type 0057 for objects that conform to the Decodable protocol 0058 0059 :parameter: key JSON key used to set value 0060 :parameter: keyPathDelimiter Delimiter used for nested keypath keys 0061 0062 :returns: Function decoding JSON to an optional value type 0063 */ 0064 public static func decodeDecodable
Operators.swift:39 return Decoder.decode(key)(json)<T: Decodable>(key: String, keyPathDelimiter: String = GlossKeyPathDelimiter()) -> JSON -> T? { 0065 return { 0066 json in 0067 0068 if let subJSON = json.valueForKeyPath(key, withDelimiter: keyPathDelimiter) as? JSON { 0069 return T(json: subJSON) 0070 } 0071 0072 return nil 0073 0074 } 0075 } 0076 0077 /** 0078 Returns function to decode JSON to date 0079 0080 :parameter: key JSON key used to set value 0081 :parameter: dateFormatter Formatter used to format date 0082 :parameter: keyPathDelimiter Delimiter used for nested keypath keys 0083 0084 :returns: Function decoding JSON to an optional date 0085 */ 0086 public static func decodeDate
Operators.swift:46 return Decoder.decodeDecodable(key)(json)(key: String, dateFormatter: NSDateFormatter, keyPathDelimiter: String = GlossKeyPathDelimiter()) -> JSON -> NSDate? { 0087 return { 0088 json in 0089 0090 if let dateString = json.valueForKeyPath(key, withDelimiter: keyPathDelimiter) as? String { 0091 return dateFormatter.dateFromString(dateString) 0092 } 0093 0094 return nil 0095 } 0096 } 0097 0098 /** 0099 Returns function to decode JSON to ISO8601 date 0100 0101 :parameter: key JSON key used to set value 0102 :parameter: dateFormatter Formatter with ISO8601 format 0103 :parameter: keyPathDelimiter Delimiter used for nested keypath keys 0104 0105 - returns: Function decoding JSON to an optional ISO8601 date 0106 */ 0107 public static func decodeDateISO8601(key: String, keyPathDelimiter: String = GlossKeyPathDelimiter()) -> JSON -> NSDate? { 0108 let dateFormatter = NSDateFormatter() 0109 dateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX") 0110 dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ" 0111 0112 return Decoder.decodeDate(key, dateFormatter: dateFormatter, keyPathDelimiter: keyPathDelimiter) 0113 } 0114 0115 /** 0116 Returns function to decode JSON to enum value 0117 0118 :parameter: key JSON key used to set value 0119 :parameter: keyPathDelimiter Delimiter used for nested keypath keys 0120 0121 :returns: Function decoding JSON to an optional enum value 0122 */ 0123 public static func decodeEnum
Decoder.swift:112 return Decoder.decodeDate(key, dateFormatter: dateFormatter, keyPathDelimiter: keyPathDelimiter)<T: RawRepresentable>(key: String, keyPathDelimiter: String = GlossKeyPathDelimiter()) -> JSON -> T? { 0124 return { 0125 json in 0126 0127 if let rawValue = json.valueForKeyPath(key, withDelimiter: keyPathDelimiter) as? T.RawValue { 0128 return T(rawValue: rawValue) 0129 } 0130 0131 return nil 0132 } 0133 } 0134 0135 /** 0136 Returns function to decode JSON to URL 0137 0138 :parameter: key JSON key used to set value 0139 :parameter: keyPathDelimiter Delimiter used for nested keypath keys 0140 0141 :returns: Function decoding JSON to an optional URL 0142 */ 0143 public static func decodeURL
Operators.swift:53 return Decoder.decodeEnum(key)(json)(key: String, keyPathDelimiter: String = GlossKeyPathDelimiter()) -> JSON -> NSURL? { 0144 return { 0145 json in 0146 0147 if let urlString = json.valueForKeyPath(key, withDelimiter: keyPathDelimiter) as? String, 0148 encodedString = urlString.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet()) { 0149 return NSURL(string: encodedString) 0150 } 0151 0152 return nil 0153 } 0154 } 0155 0156 /** 0157 Returns function to decode JSON to array 0158 for objects that conform to the Glossy protocol 0159 0160 :parameter: key JSON key used to set value 0161 :parameter: keyPathDelimiter Delimiter used for nested keypath keys 0162 0163 :returns: Function decoding JSON to an optinal array 0164 */ 0165 public static func decodeDecodableArray
Operators.swift:60 return Decoder.decodeURL(key)(json)<T: Decodable>(key: String, keyPathDelimiter: String = GlossKeyPathDelimiter()) -> JSON -> [T]? { 0166 return { 0167 json in 0168 0169 if let jsonArray = json.valueForKeyPath(key, withDelimiter: keyPathDelimiter) as? [JSON] { 0170 var models: [T] = [] 0171 0172 for subJSON in jsonArray { 0173 if let model = T(json: subJSON) { 0174 models.append(model) 0175 } 0176 } 0177 0178 return models 0179 } 0180 0181 return nil 0182 } 0183 } 0184 0185 /** 0186 Returns function to decode JSON to dictionary of 0187 objects that conform to the Glossy protocol 0188 0189 :parameter: key JSON key used to set value 0190 :parameter: keyPathDelimiter Delimiter used for nested keypath keys 0191 0192 :returns: Function decoding JSON to an optional dictionary 0193 */ 0194 public static func decodeDecodableDictionary
Operators.swift:74 return Decoder.decodeDecodableArray(key)(json)<T:Decodable>(key: String, keyPathDelimiter: String = GlossKeyPathDelimiter()) -> JSON -> [String:T]? { 0195 return { 0196 json in 0197 0198 guard let dictionary = json.valueForKeyPath(key, withDelimiter: keyPathDelimiter) as? [String : JSON] else { 0199 return nil 0200 } 0201 0202 return dictionary.flatMap { (key, value) in 0203 guard let decoded = T(json: value) else { 0204 return nil 0205 } 0206 0207 return (key, decoded) 0208 } 0209 } 0210 } 0211 0212 /** 0213 Returns function to decode JSON to enum array 0214 of enum values 0215 0216 :parameter: key JSON key used to set value 0217 :parameter: keyPathDelimiter Delimiter used for nested keypath keys 0218 0219 :returns: Function decoding JSON to an optional enum array 0220 */ 0221 public static func decodeEnumArray
Operators.swift:88 return Decoder.decodeDecodableDictionary(key)(json)<T: RawRepresentable>(key: String, keyPathDelimiter: String = GlossKeyPathDelimiter()) -> JSON -> [T]? { 0222 return { 0223 json in 0224 0225 if let rawValues = json.valueForKeyPath(key, withDelimiter: keyPathDelimiter) as? [T.RawValue] { 0226 var enumValues: [T] = [] 0227 0228 for rawValue in rawValues { 0229 if let enumValue = T(rawValue: rawValue) { 0230 enumValues.append(enumValue) 0231 } 0232 } 0233 0234 return enumValues 0235 } 0236 0237 return nil 0238 } 0239 } 0240 0241 /** 0242 Returns function to decode JSON to date array 0243 0244 :parameter: key JSON key used to set value 0245 :parameter: dateFormatter Formatter used to format date 0246 :parameter: keyPathDelimiter Delimiter used for nested keypath keys 0247 0248 :returns: Function decoding JSON to an optional date array 0249 */ 0250 public static func decodeDateArray
Operators.swift:67 return Decoder.decodeEnumArray(key)(json)(key: String, dateFormatter: NSDateFormatter, keyPathDelimiter: String = GlossKeyPathDelimiter()) -> JSON -> [NSDate]? { 0251 return { 0252 json in 0253 0254 if let dateStrings = json.valueForKeyPath(key, withDelimiter: keyPathDelimiter) as? [String] { 0255 var dates: [NSDate] = [] 0256 0257 for dateString in dateStrings { 0258 if let date = dateFormatter.dateFromString(dateString) { 0259 dates.append(date) 0260 } 0261 } 0262 0263 return dates 0264 } 0265 0266 return nil 0267 } 0268 } 0269 0270 /** 0271 Returns function to decode JSON to ISO8601 date array 0272 0273 :parameter: key JSON key used to set value 0274 :parameter: dateFormatter Formatter with ISO8601 format 0275 :parameter: keyPathDelimiter Delimiter used for nested keypath keys 0276 0277 - returns: Function decoding JSON to an optional ISO8601 date array 0278 */ 0279 public static func decodeDateISO8601Array(key: String, keyPathDelimiter: String = GlossKeyPathDelimiter()) -> JSON -> [NSDate]? { 0280 let dateFormatter = NSDateFormatter() 0281 dateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX") 0282 dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ" 0283 0284 return Decoder.decodeDateArray(key, dateFormatter: dateFormatter, keyPathDelimiter: keyPathDelimiter) 0285 } 0286 0287 /** 0288 Returns function to decode JSON to URL array 0289 0290 :parameter: key JSON key used to set value 0291 :parameter: keyPathDelimiter Delimiter used for nested keypath keys 0292 0293 :returns: Function decoding JSON to an optional URL array 0294 */ 0295 public static func decodeURLArray
Decoder.swift:284 return Decoder.decodeDateArray(key, dateFormatter: dateFormatter, keyPathDelimiter: keyPathDelimiter)(key: String, keyPathDelimiter: String = GlossKeyPathDelimiter()) -> JSON -> [NSURL]? { 0296 return { 0297 json in 0298 0299 if let urlStrings = json.valueForKeyPath(key, withDelimiter: keyPathDelimiter) as? [String] { 0300 var urls: [NSURL] = [] 0301 0302 for urlString in urlStrings { 0303 if let url = NSURL(string: urlString) { 0304 urls.append(url) 0305 } 0306 } 0307 0308 return urls 0309 } 0310 0311 return nil 0312 } 0313 } 0314 0315 } 0316
Operators.swift:81 return Decoder.decodeURLArray(key)(json)