diff --git a/JSONCodable.xcodeproj/project.pbxproj b/JSONCodable.xcodeproj/project.pbxproj index 8d4d68e..d9fe2a4 100644 --- a/JSONCodable.xcodeproj/project.pbxproj +++ b/JSONCodable.xcodeproj/project.pbxproj @@ -27,8 +27,6 @@ 9EDB39491B59D0AF00C63019 /* JSONHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EDB393F1B59D0AF00C63019 /* JSONHelpers.swift */; }; 9EDB394D1B59D0AF00C63019 /* JSONString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EDB39411B59D0AF00C63019 /* JSONString.swift */; }; 9EDB394F1B59D0AF00C63019 /* JSONTransformer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EDB39421B59D0AF00C63019 /* JSONTransformer.swift */; }; - 9EDB39501B59D0AF00C63019 /* JSONTransformer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9EDB39421B59D0AF00C63019 /* JSONTransformer.swift */; }; - 9EDB39511B59D15400C63019 /* JSONCodable.h in Headers */ = {isa = PBXBuildFile; fileRef = 9EDB39091B59D00B00C63019 /* JSONCodable.h */; settings = {ATTRIBUTES = (Public, ); }; }; A10DFC4C1DF71BF400B7D6D7 /* ClassInheritanceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A10DFC4B1DF71BF400B7D6D7 /* ClassInheritanceTests.swift */; }; A1B71C7C1D37E6BD006DA33A /* JSONEncodable+Mirror.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1B71C7B1D37E6BD006DA33A /* JSONEncodable+Mirror.swift */; }; A1B71C7E1D37E90B006DA33A /* MirrorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1B71C7D1D37E90B006DA33A /* MirrorTests.swift */; }; @@ -241,22 +239,25 @@ 9EDF80101B59CFCE00E4A2D6 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0810; + LastUpgradeCheck = 1020; TargetAttributes = { 9E455BF61BCE185B00070A4F = { CreatedOnToolsVersion = 7.0.1; + LastSwiftMigration = 1020; }; 9EDB39051B59D00B00C63019 = { CreatedOnToolsVersion = 7.0; + LastSwiftMigration = 1020; }; }; }; buildConfigurationList = 9EDF80131B59CFCE00E4A2D6 /* Build configuration list for PBXProject "JSONCodable" */; compatibilityVersion = "Xcode 6.3"; - developmentRegion = English; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, + Base, ); mainGroup = 9EDF800F1B59CFCE00E4A2D6; productRefGroup = 9EDB39071B59D00B00C63019 /* Products */; @@ -384,7 +385,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 5.0; }; name = Debug; }; @@ -427,7 +428,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 5.0; }; name = Release; }; @@ -483,7 +484,7 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2,3,4"; TVOS_DEPLOYMENT_TARGET = 9.0; VERSIONING_SYSTEM = "apple-generic"; @@ -538,7 +539,7 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2,3,4"; TVOS_DEPLOYMENT_TARGET = 9.0; VALIDATE_PRODUCT = YES; @@ -551,12 +552,21 @@ 9EDF80141B59CFCE00E4A2D6 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; @@ -582,12 +592,21 @@ 9EDF80151B59CFCE00E4A2D6 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; diff --git a/JSONCodable.xcodeproj/xcshareddata/xcschemes/JSONCodable.xcscheme b/JSONCodable.xcodeproj/xcshareddata/xcschemes/JSONCodable.xcscheme index 603b4ee..5a389d4 100644 --- a/JSONCodable.xcodeproj/xcshareddata/xcschemes/JSONCodable.xcscheme +++ b/JSONCodable.xcodeproj/xcshareddata/xcschemes/JSONCodable.xcscheme @@ -1,6 +1,6 @@ + + + + IDEDidComputeMac32BitWarning + + + diff --git a/JSONCodable/JSONDecodable.swift b/JSONCodable/JSONDecodable.swift index 7c45e56..0fcea24 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)) } @@ -96,12 +96,13 @@ 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() + internal func parseArrayIndex(_ key: String) -> Int? { + var chars = key + let first = chars.first + chars = String(chars.dropFirst()) let last = chars.popLast() if first == "[" && last == "]" { - return Int(String(chars)) + return Int(chars) } 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..10165a8 100644 --- a/JSONCodable/JSONEncodable.swift +++ b/JSONCodable/JSONEncodable.swift @@ -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..5fc47ff 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) @@ -27,8 +27,8 @@ public extension JSONEncodable { } private func escapeJSONString(_ str: String) -> String { - var chars = String.CharacterView("\"") - for c in str.characters { + var chars = "\"" + for c in str { switch c { case "\\": chars.append("\\") @@ -41,11 +41,11 @@ private func escapeJSONString(_ str: String) -> String { } } chars.append("\"") - return String(chars) + return chars } 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..30a00cc 100644 --- a/JSONCodableTests/EncodeNestingTests.swift +++ b/JSONCodableTests/EncodeNestingTests.swift @@ -28,6 +28,20 @@ class EncodeNestingTests: XCTestCase { XCTFail() return } - XCTAssert(String(describing:json1) == String(describing:propertyItemArray), "failed to convert to \(propertyItemArray)") + + XCTAssertEqual(json1["class"] as! String, propertyItemArray["class"] as! String) + XCTAssertEqual(json1["class"] as! String, propertyItemArray["class"] as! String) + + let properties = propertyItemArray["properties"] as! [String: Any] + let properties1 = json1["properties"] as! [String: Any] + XCTAssertEqual(properties1["name"] as! String, properties["name"] as! String) + + let location = properties["location"] as! [String: Any] + let location1 = properties1["location"] as! [String: Any] + + let coord = location["coord"] as! [String: Any] + let coord1 = location1["coord"] as! [String: Any] + XCTAssertEqual(coord["lat"] as! Double, coord1["lat"] as! Double) + XCTAssertEqual(coord["long"] as! Double, coord1["long"] as! Double) } }