From e012bb14baa23f5f54b17e134086969f91554ace Mon Sep 17 00:00:00 2001 From: Christoffer Winterkvist Date: Thu, 11 May 2017 11:36:37 +0200 Subject: [PATCH 1/4] Add support for mapping booleans Add method for mapping boolean value from a Dictionary. --- .../Shared/Extensions/Dictionary+Tailor.swift | 22 +++++++++++++++++++ .../Shared/DefaultTypesMappingTests.swift | 5 +++++ 2 files changed, 27 insertions(+) diff --git a/Sources/Shared/Extensions/Dictionary+Tailor.swift b/Sources/Shared/Extensions/Dictionary+Tailor.swift index 613905a..55c8106 100644 --- a/Sources/Shared/Extensions/Dictionary+Tailor.swift +++ b/Sources/Shared/Extensions/Dictionary+Tailor.swift @@ -91,6 +91,26 @@ public extension Dictionary { return property(name) } + /// Map value using key to String + /// + /// - Parameter name: The name of the key. + /// - Returns: An optional String + func boolean(_ name: String) -> Bool? { + guard let key = name as? Key else { + return nil + } + + if let string = self[key] as? String { + return string == "true" ? true : false + } else if let number = self[key] as? NSNumber { + return number.boolValue + } else if let boolean = self[key] as? Bool { + return boolean + } else { + return nil + } + } + /// A generic method that maps a value from a key to a specific type. /// /// - Parameters: @@ -110,6 +130,8 @@ public extension Dictionary { return value } else { switch ofType { + case is Bool.Type: + return boolean(forKey) as? T case is Double.Type: return double(forKey) as? T case is Float.Type: diff --git a/TailorTests/Shared/DefaultTypesMappingTests.swift b/TailorTests/Shared/DefaultTypesMappingTests.swift index 6dfde96..66a128c 100644 --- a/TailorTests/Shared/DefaultTypesMappingTests.swift +++ b/TailorTests/Shared/DefaultTypesMappingTests.swift @@ -12,6 +12,8 @@ class TestMappingDefaultTypes: QuickSpec { "name" : "Swedish Chef", "int": 1, "float": 2.5, + "bool" : true, + "string_bool" : "true", "string": "1.25", "array" : [ "foo", "bar", "baz" @@ -40,6 +42,9 @@ class TestMappingDefaultTypes: QuickSpec { expect(dictionary.value(forKey: "string", ofType: Int.self)).to(equal(1)) expect(dictionary.value(forKey: "string", ofType: String.self)).to(equal("1.25")) + expect(dictionary.value(forKey: "bool", ofType: Bool.self)).to(equal(true)) + expect(dictionary.value(forKey: "string_bool", ofType: Bool.self)).to(equal(true)) + expect(dictionary.string("string")).to(equal("1.25")) expect(dictionary.float("name")).to(beNil()) From e2b79002f04b30e5d3ac68bf1169bbb6aab545b4 Mon Sep 17 00:00:00 2001 From: Christoffer Winterkvist Date: Thu, 11 May 2017 13:57:06 +0200 Subject: [PATCH 2/4] Improve boolean string mapping Consider "true" and "1" to be equal to true and "false", "0" to be false when mapping booleans. Otherwise return nil. --- Sources/Shared/Extensions/Dictionary+Tailor.swift | 9 ++++++++- TailorTests/Shared/DefaultTypesMappingTests.swift | 4 ++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Sources/Shared/Extensions/Dictionary+Tailor.swift b/Sources/Shared/Extensions/Dictionary+Tailor.swift index 55c8106..104f84b 100644 --- a/Sources/Shared/Extensions/Dictionary+Tailor.swift +++ b/Sources/Shared/Extensions/Dictionary+Tailor.swift @@ -101,7 +101,14 @@ public extension Dictionary { } if let string = self[key] as? String { - return string == "true" ? true : false + + if ["true", "1"].contains(string.lowercased()) { + return true + } else if ["false", "0"].contains(string.lowercased()) { + return false + } + + return nil } else if let number = self[key] as? NSNumber { return number.boolValue } else if let boolean = self[key] as? Bool { diff --git a/TailorTests/Shared/DefaultTypesMappingTests.swift b/TailorTests/Shared/DefaultTypesMappingTests.swift index 66a128c..d13bbaa 100644 --- a/TailorTests/Shared/DefaultTypesMappingTests.swift +++ b/TailorTests/Shared/DefaultTypesMappingTests.swift @@ -14,6 +14,7 @@ class TestMappingDefaultTypes: QuickSpec { "float": 2.5, "bool" : true, "string_bool" : "true", + "string_number_bool" : "1", "string": "1.25", "array" : [ "foo", "bar", "baz" @@ -44,6 +45,7 @@ class TestMappingDefaultTypes: QuickSpec { expect(dictionary.value(forKey: "bool", ofType: Bool.self)).to(equal(true)) expect(dictionary.value(forKey: "string_bool", ofType: Bool.self)).to(equal(true)) + expect(dictionary.value(forKey: "string_number_bool", ofType: Bool.self)).to(equal(true)) expect(dictionary.string("string")).to(equal("1.25")) @@ -67,6 +69,8 @@ class TestMappingDefaultTypes: QuickSpec { expect(dictionary.int("string")).to(equal(1)) expect(dictionary.string("string")).to(equal("1.25")) + expect(dictionary.boolean("string_number_bool")).to(equal(true)) + } } } From e7ce7fc22a689a9e0ec58d7e0f956296382e880d Mon Sep 17 00:00:00 2001 From: Christoffer Winterkvist Date: Thu, 11 May 2017 14:03:13 +0200 Subject: [PATCH 3/4] Update README.md --- README.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/README.md b/README.md index c5a36b3..a6cf767 100644 --- a/README.md +++ b/README.md @@ -174,6 +174,30 @@ let dictionary = [ let model = Person(dictionary) ``` +## Resolving value types. + +Tailor supports mapping values from dictionaries using type specific functions. + +```swift +dictionary.boolean("key") +dictionary.double("key") +dictionary.float("key") +dictionary.int("key") +dictionary.string("key") +``` + +You can also use `value(forKey:ofType:)`, it works like this. + +```swift +dictionary.value(forKey: "key", ofType: Boolean.self) +dictionary.value(forKey: "key", ofType: Double.self) +dictionary.value(forKey: "key", ofType: Float.self) +dictionary.value(forKey: "key", ofType: Int.self) +dictionary.value(forKey: "key", ofType: String.self) +``` + +All of these methods returns an optional value. + ## Installation **Tailor** is available through [CocoaPods](http://cocoapods.org). To install From d0281466960e44455a02b5c957e117c745857f05 Mon Sep 17 00:00:00 2001 From: Christoffer Winterkvist Date: Thu, 11 May 2017 14:07:34 +0200 Subject: [PATCH 4/4] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a6cf767..5b16999 100644 --- a/README.md +++ b/README.md @@ -189,7 +189,7 @@ dictionary.string("key") You can also use `value(forKey:ofType:)`, it works like this. ```swift -dictionary.value(forKey: "key", ofType: Boolean.self) +dictionary.value(forKey: "key", ofType: Bool.self) dictionary.value(forKey: "key", ofType: Double.self) dictionary.value(forKey: "key", ofType: Float.self) dictionary.value(forKey: "key", ofType: Int.self)