diff --git a/CodableFirebase/Decoder.swift b/CodableFirebase/Decoder.swift index 19446bc..b1c16c2 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 FirestoreDecodable.Type) { decoded = value as! T } else { self.storage.push(container: value) diff --git a/CodableFirebase/Encoder.swift b/CodableFirebase/Encoder.swift index 5419094..bf31554 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 FirestoreEncodable) { guard let value = value as? NSObject else { throw DocumentReferenceError.typeIsNotNSObject } 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..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() {} @@ -25,7 +29,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) @@ -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 } 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) 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+)