diff --git a/JSONCodable.xcodeproj/project.pbxproj b/JSONCodable.xcodeproj/project.pbxproj index 8d4d68e..66474d4 100644 --- a/JSONCodable.xcodeproj/project.pbxproj +++ b/JSONCodable.xcodeproj/project.pbxproj @@ -384,7 +384,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 4.0; }; name = Debug; }; @@ -427,7 +427,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 4.0; }; name = Release; }; @@ -483,7 +483,7 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 4.0; TARGETED_DEVICE_FAMILY = "1,2,3,4"; TVOS_DEPLOYMENT_TARGET = 9.0; VERSIONING_SYSTEM = "apple-generic"; @@ -538,7 +538,7 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 4.0; TARGETED_DEVICE_FAMILY = "1,2,3,4"; TVOS_DEPLOYMENT_TARGET = 9.0; VALIDATE_PRODUCT = YES; @@ -574,7 +574,7 @@ ONLY_ACTIVE_ARCH = YES; SUPPORTED_PLATFORMS = "iphoneos macosx appletvos watchos appletvsimulator iphonesimulator watchsimulator"; SWIFT_INSTALL_OBJC_HEADER = NO; - SWIFT_VERSION = 3.0.1; + SWIFT_VERSION = 4.0; TARGETED_DEVICE_FAMILY = "1,2,3,4"; }; name = Debug; diff --git a/JSONCodable/JSONDecodable.swift b/JSONCodable/JSONDecodable.swift index 7c45e56..4d9e81f 100644 --- a/JSONCodable/JSONDecodable.swift +++ b/JSONCodable/JSONDecodable.swift @@ -54,12 +54,12 @@ public protocol JSONDecodable { public extension JSONDecodable { /// initialize with top-level Array JSON data - public init(object: [JSONObject]) throws { + init(object: [JSONObject]) throws { // use empty string key try self.init(object:["": object]) } - public init?(optional: JSONObject) { + init?(optional: JSONObject) { do { try self.init(object: optional) } catch { @@ -70,7 +70,7 @@ public extension JSONDecodable { public extension Array where Element: JSONDecodable { init(JSONArray: [Any], filtered: Bool = false) throws { - self.init(try JSONArray.flatMap { + self.init(try JSONArray.compactMap { guard let json = $0 as? [String : Any] else { throw JSONDecodableError.dictionaryTypeExpectedError(key: "n/a", elementType: type(of: $0)) } @@ -97,11 +97,12 @@ public class JSONDecoder { /// Get index from `"[0]"` formatted `String` /// returns `nil` if invalid format (i.e. no brackets or contents not an `Int`) internal func parseArrayIndex(_ key:String) -> Int? { - var chars = key.characters - let first = chars.popFirst() - let last = chars.popLast() + var mkey = key + let first = mkey[mkey.startIndex] + mkey.remove(at: mkey.startIndex) + let last = mkey.popLast() if first == "[" && last == "]" { - return Int(String(chars)) + return Int(mkey) } else { return nil } @@ -228,7 +229,7 @@ public class JSONDecoder { guard let array = value as? [JSONObject] else { throw JSONDecodableError.arrayTypeExpectedError(key: key, elementType: type(of: value)) } - return try array.flatMap { + return try array.compactMap { if filter { return try? Element(object: $0) } else { @@ -245,7 +246,7 @@ public class JSONDecoder { guard let array = value as? [JSONObject] else { throw JSONDecodableError.arrayTypeExpectedError(key: key, elementType: type(of: value)) } - return try array.flatMap { + return try array.compactMap { if filter { return try? Element(object: $0) } else { @@ -266,10 +267,10 @@ public class JSONDecoder { for x in array { if filter { - let nested = x.flatMap { try? Element(object: $0)} + let nested = x.compactMap { try? Element(object: $0)} res.append(nested) } else { - let nested = try x.flatMap { try Element(object: $0)} + let nested = try x.compactMap { try Element(object: $0)} res.append(nested) } } @@ -300,7 +301,7 @@ public class JSONDecoder { guard let array = value as? [Enum.RawValue] else { throw JSONDecodableError.arrayTypeExpectedError(key: key, elementType: type(of: value)) } - return array.flatMap { Enum(rawValue: $0) } + return array.compactMap { Enum(rawValue: $0) } } // [Enum]? @@ -311,7 +312,7 @@ public class JSONDecoder { guard let array = value as? [Enum.RawValue] else { throw JSONDecodableError.arrayTypeExpectedError(key: key, elementType: type(of: value)) } - return array.flatMap { Enum(rawValue: $0) } + return array.compactMap { Enum(rawValue: $0) } } // [String:JSONCompatible] diff --git a/JSONCodable/JSONEncodable+Mirror.swift b/JSONCodable/JSONEncodable+Mirror.swift index 45d53eb..0dfbb60 100644 --- a/JSONCodable/JSONEncodable+Mirror.swift +++ b/JSONCodable/JSONEncodable+Mirror.swift @@ -12,7 +12,7 @@ public extension Mirror { - returns: array of Tuples containing the label and value for each property */ - public func getAllProperties() -> [(label: String?, value: Any)] { + func getAllProperties() -> [(label: String?, value: Any)] { var children: [(label: String?, value: Any)] = [] for element in self.children { children.append(element) diff --git a/JSONCodable/JSONEncodable.swift b/JSONCodable/JSONEncodable.swift index 4e62ec4..596f210 100644 --- a/JSONCodable/JSONEncodable.swift +++ b/JSONCodable/JSONEncodable.swift @@ -54,8 +54,8 @@ public extension JSONEncodable { let mirror = Mirror(reflecting: self) #if !swift(>=3.0) - guard let style = mirror.displayStyle where style == .Struct || style == .Class else { - throw JSONEncodableError.IncompatibleTypeError(elementType: self.dynamicType) + guard let style = mirror.displayStyle, (style == .Struct || style == .Class) else { + throw JSONEncodableError.IncompatibleTypeError(elementType: type(of: self)) } #else @@ -105,7 +105,7 @@ public extension JSONEncodable { public extension Array { //where Element: JSONEncodable { private var wrapped: [Any] { return self.map{$0} } - public func toJSON() throws -> Any { + func toJSON() throws -> Any { var results: [Any] = [] for item in self.wrapped { if let item = item as? JSONEncodable { @@ -122,7 +122,7 @@ public extension Array { //where Element: JSONEncodable { // Dictionary convenience methods public extension Dictionary {//where Key: String, Value: JSONEncodable { - public func toJSON() throws -> Any { + func toJSON() throws -> Any { var result: [String: Any] = [:] for (k, item) in self { if let item = item as? JSONEncodable { @@ -246,7 +246,7 @@ public class JSONEncoder { // [Enum] public func encode(_ value: [Enum], key: String) throws { - let result = try value.flatMap { + let result = try value.compactMap { try ($0.rawValue as? JSONCompatible)?.toJSON() } object = update(object: object, keys: key.components(separatedBy: "."), value: result) @@ -257,7 +257,7 @@ public class JSONEncoder { guard let actual = value else { return } - let result = try actual.flatMap { + let result = try actual.compactMap { try ($0.rawValue as? JSONCompatible)?.toJSON() } object = update(object: object, keys: key.components(separatedBy: "."), value: result) diff --git a/JSONCodable/JSONString.swift b/JSONCodable/JSONString.swift index 88ee3c8..c45115e 100644 --- a/JSONCodable/JSONString.swift +++ b/JSONCodable/JSONString.swift @@ -9,7 +9,7 @@ import Foundation public extension JSONEncodable { - public func toJSONString() throws -> String { + func toJSONString() throws -> String { switch self { case let str as String: return escapeJSONString(str) @@ -45,7 +45,7 @@ private func escapeJSONString(_ str: String) -> String { } public extension Optional where Wrapped: JSONEncodable { - public func toJSONString() throws -> String { + func toJSONString() throws -> String { switch self { case let .some(jsonEncodable): return try jsonEncodable.toJSONString() diff --git a/JSONCodableTests/EncodeNestingTests.swift b/JSONCodableTests/EncodeNestingTests.swift index 3c5e66c..b61e15c 100644 --- a/JSONCodableTests/EncodeNestingTests.swift +++ b/JSONCodableTests/EncodeNestingTests.swift @@ -28,6 +28,15 @@ class EncodeNestingTests: XCTestCase { XCTFail() return } - XCTAssert(String(describing:json1) == String(describing:propertyItemArray), "failed to convert to \(propertyItemArray)") + + XCTAssert(propertyItemArray.isEqual(to: json1), "failed to convert to \(propertyItemArray)") } } + +private extension JSONObject { + + func isEqual(to obj: JSONObject) -> Bool { + (self as NSDictionary).isEqual(to: obj) + } + +}