Skip to content

Commit fe7aa8f

Browse files
committed
Merge commit 'afebc8a0883d9724a6adda263d5110eb833634d0'
* commit 'afebc8a0883d9724a6adda263d5110eb833634d0': (43 commits) Fix typo bump version Removed cream.swift reference in xcodeproj bump version number to 1.8.0 add 1.7.2 & 1.8.0 in CHANGELOG add support for the conversion of recordID to Int type primaryKey make parseFromRecord method static Custom Realm support on sync (caiyue1993#108) weak self to avoid potential retain cycle Allow SyncEngine to use custom CKContainers (besides default) use guard statement instead set default `shouldOverwrite` value to true Update CreamAsset.swift Add support for overwrite prevention; object id init Make guard statement one line Revert the changes of CreamAsset Mark save func as private and use FileManager Use break and continue correctly Update README.md Resolve `cannot use an empty list to initialize a new field` ...
2 parents 117126c + afebc8a commit fe7aa8f

File tree

13 files changed

+316
-190
lines changed

13 files changed

+316
-190
lines changed

Cartfile.resolved

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
github "realm/realm-cocoa" "v3.7.6"
1+
github "realm/realm-cocoa" "v3.11.1"

IceCream.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
Pod::Spec.new do |s|
1010
s.name = 'IceCream'
11-
s.version = '1.7.0'
11+
s.version = '1.8.1'
1212
s.summary = 'Sync Realm with CloudKit'
1313
s.description = <<-DESC
1414
Sync Realm Database with CloudKit, written in Swift. It works just like magic.

IceCream.xcodeproj/project.pbxproj

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,13 @@
1111
6743F717202B0F0F00912163 /* IceCream.h in Headers */ = {isa = PBXBuildFile; fileRef = 6743F715202B0F0F00912163 /* IceCream.h */; settings = {ATTRIBUTES = (Public, ); }; };
1212
6743F726202B0F9400912163 /* .gitkeep in Resources */ = {isa = PBXBuildFile; fileRef = 6743F71E202B0F9400912163 /* .gitkeep */; };
1313
6743F728202B0F9400912163 /* ErrorHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6743F720202B0F9400912163 /* ErrorHandler.swift */; };
14-
6743F729202B0F9400912163 /* Cream.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6743F721202B0F9400912163 /* Cream.swift */; };
1514
6743F72A202B0F9400912163 /* Manifest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6743F722202B0F9400912163 /* Manifest.swift */; };
1615
6743F72B202B0F9400912163 /* CreamAsset.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6743F723202B0F9400912163 /* CreamAsset.swift */; };
1716
6743F72D202B0F9400912163 /* Notification+Name.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6743F725202B0F9400912163 /* Notification+Name.swift */; };
1817
67478157213BEDD6005C132B /* Syncable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6773DF0220BD2CE10019FF3A /* Syncable.swift */; };
1918
67478158213BEDD6005C132B /* CKRecordConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6773DEFF20BD2CBD0019FF3A /* CKRecordConvertible.swift */; };
2019
67478159213BEDD6005C132B /* CKRecordRecoverable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6773DEFE20BD2CBD0019FF3A /* CKRecordRecoverable.swift */; };
2120
6747815A213BEDD6005C132B /* ErrorHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6743F720202B0F9400912163 /* ErrorHandler.swift */; };
22-
6747815B213BEDD6005C132B /* Cream.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6743F721202B0F9400912163 /* Cream.swift */; };
2321
6747815C213BEDD6005C132B /* Manifest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6743F722202B0F9400912163 /* Manifest.swift */; };
2422
6747815D213BEDD6005C132B /* CreamAsset.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6743F723202B0F9400912163 /* CreamAsset.swift */; };
2523
6747815E213BEDD6005C132B /* Notification+Name.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6743F725202B0F9400912163 /* Notification+Name.swift */; };
@@ -32,7 +30,6 @@
3230
67478167213BEF0E005C132B /* CKRecordConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6773DEFF20BD2CBD0019FF3A /* CKRecordConvertible.swift */; };
3331
67478168213BEF0E005C132B /* CKRecordRecoverable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6773DEFE20BD2CBD0019FF3A /* CKRecordRecoverable.swift */; };
3432
67478169213BEF0E005C132B /* ErrorHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6743F720202B0F9400912163 /* ErrorHandler.swift */; };
35-
6747816A213BEF0E005C132B /* Cream.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6743F721202B0F9400912163 /* Cream.swift */; };
3633
6747816B213BEF0E005C132B /* Manifest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6743F722202B0F9400912163 /* Manifest.swift */; };
3734
6747816C213BEF0E005C132B /* CreamAsset.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6743F723202B0F9400912163 /* CreamAsset.swift */; };
3835
6747816D213BEF0E005C132B /* Notification+Name.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6743F725202B0F9400912163 /* Notification+Name.swift */; };
@@ -52,7 +49,6 @@
5249
D826ADC9212189F2002B5C0F /* CKRecordConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6773DEFF20BD2CBD0019FF3A /* CKRecordConvertible.swift */; };
5350
D826ADCA212189F2002B5C0F /* CKRecordRecoverable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6773DEFE20BD2CBD0019FF3A /* CKRecordRecoverable.swift */; };
5451
D826ADCB212189F2002B5C0F /* ErrorHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6743F720202B0F9400912163 /* ErrorHandler.swift */; };
55-
D826ADCC212189F2002B5C0F /* Cream.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6743F721202B0F9400912163 /* Cream.swift */; };
5652
D826ADCD212189F2002B5C0F /* Manifest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6743F722202B0F9400912163 /* Manifest.swift */; };
5753
D826ADCE212189F2002B5C0F /* CreamAsset.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6743F723202B0F9400912163 /* CreamAsset.swift */; };
5854
D826ADCF212189F2002B5C0F /* Notification+Name.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6743F725202B0F9400912163 /* Notification+Name.swift */; };
@@ -69,7 +65,6 @@
6965
6743F716202B0F0F00912163 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
7066
6743F71E202B0F9400912163 /* .gitkeep */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = .gitkeep; sourceTree = "<group>"; };
7167
6743F720202B0F9400912163 /* ErrorHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ErrorHandler.swift; sourceTree = "<group>"; };
72-
6743F721202B0F9400912163 /* Cream.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Cream.swift; sourceTree = "<group>"; };
7368
6743F722202B0F9400912163 /* Manifest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Manifest.swift; sourceTree = "<group>"; };
7469
6743F723202B0F9400912163 /* CreamAsset.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CreamAsset.swift; sourceTree = "<group>"; };
7570
6743F725202B0F9400912163 /* Notification+Name.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Notification+Name.swift"; sourceTree = "<group>"; };
@@ -168,7 +163,6 @@
168163
6773DEFF20BD2CBD0019FF3A /* CKRecordConvertible.swift */,
169164
6773DEFE20BD2CBD0019FF3A /* CKRecordRecoverable.swift */,
170165
6743F720202B0F9400912163 /* ErrorHandler.swift */,
171-
6743F721202B0F9400912163 /* Cream.swift */,
172166
6743F722202B0F9400912163 /* Manifest.swift */,
173167
6743F723202B0F9400912163 /* CreamAsset.swift */,
174168
6743F725202B0F9400912163 /* Notification+Name.swift */,
@@ -395,7 +389,6 @@
395389
6773DF0320BD2CE20019FF3A /* Syncable.swift in Sources */,
396390
6773DF0020BD2CBD0019FF3A /* CKRecordRecoverable.swift in Sources */,
397391
6743F72D202B0F9400912163 /* Notification+Name.swift in Sources */,
398-
6743F729202B0F9400912163 /* Cream.swift in Sources */,
399392
6743F728202B0F9400912163 /* ErrorHandler.swift in Sources */,
400393
6767988F20BCEEB0008F98AD /* SyncObject.swift in Sources */,
401394
);
@@ -409,7 +402,6 @@
409402
67478158213BEDD6005C132B /* CKRecordConvertible.swift in Sources */,
410403
67478159213BEDD6005C132B /* CKRecordRecoverable.swift in Sources */,
411404
6747815A213BEDD6005C132B /* ErrorHandler.swift in Sources */,
412-
6747815B213BEDD6005C132B /* Cream.swift in Sources */,
413405
6747815C213BEDD6005C132B /* Manifest.swift in Sources */,
414406
6747815D213BEDD6005C132B /* CreamAsset.swift in Sources */,
415407
6747815E213BEDD6005C132B /* Notification+Name.swift in Sources */,
@@ -426,7 +418,6 @@
426418
67478167213BEF0E005C132B /* CKRecordConvertible.swift in Sources */,
427419
67478168213BEF0E005C132B /* CKRecordRecoverable.swift in Sources */,
428420
67478169213BEF0E005C132B /* ErrorHandler.swift in Sources */,
429-
6747816A213BEF0E005C132B /* Cream.swift in Sources */,
430421
6747816B213BEF0E005C132B /* Manifest.swift in Sources */,
431422
6747816C213BEF0E005C132B /* CreamAsset.swift in Sources */,
432423
6747816D213BEF0E005C132B /* Notification+Name.swift in Sources */,
@@ -439,7 +430,6 @@
439430
isa = PBXSourcesBuildPhase;
440431
buildActionMask = 2147483647;
441432
files = (
442-
D826ADCC212189F2002B5C0F /* Cream.swift in Sources */,
443433
D826ADD1212189F2002B5C0F /* SyncObject.swift in Sources */,
444434
D826ADCA212189F2002B5C0F /* CKRecordRecoverable.swift in Sources */,
445435
D826ADCD212189F2002B5C0F /* Manifest.swift in Sources */,

IceCream.xcodeproj/xcshareddata/xcschemes/IceCream-tvOS.xcscheme

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
<BuildableReference
1616
BuildableIdentifier = "primary"
1717
BlueprintIdentifier = "6747814E213BE66C005C132B"
18-
BuildableName = "IceCream_tvOS.framework"
18+
BuildableName = "IceCream.framework"
1919
BlueprintName = "IceCream-tvOS"
2020
ReferencedContainer = "container:IceCream.xcodeproj">
2121
</BuildableReference>
@@ -46,7 +46,7 @@
4646
<BuildableReference
4747
BuildableIdentifier = "primary"
4848
BlueprintIdentifier = "6747814E213BE66C005C132B"
49-
BuildableName = "IceCream_tvOS.framework"
49+
BuildableName = "IceCream.framework"
5050
BlueprintName = "IceCream-tvOS"
5151
ReferencedContainer = "container:IceCream.xcodeproj">
5252
</BuildableReference>
@@ -64,7 +64,7 @@
6464
<BuildableReference
6565
BuildableIdentifier = "primary"
6666
BlueprintIdentifier = "6747814E213BE66C005C132B"
67-
BuildableName = "IceCream_tvOS.framework"
67+
BuildableName = "IceCream.framework"
6868
BlueprintName = "IceCream-tvOS"
6969
ReferencedContainer = "container:IceCream.xcodeproj">
7070
</BuildableReference>

IceCream/Classes/CKRecordConvertible.swift

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,55 @@ extension CKRecordConvertible where Self: Object {
5454
let r = CKRecord(recordType: Self.recordType, recordID: recordID)
5555
let properties = objectSchema.properties
5656
for prop in properties {
57+
58+
let item = self[prop.name]
59+
60+
if prop.isArray {
61+
switch prop.type {
62+
case .int:
63+
guard let list = item as? List<Int>, !list.isEmpty else { break }
64+
let array = Array(list)
65+
r[prop.name] = array as CKRecordValue
66+
case .string:
67+
guard let list = item as? List<String>, !list.isEmpty else { break }
68+
let array = Array(list)
69+
r[prop.name] = array as CKRecordValue
70+
case .bool:
71+
guard let list = item as? List<Bool>, !list.isEmpty else { break }
72+
let array = Array(list)
73+
r[prop.name] = array as CKRecordValue
74+
case .float:
75+
guard let list = item as? List<Float>, !list.isEmpty else { break }
76+
let array = Array(list)
77+
r[prop.name] = array as CKRecordValue
78+
case .double:
79+
guard let list = item as? List<Double>, !list.isEmpty else { break }
80+
let array = Array(list)
81+
r[prop.name] = array as CKRecordValue
82+
case .data:
83+
guard let list = item as? List<Data>, !list.isEmpty else { break }
84+
let array = Array(list)
85+
r[prop.name] = array as CKRecordValue
86+
case .date:
87+
guard let list = item as? List<Date>, !list.isEmpty else { break }
88+
let array = Array(list)
89+
r[prop.name] = array as CKRecordValue
90+
default:
91+
break
92+
/// Other inner types of List is not supported yet
93+
}
94+
continue
95+
}
96+
5797
switch prop.type {
5898
case .int, .string, .bool, .date, .float, .double, .data:
59-
r[prop.name] = self[prop.name] as? CKRecordValue
99+
r[prop.name] = item as? CKRecordValue
60100
case .object:
61101
guard let objectName = prop.objectClassName else { break }
62102
// If object is CreamAsset, set record with its wrapped CKAsset value
63-
if objectName == CreamAsset.className(), let creamAsset = self[prop.name] as? CreamAsset {
103+
if objectName == CreamAsset.className(), let creamAsset = item as? CreamAsset {
64104
r[prop.name] = creamAsset.asset
65-
} else if let owner = self[prop.name] as? CKRecordConvertible {
105+
} else if let owner = item as? CKRecordConvertible {
66106
// Handle to-one relationship: https://realm.io/docs/swift/latest/#many-to-one
67107
// So the owner Object has to conform to CKRecordConvertible protocol
68108
r[prop.name] = CKRecord.Reference(recordID: owner.recordID, action: .none)

IceCream/Classes/CKRecordRecoverable.swift

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,50 @@ public protocol CKRecordRecoverable {
1313
}
1414

1515
extension CKRecordRecoverable where Self: Object {
16-
func parseFromRecord(record: CKRecord, realm: Realm) -> Self? {
16+
static func parseFromRecord(record: CKRecord, realm: Realm) -> Self? {
1717
let o = Self()
1818
for prop in o.objectSchema.properties {
1919
var recordValue: Any?
20+
21+
if prop.isArray {
22+
switch prop.type {
23+
case .int:
24+
guard let value = record.value(forKey: prop.name) as? [Int] else { break }
25+
let list = List<Int>()
26+
list.append(objectsIn: value)
27+
recordValue = list
28+
case .string:
29+
guard let value = record.value(forKey: prop.name) as? [String] else { break }
30+
let list = List<String>()
31+
list.append(objectsIn: value)
32+
recordValue = list
33+
case .bool:
34+
guard let value = record.value(forKey: prop.name) as? [Bool] else { break }
35+
let list = List<Bool>()
36+
list.append(objectsIn: value)
37+
recordValue = list
38+
case .float:
39+
guard let value = record.value(forKey: prop.name) as? [Float] else { break }
40+
let list = List<Float>()
41+
list.append(objectsIn: value)
42+
recordValue = list
43+
case .double:
44+
guard let value = record.value(forKey: prop.name) as? [Double] else { break }
45+
let list = List<Double>()
46+
list.append(objectsIn: value)
47+
recordValue = list
48+
case .data:
49+
guard let value = record.value(forKey: prop.name) as? [Data] else { break }
50+
let list = List<Data>()
51+
list.append(objectsIn: value)
52+
recordValue = list
53+
default:
54+
break
55+
}
56+
o.setValue(recordValue, forKey: prop.name)
57+
continue
58+
}
59+
2060
switch prop.type {
2161
case .int:
2262
recordValue = record.value(forKey: prop.name) as? Int
@@ -36,14 +76,25 @@ extension CKRecordRecoverable where Self: Object {
3676
if let asset = record.value(forKey: prop.name) as? CKAsset {
3777
recordValue = CreamAsset.parse(from: prop.name, record: record, asset: asset)
3878
} else if let owner = record.value(forKey: prop.name) as? CKRecord.Reference, let ownerType = prop.objectClassName {
39-
recordValue = realm.dynamicObject(ofType: ownerType, forPrimaryKey: owner.recordID.recordName)
79+
recordValue = realm.dynamicObject(ofType: ownerType, forPrimaryKey: primaryKeyForRecordID(recordID: owner.recordID))
4080
// Because we use the primaryKey as recordName when object converting to CKRecord
4181
}
4282
default:
4383
print("Other types will be supported in the future.")
4484
}
45-
o.setValue(recordValue, forKey: prop.name)
85+
if recordValue != nil || (recordValue == nil && prop.isOptional) {
86+
o.setValue(recordValue, forKey: prop.name)
87+
}
4688
}
4789
return o
4890
}
91+
92+
/// The primaryKey in Realm could be type of Int or String. However the `recordName` is a String type, we need to make a check.
93+
/// The reversed process happens in `recordID` property in `CKRecordConvertible` protocol.
94+
///
95+
/// - Parameter recordID: the recordID that CloudKit sent to us
96+
/// - Returns: the specific value of primaryKey in Realm
97+
static func primaryKeyForRecordID(recordID: CKRecord.ID) -> Any {
98+
return Int(recordID.recordName) ?? recordID.recordName
99+
}
49100
}

IceCream/Classes/Cream.swift

Lines changed: 0 additions & 39 deletions
This file was deleted.

0 commit comments

Comments
 (0)