Skip to content

Commit

Permalink
Merge pull request #17 from alickbass/field-type-support
Browse files Browse the repository at this point in the history
Field type support
  • Loading branch information
Oleksii Dykan authored Jan 29, 2018
2 parents e6947de + 8279c70 commit ec22c16
Show file tree
Hide file tree
Showing 7 changed files with 23 additions and 14 deletions.
4 changes: 2 additions & 2 deletions CodableFirebase/Decoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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]
}

Expand Down Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions CodableFirebase/Encoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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]
}

Expand Down Expand Up @@ -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
}
Expand Down
2 changes: 1 addition & 1 deletion CodableFirebase/FirebaseDecoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion CodableFirebase/FirebaseEncoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
18 changes: 12 additions & 6 deletions CodableFirebase/FirestoreDecoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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() {}

Expand All @@ -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)
Expand Down Expand Up @@ -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
}
Expand Down
2 changes: 1 addition & 1 deletion CodableFirebase/FirestoreEncoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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+)
Expand Down

0 comments on commit ec22c16

Please sign in to comment.