Skip to content

Commit 2b80203

Browse files
committed
adding map support
1 parent d267df2 commit 2b80203

3 files changed

Lines changed: 218 additions & 7 deletions

File tree

JSONHelper.xcodeproj/project.pbxproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
5FAD07691A70F2FC00C4D09E /* JSONHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JSONHelper.h; sourceTree = "<group>"; };
5353
5FAD076F1A70F2FC00C4D09E /* JSONHelperTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = JSONHelperTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
5454
5FAD07751A70F2FC00C4D09E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
55-
5FAD07761A70F2FC00C4D09E /* JSONHelperTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JSONHelperTests.swift; sourceTree = "<group>"; };
55+
5FAD07761A70F2FC00C4D09E /* JSONHelperTests.swift */ = {isa = PBXFileReference; indentWidth = 2; lastKnownFileType = sourcecode.swift; path = JSONHelperTests.swift; sourceTree = "<group>"; tabWidth = 2; };
5656
5FAD07841A70F31300C4D09E /* JSONHelperExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = JSONHelperExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
5757
5FAD07871A70F31300C4D09E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
5858
5FAD07881A70F31300C4D09E /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };

JSONHelper/JSONHelper.swift

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,157 @@ public func <-- (inout array: [NSDate], value: AnyObject?) -> [NSDate] {
268268
return array
269269
}
270270

271+
272+
// MARK: Primitive Map Deserialization
273+
274+
public func <-- (inout map: [String:String]?, value: AnyObject?) -> [String:String]? {
275+
if let stringMap = convertToNilIfNull(value) as? [String:String] {
276+
map = stringMap
277+
} else {
278+
map = nil
279+
}
280+
return map
281+
}
282+
283+
public func <-- (inout map: [String:String], value: AnyObject?) -> [String:String] {
284+
var newValue: [String:String]?
285+
newValue <-- value
286+
if let newValue = newValue { map = newValue }
287+
return map
288+
}
289+
290+
public func <-- (inout map: [String:Int]?, value: AnyObject?) -> [String:Int]? {
291+
if let intMap = convertToNilIfNull(value) as? [String:Int] {
292+
map = intMap
293+
} else {
294+
map = nil
295+
}
296+
return map
297+
}
298+
299+
public func <-- (inout map: [String:Int], value: AnyObject?) -> [String:Int] {
300+
var newValue: [String:Int]?
301+
newValue <-- value
302+
if let newValue = newValue { map = newValue }
303+
return map
304+
}
305+
306+
public func <-- (inout map: [String:Float]?, value: AnyObject?) -> [String:Float]? {
307+
if let floatMap = convertToNilIfNull(value) as? [String:Float] {
308+
map = floatMap
309+
} else {
310+
map = nil
311+
}
312+
return map
313+
}
314+
315+
public func <-- (inout map: [String:Float], value: AnyObject?) -> [String:Float] {
316+
var newValue: [String:Float]?
317+
newValue <-- value
318+
if let newValue = newValue { map = newValue }
319+
return map
320+
}
321+
322+
public func <-- (inout map: [String:Double]?, value: AnyObject?) -> [String:Double]? {
323+
if let doubleMapDoubleExcitement = convertToNilIfNull(value) as? [String:Double] {
324+
map = doubleMapDoubleExcitement
325+
} else {
326+
map = nil
327+
}
328+
return map
329+
}
330+
331+
public func <-- (inout map: [String:Double], value: AnyObject?) -> [String:Double] {
332+
var newValue: [String:Double]?
333+
newValue <-- value
334+
if let newValue = newValue { map = newValue }
335+
return map
336+
}
337+
338+
public func <-- (inout map: [String:Bool]?, value: AnyObject?) -> [String:Bool]? {
339+
if let boolMap = convertToNilIfNull(value) as? [String:Bool] {
340+
map = boolMap
341+
} else {
342+
map = nil
343+
}
344+
return map
345+
}
346+
347+
public func <-- (inout map: [String:Bool], value: AnyObject?) -> [String:Bool] {
348+
var newValue: [String:Bool]?
349+
newValue <-- value
350+
if let newValue = newValue { map = newValue }
351+
return map
352+
}
353+
354+
public func <-- (inout map: [String:NSURL]?, value: AnyObject?) -> [String:NSURL]? {
355+
if let stringURLMap = convertToNilIfNull(value) as? [String:String] {
356+
map = [String:NSURL]()
357+
for (key, stringURL) in stringURLMap {
358+
if let url = NSURL(string: stringURL) {
359+
map![key] = url
360+
}
361+
}
362+
} else {
363+
map = nil
364+
}
365+
return map
366+
}
367+
368+
public func <-- (inout map: [String:NSURL], value: AnyObject?) -> [String:NSURL] {
369+
var newValue: [String:NSURL]?
370+
newValue <-- value
371+
if let newValue = newValue { map = newValue }
372+
return map
373+
}
374+
375+
public func <-- (inout map: [String:NSDate]?, valueAndFormat: (AnyObject?, AnyObject?)) -> [String:NSDate]? {
376+
var newValue: [String:NSDate]?
377+
if let dateStringMap = convertToNilIfNull(valueAndFormat.0) as? [String:String] {
378+
if let formatString = convertToNilIfNull(valueAndFormat.1) as? String {
379+
let dateFormatter = NSDateFormatter()
380+
dateFormatter.dateFormat = formatString
381+
newValue = [String:NSDate]()
382+
for (key, dateString) in dateStringMap {
383+
if let date = dateFormatter.dateFromString(dateString) {
384+
newValue![key] = date
385+
}
386+
}
387+
}
388+
}
389+
map = newValue
390+
return map
391+
}
392+
393+
public func <-- (inout map: [String:NSDate], valueAndFormat: (AnyObject?, AnyObject?)) -> [String:NSDate] {
394+
var newValue: [String:NSDate]?
395+
newValue <-- valueAndFormat
396+
if let newValue = newValue { map = newValue }
397+
return map
398+
}
399+
400+
public func <-- (inout map: [String:NSDate]?, value: AnyObject?) -> [String:NSDate]? {
401+
if let timestamps = convertToNilIfNull(value) as? [String:AnyObject] {
402+
map = [String:NSDate]()
403+
for (key, timestamp) in timestamps {
404+
var date: NSDate?
405+
date <-- timestamp
406+
if date != nil { map![key] = date! }
407+
}
408+
} else {
409+
map = nil
410+
}
411+
return map
412+
}
413+
414+
public func <-- (inout map: [String:NSDate], value: AnyObject?) -> [String:NSDate] {
415+
var newValue: [String:NSDate]?
416+
newValue <-- value
417+
if let newValue = newValue { map = newValue }
418+
return map
419+
}
420+
421+
271422
// MARK: Custom Object Deserialization
272423

273424
public protocol Deserializable {
@@ -311,6 +462,27 @@ public func <-- <T: Deserializable>(inout array: [T], dataObject: AnyObject?) ->
311462
return array
312463
}
313464

465+
// MARK: Custom Object Map Deserialization
466+
467+
public func <-- <T: Deserializable>(inout map: [String:T]?, dataObject: AnyObject?) -> [String:T]? {
468+
if let dataMap = convertToNilIfNull(dataObject) as? [String:JSONDictionary] {
469+
map = [String:T]()
470+
for (key, data) in dataMap {
471+
map![key] = T(data: data)
472+
}
473+
} else {
474+
map = nil
475+
}
476+
return map
477+
}
478+
479+
public func <-- <T: Deserializable>(inout map: [String:T], dataObject: AnyObject?) -> [String:T] {
480+
var newMap: [String:T]?
481+
newMap <-- dataObject
482+
if let newMap = newMap { map = newMap }
483+
return map
484+
}
485+
314486
// MARK: Raw Value Representable (Enum) Deserialization
315487

316488
public func <-- <T: RawRepresentable>(inout property: T?, value: AnyObject?) -> T? {
@@ -356,4 +528,12 @@ public func <-- <T: Deserializable>(inout array: [T], dataString: String) -> [T]
356528
return array <-- dataStringToObject(dataString)
357529
}
358530

531+
public func <-- <T: Deserializable>(inout map: [String:T]?, dataString: String) -> [String:T]? {
532+
return map <-- dataStringToObject(dataString)
533+
}
534+
535+
public func <-- <T: Deserializable>(inout map: [String:T], dataString: String) -> [String:T] {
536+
return map <-- dataStringToObject(dataString)
537+
}
538+
359539

JSONHelperTests/JSONHelperTests.swift

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,14 @@ class JSONHelperTests: XCTestCase {
3030
], [
3131
"name": "d"
3232
]
33+
],
34+
"instanceMap": [
35+
"ePerson": [
36+
"name": "e"
37+
],
38+
"fPerson": [
39+
"name": "f"
40+
]
3341
]
3442
]
3543

@@ -176,24 +184,47 @@ class JSONHelperTests: XCTestCase {
176184
property <-- dummyResponse["instanceArray"]
177185
XCTAssertEqual(property.count, 2, "[Person] property should have 2 members")
178186
}
179-
187+
188+
func testInstanceMap() {
189+
var property = [String:Person]()
190+
property <-- dummyResponse["instanceMap"]
191+
XCTAssertEqual(property["ePerson"]!.name, "e", "member \"ePerson\" of [String:Person] property should have \"e\" for name")
192+
}
193+
180194
func testRawValueEnum() {
181195
var property = EnumTest.Zero
182196
property <-- dummyResponse["int"]
183197
XCTAssertEqual(property, EnumTest.One, "EnumTest should be equal to .One")
184198
}
185-
186-
func testJSONStringParsing() {
199+
200+
func testJSONStringArrayParsing() {
187201
var jsonString = "[{\"name\": \"I am \"},{\"name\": \"Groot!\"}]"
188202
var people = [Person]()
189203
var areYouGroot = ""
190-
204+
191205
people <-- jsonString
192-
206+
193207
for person in people {
194208
areYouGroot += person.name
195209
}
196-
210+
211+
XCTAssertEqual(areYouGroot, "I am Groot!", "Groot should be Groot")
212+
}
213+
214+
func testJSONStringMapParsing() {
215+
var jsonString = "{\"person one\": {\"name\": \"I am \"}, \"person two\": {\"name\": \"Groot!\"}}"
216+
var people = [String:Person]()
217+
var areYouGroot = ""
218+
var keys = ""
219+
220+
people <-- jsonString
221+
222+
for (personKey, person) in people {
223+
areYouGroot += person.name
224+
keys += personKey
225+
}
226+
227+
XCTAssertEqual(keys, "person oneperson two", "keys should be correctly picked up")
197228
XCTAssertEqual(areYouGroot, "I am Groot!", "Groot should be Groot")
198229
}
199230
}

0 commit comments

Comments
 (0)