Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Customize CKRecord.ReferenceAction #10

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ func ignoredProperties() -> [String]
```
which how its name suggests, let you ignore some properties from being encoded in the resultant `CKRecord`.

You can implement the function
```swift
func cloudKitReferenceActions() -> [String: CKRecord.Reference.Action]
```
which how its name suggests, let you set `CKRecord.Reference.Action` for any reference property. The default action is `.deleteSelf`.

### CLLocation

`CLLocation` properties has a special behavior. Since they are primitive types for `CloudKit` but they are not for `Codable` protocol, it was necessary to create a workaround to encode/decode them.
Expand Down
9 changes: 9 additions & 0 deletions Shared/Example Objects/School.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import CoreLocation
import NestedCloudKitCodable
import UIKit
import CloudKit

// swiftlint:disable implicitly_unwrapped_optional
struct School: CKCodable {
Expand Down Expand Up @@ -61,4 +62,12 @@ struct School: CKCodable {
try container.encode(director, forKey: .director)
try container.encode(books, forKey: .books)
}

func cloudKitReferenceActions() -> [String : CKRecord.Reference.Action] {
return [
"students": .deleteSelf,
"director": .deleteSelf,
"books": .none
]
}
}
2 changes: 2 additions & 0 deletions Source/Classes/CKRecordRepresentable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@ public protocol CKRecordRepresentable {
var cloudKitIdentifier: String { get }

func ignoredProperties() -> [String]
func cloudKitReferenceActions() -> [String: CKRecord.Reference.Action]
}

public extension CKRecordRepresentable {
func ignoredProperties() -> [String] { return [] }
func cloudKitReferenceActions() -> [String: CKRecord.Reference.Action] { return [:] }
}

public typealias CKEncodable = CKRecordRepresentable & Encodable
Expand Down
10 changes: 6 additions & 4 deletions Source/Classes/Encoder/CKEncoderKeyedContainer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ extension CKEncoderKeyedContainer: KeyedEncodingContainerProtocol {
// MARK: Auxiliar Encode functions

private func encodeSingleValue(_ value: CKEncodable, forKey key: Key) throws {
storage[key.stringValue] = try produceReference(for: value)
storage[key.stringValue] = try produceReference(for: value, key: key)

let encoder = CloudKitRecordEncoder(object: value, zoneID: zoneID, createdRecords: createdRecords)

Expand All @@ -87,7 +87,7 @@ extension CKEncoderKeyedContainer: KeyedEncodingContainerProtocol {
forKey key: Key) throws where T: Encodable {
var references = [CKRecord.Reference]()
try castedValues.forEach {
let reference = try produceReference(for: $0)
let reference = try produceReference(for: $0, key: key)
references.append(reference)
}
storage[key.stringValue] = references as CKRecordValue
Expand Down Expand Up @@ -198,9 +198,11 @@ extension CKEncoderKeyedContainer: KeyedEncodingContainerProtocol {
storage[key.stringValue] = locations as CKRecordValue
}

private func produceReference(for value: CKEncodable) throws -> CKRecord.Reference {
private func produceReference(for value: CKEncodable, key: Key) throws -> CKRecord.Reference {
let recordID = CKRecord.ID(recordName: value.cloudKitIdentifier, zoneID: zoneID ?? .default)
return CKRecord.Reference(recordID: recordID, action: .deleteSelf)
let actions = object.cloudKitReferenceActions()
let action = actions[key.stringValue] ?? .deleteSelf
return CKRecord.Reference(recordID: recordID, action: action)
}

func nestedUnkeyedContainer(forKey key: Key) -> UnkeyedEncodingContainer {
Expand Down