From 0aed3041c4d03c07280fb6f47fabd943a337a43a Mon Sep 17 00:00:00 2001 From: Guilherme Rambo Date: Wed, 2 Dec 2020 11:16:09 -0300 Subject: [PATCH] Added basic SPM support for WWDC --- .gitignore | 3 +- CloudKitCodable.xcodeproj/project.pbxproj | 27 +++++++-------- .../xcschemes/CloudKitCodable-iOS.xcscheme | 30 ++++++++--------- .../xcschemes/CloudKitCodable.xcscheme | 24 ++++++-------- .../Source/CloudKitRecordDecoder.swift | 8 +++-- .../Source/CloudKitRecordEncoder.swift | 26 +++++++-------- .../CloudKitRecordDecoderTests.swift | 4 +-- .../CloudKitRecordEncoderTests.swift | 4 +-- CloudKitCodableTests/TestUtils.swift | 6 ++-- Package.swift | 33 +++++++++++++++++++ 10 files changed, 96 insertions(+), 69 deletions(-) create mode 100644 Package.swift diff --git a/.gitignore b/.gitignore index 6a59638..c0c2b97 100644 --- a/.gitignore +++ b/.gitignore @@ -20,4 +20,5 @@ generatechangelog.sh Pods/ Carthage Provisioning -Crashlytics.sh \ No newline at end of file +Crashlytics.sh +.build/ \ No newline at end of file diff --git a/CloudKitCodable.xcodeproj/project.pbxproj b/CloudKitCodable.xcodeproj/project.pbxproj index 38c2d0a..02bc1d0 100644 --- a/CloudKitCodable.xcodeproj/project.pbxproj +++ b/CloudKitCodable.xcodeproj/project.pbxproj @@ -290,7 +290,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0930; - LastUpgradeCheck = 0930; + LastUpgradeCheck = 1220; ORGANIZATIONNAME = "Guilherme Rambo"; TargetAttributes = { 02DF65F720D1772900A20812 = { @@ -314,6 +314,7 @@ hasScannedForEncodings = 0; knownRegions = ( en, + Base, ); mainGroup = DDCD634920A6532D00CDB5B2; productRefGroup = DDCD635420A6532D00CDB5B2 /* Products */; @@ -423,7 +424,7 @@ 02DF660920D1772900A20812 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; @@ -431,7 +432,7 @@ DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = "CloudKitCodable-iOS/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 11.3; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -441,7 +442,6 @@ PRODUCT_NAME = CloudKitCodable; SDKROOT = iphoneos; SKIP_INSTALL = YES; - SWIFT_VERSION = 4.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; @@ -449,7 +449,7 @@ 02DF660A20D1772900A20812 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_IDENTITY = ""; CODE_SIGN_STYLE = Automatic; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; @@ -457,7 +457,7 @@ DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = "CloudKitCodable-iOS/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 11.3; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -467,7 +467,6 @@ PRODUCT_NAME = CloudKitCodable; SDKROOT = iphoneos; SKIP_INSTALL = YES; - SWIFT_VERSION = 4.0; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; @@ -480,7 +479,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; INFOPLIST_FILE = "CloudKitCodable-iOSTests/Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 11.3; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -489,7 +488,6 @@ PRODUCT_BUNDLE_IDENTIFIER = "br.com.guilhermerambo.CloudKitCodable-iOSTests"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; - SWIFT_VERSION = 4.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; @@ -501,7 +499,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; INFOPLIST_FILE = "CloudKitCodable-iOSTests/Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 11.3; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -510,7 +508,6 @@ PRODUCT_BUNDLE_IDENTIFIER = "br.com.guilhermerambo.CloudKitCodable-iOSTests"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; - SWIFT_VERSION = 4.0; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; @@ -542,6 +539,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -574,6 +572,7 @@ SDKROOT = macosx; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; @@ -605,6 +604,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -630,6 +630,7 @@ SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; @@ -662,7 +663,6 @@ PROVISIONING_PROFILE_SPECIFIER = ""; SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 4.0; }; name = Debug; }; @@ -692,7 +692,6 @@ PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; PROVISIONING_PROFILE_SPECIFIER = ""; SKIP_INSTALL = YES; - SWIFT_VERSION = 4.0; }; name = Release; }; @@ -712,7 +711,6 @@ PRODUCT_BUNDLE_IDENTIFIER = br.com.guilhermerambo.CloudKitCodableTests; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_VERSION = 4.0; }; name = Debug; }; @@ -732,7 +730,6 @@ PRODUCT_BUNDLE_IDENTIFIER = br.com.guilhermerambo.CloudKitCodableTests; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_VERSION = 4.0; }; name = Release; }; diff --git a/CloudKitCodable.xcodeproj/xcshareddata/xcschemes/CloudKitCodable-iOS.xcscheme b/CloudKitCodable.xcodeproj/xcshareddata/xcschemes/CloudKitCodable-iOS.xcscheme index 1c9762a..83e1f07 100644 --- a/CloudKitCodable.xcodeproj/xcshareddata/xcschemes/CloudKitCodable-iOS.xcscheme +++ b/CloudKitCodable.xcodeproj/xcshareddata/xcschemes/CloudKitCodable-iOS.xcscheme @@ -1,6 +1,6 @@ @@ -27,6 +27,15 @@ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" shouldUseLaunchSchemeArgsEnv = "YES"> + + + + @@ -39,17 +48,6 @@ - - - - - - - - diff --git a/CloudKitCodable.xcodeproj/xcshareddata/xcschemes/CloudKitCodable.xcscheme b/CloudKitCodable.xcodeproj/xcshareddata/xcschemes/CloudKitCodable.xcscheme index 631d299..7ec186f 100644 --- a/CloudKitCodable.xcodeproj/xcshareddata/xcschemes/CloudKitCodable.xcscheme +++ b/CloudKitCodable.xcodeproj/xcshareddata/xcschemes/CloudKitCodable.xcscheme @@ -1,6 +1,6 @@ + + + + @@ -39,17 +48,6 @@ - - - - - - - - URL { if let asset = record[key.stringValue] as? CKAsset { - return decodeURL(from: asset) + guard let url = decodeURL(from: asset) else { + throw DecodingError.dataCorruptedError(forKey: key, in: self, debugDescription: "CKAsset must have a URL") + } + + return url } guard let str = record[key.stringValue] as? String else { @@ -161,7 +165,7 @@ extension _CloudKitRecordDecoder.KeyedContainer: KeyedDecodingContainerProtocol return url } - private func decodeURL(from asset: CKAsset) -> URL { + private func decodeURL(from asset: CKAsset) -> URL? { return asset.fileURL } diff --git a/CloudKitCodable/Source/CloudKitRecordEncoder.swift b/CloudKitCodable/Source/CloudKitRecordEncoder.swift index c75d74c..e98566e 100644 --- a/CloudKitCodable/Source/CloudKitRecordEncoder.swift +++ b/CloudKitCodable/Source/CloudKitRecordEncoder.swift @@ -31,7 +31,7 @@ public enum CloudKitRecordEncodingError: Error { } public class CloudKitRecordEncoder { - public var zoneID: CKRecordZoneID? + public var zoneID: CKRecordZone.ID? public func encode(_ value: Encodable) throws -> CKRecord { let type = recordTypeName(for: value) @@ -60,17 +60,17 @@ public class CloudKitRecordEncoder { } } - public init(zoneID: CKRecordZoneID? = nil) { + public init(zoneID: CKRecordZone.ID? = nil) { self.zoneID = zoneID } } final class _CloudKitRecordEncoder { - let zoneID: CKRecordZoneID? + let zoneID: CKRecordZone.ID? let recordTypeName: String let recordName: String - init(recordTypeName: String, zoneID: CKRecordZoneID?, recordName: String) { + init(recordTypeName: String, zoneID: CKRecordZone.ID?, recordName: String) { self.recordTypeName = recordTypeName self.zoneID = zoneID self.recordName = recordName @@ -91,8 +91,8 @@ extension _CloudKitRecordEncoder: Encoder { var record: CKRecord { if let existingRecord = container?.record { return existingRecord } - let zid = zoneID ?? CKRecordZoneID(zoneName: CKRecordZoneDefaultName, ownerName: CKCurrentUserDefaultName) - let rid = CKRecordID(recordName: recordName, zoneID: zid) + let zid = zoneID ?? CKRecordZone.ID(zoneName: CKRecordZone.ID.defaultZoneName, ownerName: CKCurrentUserDefaultName) + let rid = CKRecord.ID(recordName: recordName, zoneID: zid) return CKRecord(recordType: recordTypeName, recordID: rid) } @@ -130,7 +130,7 @@ protocol CloudKitRecordEncodingContainer: class { extension _CloudKitRecordEncoder { final class KeyedContainer where Key: CodingKey { let recordTypeName: String - let zoneID: CKRecordZoneID? + let zoneID: CKRecordZone.ID? let recordName: String var metaRecord: CKRecord? var codingPath: [CodingKey] @@ -139,7 +139,7 @@ extension _CloudKitRecordEncoder { fileprivate var storage: [String: CKRecordValue] = [:] init(recordTypeName: String, - zoneID: CKRecordZoneID?, + zoneID: CKRecordZone.ID?, recordName: String, codingPath: [CodingKey], userInfo: [CodingUserInfoKey : Any]) @@ -186,10 +186,10 @@ extension _CloudKitRecordEncoder.KeyedContainer: KeyedEncodingContainerProtocol } } - private func produceReference(for value: CustomCloudKitEncodable) throws -> CKReference { + private func produceReference(for value: CustomCloudKitEncodable) throws -> CKRecord.Reference { let childRecord = try CloudKitRecordEncoder().encode(value) - return CKReference(record: childRecord, action: .deleteSelf) + return CKRecord.Reference(record: childRecord, action: .deleteSelf) } private func prepareMetaRecord(with systemFields: Data) { @@ -226,9 +226,9 @@ extension _CloudKitRecordEncoder.KeyedContainer: KeyedEncodingContainerProtocol extension _CloudKitRecordEncoder.KeyedContainer: CloudKitRecordEncodingContainer { - var recordID: CKRecordID { - let zid = zoneID ?? CKRecordZoneID(zoneName: CKRecordZoneDefaultName, ownerName: CKCurrentUserDefaultName) - return CKRecordID(recordName: recordName, zoneID: zid) + var recordID: CKRecord.ID { + let zid = zoneID ?? CKRecordZone.ID(zoneName: CKRecordZone.ID.defaultZoneName, ownerName: CKCurrentUserDefaultName) + return CKRecord.ID(recordName: recordName, zoneID: zid) } var record: CKRecord? { diff --git a/CloudKitCodableTests/CloudKitRecordDecoderTests.swift b/CloudKitCodableTests/CloudKitRecordDecoderTests.swift index 1935761..a7cf856 100644 --- a/CloudKitCodableTests/CloudKitRecordDecoderTests.swift +++ b/CloudKitCodableTests/CloudKitRecordDecoderTests.swift @@ -31,7 +31,7 @@ final class CloudKitRecordDecoderTests: XCTestCase { } func testRoundTripWithCustomZoneID() throws { - let zoneID = CKRecordZoneID(zoneName: "ABCDE", ownerName: CKCurrentUserDefaultName) + let zoneID = CKRecordZone.ID(zoneName: "ABCDE", ownerName: CKCurrentUserDefaultName) let encodedPerson = try CloudKitRecordEncoder(zoneID: zoneID).encode(Person.rambo) let samePersonDecoded = try CloudKitRecordDecoder().decode(Person.self, from: encodedPerson) let samePersonReencoded = try CloudKitRecordEncoder().encode(samePersonDecoded) @@ -42,7 +42,7 @@ final class CloudKitRecordDecoderTests: XCTestCase { } func testCustomRecordIdentifierRoundTrip() throws { - let zoneID = CKRecordZoneID(zoneName: "ABCDE", ownerName: CKCurrentUserDefaultName) + let zoneID = CKRecordZone.ID(zoneName: "ABCDE", ownerName: CKCurrentUserDefaultName) let record = try CloudKitRecordEncoder(zoneID: zoneID).encode(PersonWithCustomIdentifier.rambo) diff --git a/CloudKitCodableTests/CloudKitRecordEncoderTests.swift b/CloudKitCodableTests/CloudKitRecordEncoderTests.swift index c545c7d..4be4ebe 100644 --- a/CloudKitCodableTests/CloudKitRecordEncoderTests.swift +++ b/CloudKitCodableTests/CloudKitRecordEncoderTests.swift @@ -19,7 +19,7 @@ final class CloudKitRecordEncoderTests: XCTestCase { } func testCustomZoneIDEncoding() throws { - let zoneID = CKRecordZoneID(zoneName: "ABCDE", ownerName: CKCurrentUserDefaultName) + let zoneID = CKRecordZone.ID(zoneName: "ABCDE", ownerName: CKCurrentUserDefaultName) let record = try CloudKitRecordEncoder(zoneID: zoneID).encode(Person.rambo) _validateRamboFields(in: record) @@ -42,7 +42,7 @@ final class CloudKitRecordEncoderTests: XCTestCase { } func testCustomRecordIdentifierEncoding() throws { - let zoneID = CKRecordZoneID(zoneName: "ABCDE", ownerName: CKCurrentUserDefaultName) + let zoneID = CKRecordZone.ID(zoneName: "ABCDE", ownerName: CKCurrentUserDefaultName) let record = try CloudKitRecordEncoder(zoneID: zoneID).encode(PersonWithCustomIdentifier.rambo) diff --git a/CloudKitCodableTests/TestUtils.swift b/CloudKitCodableTests/TestUtils.swift index 157506d..ef2ed9c 100644 --- a/CloudKitCodableTests/TestUtils.swift +++ b/CloudKitCodableTests/TestUtils.swift @@ -22,8 +22,8 @@ extension CKRecord { /// Creates a temporary record to simulate what would happen when encoding a CKRecord /// from a value that was previosly encoded to a CKRecord and had its system fields set static var systemFieldsDataForTesting: Data { - let zoneID = CKRecordZoneID(zoneName: "ZoneABCD", ownerName: "OwnerABCD") - let recordID = CKRecordID(recordName: "RecordABCD", zoneID: zoneID) + let zoneID = CKRecordZone.ID(zoneName: "ZoneABCD", ownerName: "OwnerABCD") + let recordID = CKRecord.ID(recordName: "RecordABCD", zoneID: zoneID) let testRecord = CKRecord(recordType: "Person", recordID: recordID) let data = NSMutableData() let coder = NSKeyedArchiver.init(forWritingWith: data) @@ -58,7 +58,7 @@ func _validateRamboFields(in record: CKRecord) { return } - XCTAssertEqual(asset.fileURL.path, "/Users/inside/Library/Containers/br.com.guilhermerambo.CloudKitRoundTrip/Data/Library/Caches/CloudKit/aa007d03cf247aebef55372fa57c05d0dc3d8682/Assets/7644AD10-A5A5-4191-B4FF-EF412CC08A52.01ec4e7f3a4fe140bcc758ae2c4a30c7bbb04de8db") + XCTAssertEqual(asset.fileURL!.path, "/Users/inside/Library/Containers/br.com.guilhermerambo.CloudKitRoundTrip/Data/Library/Caches/CloudKit/aa007d03cf247aebef55372fa57c05d0dc3d8682/Assets/7644AD10-A5A5-4191-B4FF-EF412CC08A52.01ec4e7f3a4fe140bcc758ae2c4a30c7bbb04de8db") XCTAssertNil(record[_CKSystemFieldsKeyName], "\(_CKSystemFieldsKeyName) should NOT be encoded to the record directly") } diff --git a/Package.swift b/Package.swift new file mode 100644 index 0000000..4bcaab0 --- /dev/null +++ b/Package.swift @@ -0,0 +1,33 @@ +// swift-tools-version:5.3 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "CloudKitCodable", + platforms: [ + .macOS(.v10_14), + .iOS(.v11), + .tvOS(.v11), + .watchOS(.v4), + ], + products: [ + // Products define the executables and libraries produced by a package, and make them visible to other packages. + .library( + name: "CloudKitCodable", + targets: ["CloudKitCodable"]), + .library( + name: "CloudKitCodableDynamic", + type: .dynamic, + targets: ["CloudKitCodable"]), + ], + dependencies: [ ], + targets: [ + // Targets are the basic building blocks of a package. A target can define a module or a test suite. + // Targets can depend on other targets in this package, and on products in packages which this package depends on. + .target( + name: "CloudKitCodable", + dependencies: [ ], + path: "CloudKitCodable/Source/"), + ] +)