From 747d540d773f77d152334981299e61aeef20e094 Mon Sep 17 00:00:00 2001 From: Oleksii Dykan Date: Mon, 29 Jan 2018 11:18:27 +0100 Subject: [PATCH 1/4] Rename bool option to skip firestore types --- CodableFirebase/Decoder.swift | 4 ++-- CodableFirebase/Encoder.swift | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CodableFirebase/Decoder.swift b/CodableFirebase/Decoder.swift index 19446bc..c85f17c 100644 --- a/CodableFirebase/Decoder.swift +++ b/CodableFirebase/Decoder.swift @@ -13,7 +13,7 @@ class _FirebaseDecoder : Decoder { struct _Options { let dateDecodingStrategy: FirebaseDecoder.DateDecodingStrategy? let dataDecodingStrategy: FirebaseDecoder.DataDecodingStrategy? - let skipGeoPointAndReference: Bool + let skipFirestoreTypes: Bool let userInfo: [CodingUserInfoKey : Any] } @@ -1230,7 +1230,7 @@ extension _FirebaseDecoder { } else if T.self == Decimal.self || T.self == NSDecimalNumber.self { guard let decimal = try self.unbox(value, as: Decimal.self) else { return nil } decoded = decimal as! T - } else if options.skipGeoPointAndReference && (T.self is GeoPointType.Type || T.self is DocumentReferenceType.Type) { + } else if options.skipFirestoreTypes && (T.self is GeoPointType.Type || T.self is DocumentReferenceType.Type) { decoded = value as! T } else { self.storage.push(container: value) diff --git a/CodableFirebase/Encoder.swift b/CodableFirebase/Encoder.swift index 5419094..97b82ea 100644 --- a/CodableFirebase/Encoder.swift +++ b/CodableFirebase/Encoder.swift @@ -13,7 +13,7 @@ class _FirebaseEncoder : Encoder { struct _Options { let dateEncodingStrategy: FirebaseEncoder.DateEncodingStrategy? let dataEncodingStrategy: FirebaseEncoder.DataEncodingStrategy? - let skipGeoPointAndReference: Bool + let skipFirestoreTypes: Bool let userInfo: [CodingUserInfoKey : Any] } @@ -383,7 +383,7 @@ extension _FirebaseEncoder { return try self.box((value as! Data)) } else if T.self == URL.self || T.self == NSURL.self { return self.box((value as! URL).absoluteString) - } else if options.skipGeoPointAndReference && (value is GeoPointType || value is DocumentReferenceType) { + } else if options.skipFirestoreTypes && (value is GeoPointType || value is DocumentReferenceType) { guard let value = value as? NSObject else { throw DocumentReferenceError.typeIsNotNSObject } From fcfb7b8b1ef1ec17ac6eeff5bdfa3a97120b9b02 Mon Sep 17 00:00:00 2001 From: Oleksii Dykan Date: Mon, 29 Jan 2018 11:19:33 +0100 Subject: [PATCH 2/4] Fix setting option for skipping values --- CodableFirebase/FirebaseDecoder.swift | 2 +- CodableFirebase/FirebaseEncoder.swift | 2 +- CodableFirebase/FirestoreDecoder.swift | 2 +- CodableFirebase/FirestoreEncoder.swift | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CodableFirebase/FirebaseDecoder.swift b/CodableFirebase/FirebaseDecoder.swift index 8db7fa5..a6a20f0 100644 --- a/CodableFirebase/FirebaseDecoder.swift +++ b/CodableFirebase/FirebaseDecoder.swift @@ -53,7 +53,7 @@ open class FirebaseDecoder { let options = _FirebaseDecoder._Options( dateDecodingStrategy: dateDecodingStrategy, dataDecodingStrategy: dataDecodingStrategy, - skipGeoPointAndReference: false, + skipFirestoreTypes: false, userInfo: userInfo ) let decoder = _FirebaseDecoder(referencing: container, options: options) diff --git a/CodableFirebase/FirebaseEncoder.swift b/CodableFirebase/FirebaseEncoder.swift index 526d072..49f79fc 100644 --- a/CodableFirebase/FirebaseEncoder.swift +++ b/CodableFirebase/FirebaseEncoder.swift @@ -57,7 +57,7 @@ open class FirebaseEncoder { let options = _FirebaseEncoder._Options( dateEncodingStrategy: dateEncodingStrategy, dataEncodingStrategy: dataEncodingStrategy, - skipGeoPointAndReference: false, + skipFirestoreTypes: false, userInfo: userInfo ) let encoder = _FirebaseEncoder(options: options) diff --git a/CodableFirebase/FirestoreDecoder.swift b/CodableFirebase/FirestoreDecoder.swift index b395b1a..20d557f 100644 --- a/CodableFirebase/FirestoreDecoder.swift +++ b/CodableFirebase/FirestoreDecoder.swift @@ -25,7 +25,7 @@ open class FirestoreDecoder { let options = _FirebaseDecoder._Options( dateDecodingStrategy: nil, dataDecodingStrategy: nil, - skipGeoPointAndReference: true, + skipFirestoreTypes: true, userInfo: userInfo ) let decoder = _FirebaseDecoder(referencing: container, options: options) diff --git a/CodableFirebase/FirestoreEncoder.swift b/CodableFirebase/FirestoreEncoder.swift index 76ebdec..d88e5cb 100644 --- a/CodableFirebase/FirestoreEncoder.swift +++ b/CodableFirebase/FirestoreEncoder.swift @@ -29,7 +29,7 @@ open class FirestoreEncoder { let options = _FirebaseEncoder._Options( dateEncodingStrategy: nil, dataEncodingStrategy: nil, - skipGeoPointAndReference: true, + skipFirestoreTypes: true, userInfo: userInfo ) let encoder = _FirebaseEncoder(options: options) From c4ed0ec8eb65118ee9480135399a2696991f3b2f Mon Sep 17 00:00:00 2001 From: Oleksii Dykan Date: Mon, 29 Jan 2018 11:25:25 +0100 Subject: [PATCH 3/4] Refactor to FirestoreDecodable and FirestoreEncodable protocols --- CodableFirebase/Decoder.swift | 2 +- CodableFirebase/Encoder.swift | 2 +- CodableFirebase/FirestoreDecoder.swift | 16 +++++++++++----- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/CodableFirebase/Decoder.swift b/CodableFirebase/Decoder.swift index c85f17c..b1c16c2 100644 --- a/CodableFirebase/Decoder.swift +++ b/CodableFirebase/Decoder.swift @@ -1230,7 +1230,7 @@ extension _FirebaseDecoder { } else if T.self == Decimal.self || T.self == NSDecimalNumber.self { guard let decimal = try self.unbox(value, as: Decimal.self) else { return nil } decoded = decimal as! T - } else if options.skipFirestoreTypes && (T.self is GeoPointType.Type || T.self is DocumentReferenceType.Type) { + } else if options.skipFirestoreTypes && (T.self is FirestoreDecodable.Type) { decoded = value as! T } else { self.storage.push(container: value) diff --git a/CodableFirebase/Encoder.swift b/CodableFirebase/Encoder.swift index 97b82ea..bf31554 100644 --- a/CodableFirebase/Encoder.swift +++ b/CodableFirebase/Encoder.swift @@ -383,7 +383,7 @@ extension _FirebaseEncoder { return try self.box((value as! Data)) } else if T.self == URL.self || T.self == NSURL.self { return self.box((value as! URL).absoluteString) - } else if options.skipFirestoreTypes && (value is GeoPointType || value is DocumentReferenceType) { + } else if options.skipFirestoreTypes && (value is FirestoreEncodable) { guard let value = value as? NSObject else { throw DocumentReferenceError.typeIsNotNSObject } diff --git a/CodableFirebase/FirestoreDecoder.swift b/CodableFirebase/FirestoreDecoder.swift index 20d557f..f44fcb0 100644 --- a/CodableFirebase/FirestoreDecoder.swift +++ b/CodableFirebase/FirestoreDecoder.swift @@ -8,14 +8,18 @@ import Foundation -public protocol GeoPointType: Codable { +public protocol FirestoreDecodable: Decodable {} +public protocol FirestoreEncodable: Encodable {} + +public typealias DocumentReferenceType = FirestoreDecodable & FirestoreEncodable +public typealias FieldValueType = FirestoreEncodable + +public protocol GeoPointType: FirestoreDecodable, FirestoreEncodable { var latitude: Double { get } var longitude: Double { get } init(latitude: Double, longitude: Double) } -public protocol DocumentReferenceType: Codable {} - open class FirestoreDecoder { public init() {} @@ -61,11 +65,13 @@ enum DocumentReferenceError: Error { case typeIsNotNSObject } -extension DocumentReferenceType { +extension FirestoreDecodable { public init(from decoder: Decoder) throws { throw DocumentReferenceError.typeIsNotSupported } - +} + +extension FirestoreEncodable { public func encode(to encoder: Encoder) throws { throw DocumentReferenceError.typeIsNotSupported } From 8279c70901a333f1b98d2c00ff8f743a9d1677b4 Mon Sep 17 00:00:00 2001 From: Oleksii Dykan Date: Mon, 29 Jan 2018 11:32:46 +0100 Subject: [PATCH 4/4] Update README --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 485f457..f1f5ee0 100644 --- a/README.md +++ b/README.md @@ -86,17 +86,20 @@ Firestore.firestore().collection("data").document("one").getDocument { (document } ``` -### How to use `GeoPoint` and `DocumentRefence` in Firestore +### How to use `GeoPoint`, `DocumentRefence`, `FieldValue` in Firestore In order to use these 2 types with `Firestore`, you need to add the following code somewhere in your app: ```swift extension DocumentReference: DocumentReferenceType {} extension GeoPoint: GeoPointType {} +extension FieldValue: FieldValueType {} ``` and now they become `Codable` and can be used properly with `FirestoreEncoder` and `FirestoreDecoder`. +***PLEASE NOTE*** that as `FieldValue` is only used to [`setData()` and `updateData()`](https://firebase.google.com/docs/reference/swift/firebasefirestore/api/reference/Classes/FieldValue), it only adopts the `Encodable` protocol. + ## Integration ### CocoaPods (iOS 9+)