mirror of
https://github.com/caoer/CodableFirebase.git
synced 2026-06-15 09:27:41 +08:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2afa8c101c | ||
|
|
ec22c1649e | ||
|
|
8279c70901 | ||
|
|
c4ed0ec8eb | ||
|
|
fcfb7b8b1e | ||
|
|
747d540d77 |
@@ -1,6 +1,6 @@
|
|||||||
Pod::Spec.new do |s|
|
Pod::Spec.new do |s|
|
||||||
s.name = "CodableFirebase"
|
s.name = "CodableFirebase"
|
||||||
s.version = "0.0.4"
|
s.version = "0.0.5"
|
||||||
s.summary = "Use Codable with Firebase"
|
s.summary = "Use Codable with Firebase"
|
||||||
s.description = "This library helps you use your custom models that conform to Codable protocol with Firebase Realtime Database and Firestore"
|
s.description = "This library helps you use your custom models that conform to Codable protocol with Firebase Realtime Database and Firestore"
|
||||||
s.homepage = "https://github.com/alickbass/CodableFirebase"
|
s.homepage = "https://github.com/alickbass/CodableFirebase"
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class _FirebaseDecoder : Decoder {
|
|||||||
struct _Options {
|
struct _Options {
|
||||||
let dateDecodingStrategy: FirebaseDecoder.DateDecodingStrategy?
|
let dateDecodingStrategy: FirebaseDecoder.DateDecodingStrategy?
|
||||||
let dataDecodingStrategy: FirebaseDecoder.DataDecodingStrategy?
|
let dataDecodingStrategy: FirebaseDecoder.DataDecodingStrategy?
|
||||||
let skipGeoPointAndReference: Bool
|
let skipFirestoreTypes: Bool
|
||||||
let userInfo: [CodingUserInfoKey : Any]
|
let userInfo: [CodingUserInfoKey : Any]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1230,7 +1230,7 @@ extension _FirebaseDecoder {
|
|||||||
} else if T.self == Decimal.self || T.self == NSDecimalNumber.self {
|
} else if T.self == Decimal.self || T.self == NSDecimalNumber.self {
|
||||||
guard let decimal = try self.unbox(value, as: Decimal.self) else { return nil }
|
guard let decimal = try self.unbox(value, as: Decimal.self) else { return nil }
|
||||||
decoded = decimal as! T
|
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
|
decoded = value as! T
|
||||||
} else {
|
} else {
|
||||||
self.storage.push(container: value)
|
self.storage.push(container: value)
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class _FirebaseEncoder : Encoder {
|
|||||||
struct _Options {
|
struct _Options {
|
||||||
let dateEncodingStrategy: FirebaseEncoder.DateEncodingStrategy?
|
let dateEncodingStrategy: FirebaseEncoder.DateEncodingStrategy?
|
||||||
let dataEncodingStrategy: FirebaseEncoder.DataEncodingStrategy?
|
let dataEncodingStrategy: FirebaseEncoder.DataEncodingStrategy?
|
||||||
let skipGeoPointAndReference: Bool
|
let skipFirestoreTypes: Bool
|
||||||
let userInfo: [CodingUserInfoKey : Any]
|
let userInfo: [CodingUserInfoKey : Any]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -383,7 +383,7 @@ extension _FirebaseEncoder {
|
|||||||
return try self.box((value as! Data))
|
return try self.box((value as! Data))
|
||||||
} else if T.self == URL.self || T.self == NSURL.self {
|
} else if T.self == URL.self || T.self == NSURL.self {
|
||||||
return self.box((value as! URL).absoluteString)
|
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 {
|
guard let value = value as? NSObject else {
|
||||||
throw DocumentReferenceError.typeIsNotNSObject
|
throw DocumentReferenceError.typeIsNotNSObject
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ open class FirebaseDecoder {
|
|||||||
let options = _FirebaseDecoder._Options(
|
let options = _FirebaseDecoder._Options(
|
||||||
dateDecodingStrategy: dateDecodingStrategy,
|
dateDecodingStrategy: dateDecodingStrategy,
|
||||||
dataDecodingStrategy: dataDecodingStrategy,
|
dataDecodingStrategy: dataDecodingStrategy,
|
||||||
skipGeoPointAndReference: false,
|
skipFirestoreTypes: false,
|
||||||
userInfo: userInfo
|
userInfo: userInfo
|
||||||
)
|
)
|
||||||
let decoder = _FirebaseDecoder(referencing: container, options: options)
|
let decoder = _FirebaseDecoder(referencing: container, options: options)
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ open class FirebaseEncoder {
|
|||||||
let options = _FirebaseEncoder._Options(
|
let options = _FirebaseEncoder._Options(
|
||||||
dateEncodingStrategy: dateEncodingStrategy,
|
dateEncodingStrategy: dateEncodingStrategy,
|
||||||
dataEncodingStrategy: dataEncodingStrategy,
|
dataEncodingStrategy: dataEncodingStrategy,
|
||||||
skipGeoPointAndReference: false,
|
skipFirestoreTypes: false,
|
||||||
userInfo: userInfo
|
userInfo: userInfo
|
||||||
)
|
)
|
||||||
let encoder = _FirebaseEncoder(options: options)
|
let encoder = _FirebaseEncoder(options: options)
|
||||||
|
|||||||
@@ -8,14 +8,18 @@
|
|||||||
|
|
||||||
import Foundation
|
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 latitude: Double { get }
|
||||||
var longitude: Double { get }
|
var longitude: Double { get }
|
||||||
init(latitude: Double, longitude: Double)
|
init(latitude: Double, longitude: Double)
|
||||||
}
|
}
|
||||||
|
|
||||||
public protocol DocumentReferenceType: Codable {}
|
|
||||||
|
|
||||||
open class FirestoreDecoder {
|
open class FirestoreDecoder {
|
||||||
public init() {}
|
public init() {}
|
||||||
|
|
||||||
@@ -25,7 +29,7 @@ open class FirestoreDecoder {
|
|||||||
let options = _FirebaseDecoder._Options(
|
let options = _FirebaseDecoder._Options(
|
||||||
dateDecodingStrategy: nil,
|
dateDecodingStrategy: nil,
|
||||||
dataDecodingStrategy: nil,
|
dataDecodingStrategy: nil,
|
||||||
skipGeoPointAndReference: true,
|
skipFirestoreTypes: true,
|
||||||
userInfo: userInfo
|
userInfo: userInfo
|
||||||
)
|
)
|
||||||
let decoder = _FirebaseDecoder(referencing: container, options: options)
|
let decoder = _FirebaseDecoder(referencing: container, options: options)
|
||||||
@@ -61,11 +65,13 @@ enum DocumentReferenceError: Error {
|
|||||||
case typeIsNotNSObject
|
case typeIsNotNSObject
|
||||||
}
|
}
|
||||||
|
|
||||||
extension DocumentReferenceType {
|
extension FirestoreDecodable {
|
||||||
public init(from decoder: Decoder) throws {
|
public init(from decoder: Decoder) throws {
|
||||||
throw DocumentReferenceError.typeIsNotSupported
|
throw DocumentReferenceError.typeIsNotSupported
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension FirestoreEncodable {
|
||||||
public func encode(to encoder: Encoder) throws {
|
public func encode(to encoder: Encoder) throws {
|
||||||
throw DocumentReferenceError.typeIsNotSupported
|
throw DocumentReferenceError.typeIsNotSupported
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ open class FirestoreEncoder {
|
|||||||
let options = _FirebaseEncoder._Options(
|
let options = _FirebaseEncoder._Options(
|
||||||
dateEncodingStrategy: nil,
|
dateEncodingStrategy: nil,
|
||||||
dataEncodingStrategy: nil,
|
dataEncodingStrategy: nil,
|
||||||
skipGeoPointAndReference: true,
|
skipFirestoreTypes: true,
|
||||||
userInfo: userInfo
|
userInfo: userInfo
|
||||||
)
|
)
|
||||||
let encoder = _FirebaseEncoder(options: options)
|
let encoder = _FirebaseEncoder(options: options)
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>FMWK</string>
|
<string>FMWK</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>0.0.4</string>
|
<string>0.0.5</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||||
<key>NSPrincipalClass</key>
|
<key>NSPrincipalClass</key>
|
||||||
|
|||||||
@@ -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:
|
In order to use these 2 types with `Firestore`, you need to add the following code somewhere in your app:
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
extension DocumentReference: DocumentReferenceType {}
|
extension DocumentReference: DocumentReferenceType {}
|
||||||
extension GeoPoint: GeoPointType {}
|
extension GeoPoint: GeoPointType {}
|
||||||
|
extension FieldValue: FieldValueType {}
|
||||||
```
|
```
|
||||||
|
|
||||||
and now they become `Codable` and can be used properly with `FirestoreEncoder` and `FirestoreDecoder`.
|
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
|
## Integration
|
||||||
|
|
||||||
### CocoaPods (iOS 9+)
|
### CocoaPods (iOS 9+)
|
||||||
|
|||||||
Reference in New Issue
Block a user