From a480cd929afa068ea0b5bc56567a0b41b68100e3 Mon Sep 17 00:00:00 2001 From: Corey's iMac Date: Sun, 24 May 2020 08:59:54 -0400 Subject: [PATCH 1/4] Fix most of the warnings. Need to look into codable/decodable any --- Sources/ParseSwift/API/API+Commands.swift | 10 +++++----- Sources/ParseSwift/API/API.swift | 16 ++++++++-------- Sources/ParseSwift/Asynchronous.swift | 4 ++-- Sources/ParseSwift/Encoder/ParseEncoder.swift | 2 +- .../Objects Protocols/ObjectType+Batch.swift | 2 +- .../Objects Protocols/ObjectType+Query.swift | 6 +++--- .../Objects Protocols/ObjectType.swift | 10 +++++----- Sources/ParseSwift/Storage/KeychainStore.swift | 2 +- 8 files changed, 26 insertions(+), 26 deletions(-) diff --git a/Sources/ParseSwift/API/API+Commands.swift b/Sources/ParseSwift/API/API+Commands.swift index 86a458d28..c63ac8cf8 100644 --- a/Sources/ParseSwift/API/API+Commands.swift +++ b/Sources/ParseSwift/API/API+Commands.swift @@ -9,7 +9,7 @@ import Foundation internal extension API { - internal struct Command: Encodable where T: Encodable { + struct Command: Encodable where T: Encodable { typealias ReturnType = U let method: API.Method let path: API.Endpoint @@ -63,7 +63,7 @@ internal extension API { internal extension API.Command { // MARK: Saving - internal static func saveCommand(_ object: T) -> API.Command where T: ObjectType { + static func saveCommand(_ object: T) -> API.Command where T: ObjectType { if object.isSaved { return updateCommand(object) } @@ -92,7 +92,7 @@ internal extension API.Command { } // MARK: Fetching - internal static func fetchCommand(_ object: T) throws -> API.Command where T: ObjectType { + static func fetchCommand(_ object: T) throws -> API.Command where T: ObjectType { guard object.isSaved else { throw ParseError(code: .unknownError, message: "Cannot Fetch an object without id") } @@ -111,7 +111,7 @@ extension API.Command where T: ObjectType { } static func batch(commands: [API.Command]) -> RESTBatchCommandType { - let commands = commands.flatMap { (command) -> API.Command? in + let commands = commands.compactMap { (command) -> API.Command? in let path = ParseConfiguration.mountPath + command.path.urlComponent guard let body = command.body else { return nil @@ -119,7 +119,7 @@ extension API.Command where T: ObjectType { return API.Command(method: command.method, path: .any(path), body: body, mapper: command.mapper) } - let bodies = commands.flatMap { (command) -> T? in + let bodies = commands.compactMap { (command) -> T? in return command.body } let mapper = { (data: Data) -> [(T, ParseError?)] in diff --git a/Sources/ParseSwift/API/API.swift b/Sources/ParseSwift/API/API.swift index dac960380..c371d02ec 100644 --- a/Sources/ParseSwift/API/API.swift +++ b/Sources/ParseSwift/API/API.swift @@ -54,22 +54,22 @@ public struct API { case useMasterKey case sessionToken(String) case installationId(String) - - // use HashValue so we can use in a sets - public var hashValue: Int { + + public func hash(into hasher: inout Hasher){ switch self { case .useMasterKey: - return 1 + hasher.combine(1) case .sessionToken: - return 2 + hasher.combine(2) case .installationId: - return 3 + hasher.combine(3) } } - + //Check to see if the compliler handles this + /* public static func == (lhs: API.Option, rhs: API.Option) -> Bool { return lhs.hashValue == rhs.hashValue - } + }*/ } internal static func getHeaders(options: API.Options) -> [String: String] { diff --git a/Sources/ParseSwift/Asynchronous.swift b/Sources/ParseSwift/Asynchronous.swift index 03a284abc..32aefd2d9 100644 --- a/Sources/ParseSwift/Asynchronous.swift +++ b/Sources/ParseSwift/Asynchronous.swift @@ -47,7 +47,7 @@ extension Querying { } public extension ObjectType { - public static func saveAll(options: API.Options = [], + static func saveAll(options: API.Options = [], _ objects: Self..., callback: @escaping ([(Self, ParseError?)]?, Error?) -> Void) { objects.saveAll(options: options, callback: callback) @@ -55,7 +55,7 @@ public extension ObjectType { } public extension Sequence where Element: ObjectType { - public func saveAll(options: API.Options = [], + func saveAll(options: API.Options = [], callback: @escaping ([(Element, ParseError?)]?, Error?) -> Void) { runAsync(options: options, function: self.saveAll, callback: callback) } diff --git a/Sources/ParseSwift/Encoder/ParseEncoder.swift b/Sources/ParseSwift/Encoder/ParseEncoder.swift index 76f6d4635..9a17fe778 100644 --- a/Sources/ParseSwift/Encoder/ParseEncoder.swift +++ b/Sources/ParseSwift/Encoder/ParseEncoder.swift @@ -841,7 +841,7 @@ fileprivate extension EncodingError { /// - parameter value: The value that was invalid to encode. /// - parameter path: The path of `CodingKey`s taken to encode this value. /// - returns: An `EncodingError` with the appropriate path and debug description. - fileprivate static func _invalidFloatingPointValue(_ value: T, at codingPath: [CodingKey]) -> EncodingError { + static func _invalidFloatingPointValue(_ value: T, at codingPath: [CodingKey]) -> EncodingError { let valueDescription: String if value == T.infinity { valueDescription = "\(T.self).infinity" diff --git a/Sources/ParseSwift/Objects Protocols/ObjectType+Batch.swift b/Sources/ParseSwift/Objects Protocols/ObjectType+Batch.swift index 9b38b9bac..8b2823ecc 100644 --- a/Sources/ParseSwift/Objects Protocols/ObjectType+Batch.swift +++ b/Sources/ParseSwift/Objects Protocols/ObjectType+Batch.swift @@ -9,7 +9,7 @@ import Foundation public extension ObjectType { - public static func saveAll(_ objects: Self...) throws -> [(Self, ParseError?)] { + static func saveAll(_ objects: Self...) throws -> [(Self, ParseError?)] { return try objects.saveAll() } } diff --git a/Sources/ParseSwift/Objects Protocols/ObjectType+Query.swift b/Sources/ParseSwift/Objects Protocols/ObjectType+Query.swift index 03fe8d1d5..c963094d3 100644 --- a/Sources/ParseSwift/Objects Protocols/ObjectType+Query.swift +++ b/Sources/ParseSwift/Objects Protocols/ObjectType+Query.swift @@ -9,15 +9,15 @@ import Foundation public extension ObjectType { - public static func find() throws -> [Self] { + static func find() throws -> [Self] { return try query().find() } - public static func query() -> Query { + static func query() -> Query { return Query() } - public static func query(_ constraints: QueryConstraint...) -> Query { + static func query(_ constraints: QueryConstraint...) -> Query { return Query(constraints) } } diff --git a/Sources/ParseSwift/Objects Protocols/ObjectType.swift b/Sources/ParseSwift/Objects Protocols/ObjectType.swift index 4693850a5..1b8da620c 100644 --- a/Sources/ParseSwift/Objects Protocols/ObjectType.swift +++ b/Sources/ParseSwift/Objects Protocols/ObjectType.swift @@ -43,7 +43,7 @@ public protocol ObjectType: Fetching, Saving, CustomDebugStringConvertible, Equa } internal extension ObjectType { - internal func getEncoder() -> ParseEncoder { + func getEncoder() -> ParseEncoder { return getParseEncoder() } } @@ -102,10 +102,10 @@ let dateEncodingStrategy: JSONEncoder.DateEncodingStrategy = .custom({ (date, en }) internal extension Date { - internal func parseFormatted() -> String { + func parseFormatted() -> String { return dateFormatter.string(from: self) } - internal var parseRepresentation: [String: String] { + var parseRepresentation: [String: String] { return ["__type": "Date", "iso": parseFormatted()] } } @@ -161,11 +161,11 @@ func getDecoder() -> JSONDecoder { } public extension ObjectType { - public func save(options: API.Options) throws -> Self { + func save(options: API.Options) throws -> Self { return try saveCommand().execute(options: options) } - public func fetch(options: API.Options) throws -> Self { + func fetch(options: API.Options) throws -> Self { return try fetchCommand().execute(options: options) } diff --git a/Sources/ParseSwift/Storage/KeychainStore.swift b/Sources/ParseSwift/Storage/KeychainStore.swift index 896c9c90e..b2572a16d 100644 --- a/Sources/ParseSwift/Storage/KeychainStore.swift +++ b/Sources/ParseSwift/Storage/KeychainStore.swift @@ -10,7 +10,7 @@ import Foundation func getKeychainQueryTemplate(forService service: String) -> [String: String] { var query = [String: String]() - if service.characters.count > 0 { + if service.count > 0 { query[kSecAttrService as String] = service } query[kSecClass as String] = kSecClassGenericPassword as String From 17adfbd7744bc8ee25a26aa3ecd513ff5913dfbc Mon Sep 17 00:00:00 2001 From: Corey's iMac Date: Thu, 9 Jul 2020 10:59:47 -0400 Subject: [PATCH 2/4] Fix test cases and commented out the Any dictionary case because it's not Encodable. The issue is referenced on other repos here: https://github.com/Moya/Moya/pull/1936 --- .../ParseSwiftTests/KeychainStoreTests.swift | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/Tests/ParseSwiftTests/KeychainStoreTests.swift b/Tests/ParseSwiftTests/KeychainStoreTests.swift index 560320ff2..7436b5fa7 100644 --- a/Tests/ParseSwiftTests/KeychainStoreTests.swift +++ b/Tests/ParseSwiftTests/KeychainStoreTests.swift @@ -31,8 +31,11 @@ class KeychainStoreTests: XCTestCase { let key = "yarrKey" let value = "yarrValue" testStore[key] = value - let storedValue: String = testStore.object(forKey: key)! - XCTAssertEqual(storedValue, value, "Values should be equal after get") + let storedValue: String? = testStore.object(forKey: key) + XCTAssertNotNil(storedValue, "Values should not be nil") + if let storedValue: String = testStore.object(forKey: key){ + XCTAssertEqual(storedValue, value, "Values should be equal after get") + } } func testGetObjectSubscript() { @@ -70,6 +73,8 @@ class KeychainStoreTests: XCTestCase { XCTAssertNil(testStore[bool: key], "Values should be equal after get") } + //Removed the test case below as it's currently not possible to make Any conform to Encodable. See issue/workarounds here: https://github.com/Moya/Moya/pull/1936 + /* func testSetComplextObject() { let complexObject: [Any] = [["key": "value"], "string2", 1234, NSNull()] testStore["complexObject"] = complexObject @@ -107,11 +112,11 @@ class KeychainStoreTests: XCTestCase { default: break } } - } + }*/ func testRemoveObject() { testStore["key1"] = "value1" - XCTAssertNotNil(testStore["key1"]!, "The value should be set") + XCTAssertNotNil(testStore[string: "key1"], "The value should be set") _ = testStore.removeObject(forKey: "key1") let key1Val: String? = testStore["key1"] XCTAssertNil(key1Val, "There should be no value after removal") @@ -119,7 +124,7 @@ class KeychainStoreTests: XCTestCase { func testRemoveObjectSubscript() { testStore["key1"] = "value1" - XCTAssertNotNil(testStore["key1"]!, "The value should be set") + XCTAssertNotNil(testStore[string: "key1"], "The value should be set") testStore[string: "key1"] = nil let key1Val: String? = testStore["key1"] XCTAssertNil(key1Val, "There should be no value after removal") @@ -128,8 +133,8 @@ class KeychainStoreTests: XCTestCase { func testRemoveAllObjects() { testStore["key1"] = "value1" testStore["key2"] = "value2" - XCTAssertNotNil(testStore["key1"]!, "The value should be set") - XCTAssertNotNil(testStore["key2"]!, "The value should be set") + XCTAssertNotNil(testStore[string: "key1"], "The value should be set") + XCTAssertNotNil(testStore[string: "key2"], "The value should be set") _ = testStore.removeAllObjects() let key1Val: String? = testStore["key1"] let key2Val: String? = testStore["key1"] From f86605d07ce7a28322d2ea70d26bfbb4bd566988 Mon Sep 17 00:00:00 2001 From: Corey's iMac Date: Thu, 9 Jul 2020 11:04:27 -0400 Subject: [PATCH 3/4] update travis to xcode11.3. Didn't go higher because they have been having weird time issues. Will test later --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 45c345e8c..946a81ce7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ -osx_image: xcode9 -language: objective-c +osx_image: xcode11.3 +language: swift stage: Build env: matrix: From 8bd1b4b1e1b473abbc8bf25df3d21d6fd18f0634 Mon Sep 17 00:00:00 2001 From: Corey's iMac Date: Thu, 9 Jul 2020 11:19:33 -0400 Subject: [PATCH 4/4] Update to Swift 5, fixed a lint issue --- .../3- Users.xcplaygroundpage/Contents.swift | 8 ++++---- ParseSwift.playground/contents.xcplayground | 2 +- ParseSwift.xcodeproj/project.pbxproj | 17 +++++++++-------- .../Objects Protocols/ObjectType.swift | 2 +- Sources/ParseSwift/Types/ACL.swift | 2 +- 5 files changed, 16 insertions(+), 15 deletions(-) diff --git a/ParseSwift.playground/Pages/3- Users.xcplaygroundpage/Contents.swift b/ParseSwift.playground/Pages/3- Users.xcplaygroundpage/Contents.swift index c7578568e..083cf9487 100644 --- a/ParseSwift.playground/Pages/3- Users.xcplaygroundpage/Contents.swift +++ b/ParseSwift.playground/Pages/3- Users.xcplaygroundpage/Contents.swift @@ -54,10 +54,10 @@ do { acl?.publicWrite = true loggedIn.ACL = acl try loggedIn.save() -} catch let e { - e - e.localizedDescription - fatalError("\(e.localizedDescription)") +} catch let error { + error + error.localizedDescription + fatalError("\(error.localizedDescription)") } //var acl = ACL() diff --git a/ParseSwift.playground/contents.xcplayground b/ParseSwift.playground/contents.xcplayground index 2efd0263e..5deb0f128 100644 --- a/ParseSwift.playground/contents.xcplayground +++ b/ParseSwift.playground/contents.xcplayground @@ -1,5 +1,5 @@ - + diff --git a/ParseSwift.xcodeproj/project.pbxproj b/ParseSwift.xcodeproj/project.pbxproj index d3e86ef69..0d3db2df2 100644 --- a/ParseSwift.xcodeproj/project.pbxproj +++ b/ParseSwift.xcodeproj/project.pbxproj @@ -440,15 +440,16 @@ TargetAttributes = { 4AA807571F794242008CD551 = { CreatedOnToolsVersion = 9.0; + LastSwiftMigration = 1130; ProvisioningStyle = Automatic; }; 4AB8B4F31F254AE10070F682 = { CreatedOnToolsVersion = 9.0; - LastSwiftMigration = 0900; + LastSwiftMigration = 1130; }; 4AB8B4FC1F254AE10070F682 = { CreatedOnToolsVersion = 9.0; - LastSwiftMigration = 0900; + LastSwiftMigration = 1130; TestTargetID = 4AA807571F794242008CD551; }; 4AFDA7111F26D9A5002AE4FC = { @@ -673,7 +674,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.parse.TestHost; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; @@ -687,7 +688,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.parse.TestHost; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; @@ -823,7 +824,7 @@ PRODUCT_NAME = ParseSwift; SKIP_INSTALL = YES; SWIFT_SWIFT3_OBJC_INFERENCE = Off; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; @@ -844,7 +845,7 @@ PRODUCT_NAME = ParseSwift; SKIP_INSTALL = YES; SWIFT_SWIFT3_OBJC_INFERENCE = Off; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; @@ -857,7 +858,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.parse.ParseSwiftTests; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/TestHost.app/TestHost"; }; @@ -871,7 +872,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.parse.ParseSwiftTests; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/TestHost.app/TestHost"; }; diff --git a/Sources/ParseSwift/Objects Protocols/ObjectType.swift b/Sources/ParseSwift/Objects Protocols/ObjectType.swift index 1b8da620c..9c6aa3401 100644 --- a/Sources/ParseSwift/Objects Protocols/ObjectType.swift +++ b/Sources/ParseSwift/Objects Protocols/ObjectType.swift @@ -137,7 +137,7 @@ func getParseEncoder() -> ParseEncoder { encoder.dateEncodingStrategy = parseDateEncodingStrategy encoder.shouldEncodeKey = { (key, path) -> Bool in if path.count == 0 // top level - && forbiddenKeys.index(of: key) != nil { + && forbiddenKeys.firstIndex(of: key) != nil { return false } return true diff --git a/Sources/ParseSwift/Types/ACL.swift b/Sources/ParseSwift/Types/ACL.swift index a7af08cc1..ecefee848 100644 --- a/Sources/ParseSwift/Types/ACL.swift +++ b/Sources/ParseSwift/Types/ACL.swift @@ -114,7 +114,7 @@ extension ACL { try container.nestedContainer(keyedBy: Access.self, forKey: scope)) }.flatMap { pair -> [(String, Access, Bool)] in let (scope, accessValues) = pair - return try accessValues.allKeys.flatMap { (access) -> (String, Access, Bool)? in + return try accessValues.allKeys.compactMap { (access) -> (String, Access, Bool)? in guard let value = try accessValues.decodeIfPresent(Bool.self, forKey: access) else { return nil }