Skip to content

Commit 3da0721

Browse files
author
Oleksii Dykan
authored
Merge pull request #11 from alickbass/firebase-database
Firebase database
2 parents e968543 + cbf348f commit 3da0721

File tree

9 files changed

+1220
-582
lines changed

9 files changed

+1220
-582
lines changed

.travis.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
language: objective-c
2-
osx_image: xcode9
2+
osx_image: xcode9.2
33

44
env:
55
- ACTION=test PLATFORM=Mac DESTINATION='platform=OS X'
66
- ACTION=test PLATFORM=iOS DESTINATION='platform=iOS Simulator,name=iPhone 8'
77
- ACTION=build PLATFORM=watchOS DESTINATION='platform=watchOS Simulator,name=Apple Watch - 38mm'
8-
- ACTION=test PLATFORM=tvOS DESTINATION='platform=tvOS Simulator,name=Apple TV 1080p'
8+
- ACTION=test PLATFORM=tvOS DESTINATION='platform=tvOS Simulator,name=Apple TV'
99

1010
script:
1111
- xcodebuild clean $ACTION -project CodableFirebase.xcodeproj -scheme CodableFirebase -destination "$DESTINATION"

CodableFirebase.xcodeproj/project.pbxproj

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414
CE7DD3861F9DE4F7000225C5 /* TestCodableFirestore.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE7DD3851F9DE4F7000225C5 /* TestCodableFirestore.swift */; };
1515
CEFDBF821FF3B35B00745EBE /* Encoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEFDBF811FF3B35B00745EBE /* Encoder.swift */; };
1616
CEFDBF861FF3B56200745EBE /* Decoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEFDBF851FF3B56200745EBE /* Decoder.swift */; };
17+
CEFDBF8A1FF3E24200745EBE /* FirebaseDecoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEFDBF891FF3E24200745EBE /* FirebaseDecoder.swift */; };
18+
CEFDBF8C1FF3E3CB00745EBE /* FirebaseEncoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEFDBF8B1FF3E3CB00745EBE /* FirebaseEncoder.swift */; };
19+
CEFDBF8E1FF3E63700745EBE /* CodaleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEFDBF8D1FF3E63700745EBE /* CodaleTests.swift */; };
20+
CEFDBF901FF3EB2900745EBE /* TestCodableFirebase.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEFDBF8F1FF3EB2900745EBE /* TestCodableFirebase.swift */; };
1721
/* End PBXBuildFile section */
1822

1923
/* Begin PBXContainerItemProxy section */
@@ -37,6 +41,10 @@
3741
CE7DD3851F9DE4F7000225C5 /* TestCodableFirestore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestCodableFirestore.swift; sourceTree = "<group>"; };
3842
CEFDBF811FF3B35B00745EBE /* Encoder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Encoder.swift; sourceTree = "<group>"; };
3943
CEFDBF851FF3B56200745EBE /* Decoder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Decoder.swift; sourceTree = "<group>"; };
44+
CEFDBF891FF3E24200745EBE /* FirebaseDecoder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirebaseDecoder.swift; sourceTree = "<group>"; };
45+
CEFDBF8B1FF3E3CB00745EBE /* FirebaseEncoder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirebaseEncoder.swift; sourceTree = "<group>"; };
46+
CEFDBF8D1FF3E63700745EBE /* CodaleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CodaleTests.swift; sourceTree = "<group>"; };
47+
CEFDBF8F1FF3EB2900745EBE /* TestCodableFirebase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestCodableFirebase.swift; sourceTree = "<group>"; };
4048
/* End PBXFileReference section */
4149

4250
/* Begin PBXFrameworksBuildPhase section */
@@ -82,6 +90,8 @@
8290
CE7DD36A1F9CFA81000225C5 /* CodableFirebase.h */,
8391
CE7DD3821F9D04AE000225C5 /* FirestoreDecoder.swift */,
8492
CE7DD3811F9D04AE000225C5 /* FirestoreEncoder.swift */,
93+
CEFDBF891FF3E24200745EBE /* FirebaseDecoder.swift */,
94+
CEFDBF8B1FF3E3CB00745EBE /* FirebaseEncoder.swift */,
8595
CEFDBF851FF3B56200745EBE /* Decoder.swift */,
8696
CEFDBF811FF3B35B00745EBE /* Encoder.swift */,
8797
CE7DD36B1F9CFA81000225C5 /* Info.plist */,
@@ -92,7 +102,9 @@
92102
CE7DD3741F9CFA81000225C5 /* CodableFirebaseTests */ = {
93103
isa = PBXGroup;
94104
children = (
105+
CEFDBF8D1FF3E63700745EBE /* CodaleTests.swift */,
95106
CE7DD3851F9DE4F7000225C5 /* TestCodableFirestore.swift */,
107+
CEFDBF8F1FF3EB2900745EBE /* TestCodableFirebase.swift */,
96108
CE7DD3771F9CFA81000225C5 /* Info.plist */,
97109
);
98110
path = CodableFirebaseTests;
@@ -210,9 +222,11 @@
210222
buildActionMask = 2147483647;
211223
files = (
212224
CE7DD3831F9D04AE000225C5 /* FirestoreEncoder.swift in Sources */,
225+
CEFDBF8C1FF3E3CB00745EBE /* FirebaseEncoder.swift in Sources */,
213226
CEFDBF821FF3B35B00745EBE /* Encoder.swift in Sources */,
214227
CEFDBF861FF3B56200745EBE /* Decoder.swift in Sources */,
215228
CE7DD3841F9D04AE000225C5 /* FirestoreDecoder.swift in Sources */,
229+
CEFDBF8A1FF3E24200745EBE /* FirebaseDecoder.swift in Sources */,
216230
);
217231
runOnlyForDeploymentPostprocessing = 0;
218232
};
@@ -221,6 +235,8 @@
221235
buildActionMask = 2147483647;
222236
files = (
223237
CE7DD3861F9DE4F7000225C5 /* TestCodableFirestore.swift in Sources */,
238+
CEFDBF8E1FF3E63700745EBE /* CodaleTests.swift in Sources */,
239+
CEFDBF901FF3EB2900745EBE /* TestCodableFirebase.swift in Sources */,
224240
);
225241
runOnlyForDeploymentPostprocessing = 0;
226242
};

CodableFirebase/Decoder.swift

Lines changed: 2 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -9,44 +9,10 @@
99
import Foundation
1010

1111
class _FirebaseDecoder : Decoder {
12-
/// The strategy to use for decoding `Date` values.
13-
enum DateDecodingStrategy {
14-
/// Defer to `Date` for decoding. This is the default strategy.
15-
case deferredToDate
16-
17-
/// Decode the `Date` as a UNIX timestamp from a JSON number.
18-
case secondsSince1970
19-
20-
/// Decode the `Date` as UNIX millisecond timestamp from a JSON number.
21-
case millisecondsSince1970
22-
23-
/// Decode the `Date` as an ISO-8601-formatted string (in RFC 3339 format).
24-
@available(OSX 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *)
25-
case iso8601
26-
27-
/// Decode the `Date` as a string parsed by the given formatter.
28-
case formatted(DateFormatter)
29-
30-
/// Decode the `Date` as a custom value decoded by the given closure.
31-
case custom((_ decoder: Decoder) throws -> Date)
32-
}
33-
34-
/// The strategy to use for decoding `Data` values.
35-
enum DataDecodingStrategy {
36-
/// Defer to `Data` for decoding.
37-
case deferredToData
38-
39-
/// Decode the `Data` from a Base64-encoded string. This is the default strategy.
40-
case base64
41-
42-
/// Decode the `Data` as a custom value decoded by the given closure.
43-
case custom((_ decoder: Decoder) throws -> Data)
44-
}
45-
4612
/// Options set on the top-level encoder to pass down the decoding hierarchy.
4713
struct _Options {
48-
let dateDecodingStrategy: DateDecodingStrategy?
49-
let dataDecodingStrategy: DataDecodingStrategy?
14+
let dateDecodingStrategy: FirebaseDecoder.DateDecodingStrategy?
15+
let dataDecodingStrategy: FirebaseDecoder.DataDecodingStrategy?
5016
let userInfo: [CodingUserInfoKey : Any]
5117
}
5218

CodableFirebase/Encoder.swift

Lines changed: 2 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -9,49 +9,10 @@
99
import Foundation
1010

1111
class _FirebaseEncoder : Encoder {
12-
13-
/// The strategy to use for encoding `Date` values.
14-
public enum DateEncodingStrategy {
15-
/// Defer to `Date` for choosing an encoding. This is the default strategy.
16-
case deferredToDate
17-
18-
/// Encode the `Date` as a UNIX timestamp (as a JSON number).
19-
case secondsSince1970
20-
21-
/// Encode the `Date` as UNIX millisecond timestamp (as a JSON number).
22-
case millisecondsSince1970
23-
24-
/// Encode the `Date` as an ISO-8601-formatted string (in RFC 3339 format).
25-
@available(OSX 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *)
26-
case iso8601
27-
28-
/// Encode the `Date` as a string formatted by the given formatter.
29-
case formatted(DateFormatter)
30-
31-
/// Encode the `Date` as a custom value encoded by the given closure.
32-
///
33-
/// If the closure fails to encode a value into the given encoder, the encoder will encode an empty automatic container in its place.
34-
case custom((Date, Encoder) throws -> Void)
35-
}
36-
37-
/// The strategy to use for encoding `Data` values.
38-
public enum DataEncodingStrategy {
39-
/// Defer to `Data` for choosing an encoding.
40-
case deferredToData
41-
42-
/// Encoded the `Data` as a Base64-encoded string. This is the default strategy.
43-
case base64
44-
45-
/// Encode the `Data` as a custom value encoded by the given closure.
46-
///
47-
/// If the closure fails to encode a value into the given encoder, the encoder will encode an empty automatic container in its place.
48-
case custom((Data, Encoder) throws -> Void)
49-
}
50-
5112
/// Options set on the top-level encoder to pass down the encoding hierarchy.
5213
struct _Options {
53-
let dateEncodingStrategy: DateEncodingStrategy?
54-
let dataEncodingStrategy: DataEncodingStrategy?
14+
let dateEncodingStrategy: FirebaseEncoder.DateEncodingStrategy?
15+
let dataEncodingStrategy: FirebaseEncoder.DataEncodingStrategy?
5516
let userInfo: [CodingUserInfoKey : Any]
5617
}
5718

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
//
2+
// FirebaseDecoder.swift
3+
// CodableFirebase
4+
//
5+
// Created by Oleksii on 27/12/2017.
6+
// Copyright © 2017 ViolentOctopus. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
open class FirebaseDecoder {
12+
/// The strategy to use for decoding `Date` values.
13+
public enum DateDecodingStrategy {
14+
/// Defer to `Date` for decoding. This is the default strategy.
15+
case deferredToDate
16+
17+
/// Decode the `Date` as a UNIX timestamp from a JSON number.
18+
case secondsSince1970
19+
20+
/// Decode the `Date` as UNIX millisecond timestamp from a JSON number.
21+
case millisecondsSince1970
22+
23+
/// Decode the `Date` as an ISO-8601-formatted string (in RFC 3339 format).
24+
@available(OSX 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *)
25+
case iso8601
26+
27+
/// Decode the `Date` as a string parsed by the given formatter.
28+
case formatted(DateFormatter)
29+
30+
/// Decode the `Date` as a custom value decoded by the given closure.
31+
case custom((_ decoder: Decoder) throws -> Date)
32+
}
33+
34+
/// The strategy to use for decoding `Data` values.
35+
public enum DataDecodingStrategy {
36+
/// Defer to `Data` for decoding.
37+
case deferredToData
38+
39+
/// Decode the `Data` from a Base64-encoded string. This is the default strategy.
40+
case base64
41+
42+
/// Decode the `Data` as a custom value decoded by the given closure.
43+
case custom((_ decoder: Decoder) throws -> Data)
44+
}
45+
46+
public init() {}
47+
48+
open var userInfo: [CodingUserInfoKey : Any] = [:]
49+
open var dateDecodingStrategy: DateDecodingStrategy = .deferredToDate
50+
open var dataDecodingStrategy: DataDecodingStrategy = .deferredToData
51+
52+
open func decode<T : Decodable>(_ type: T.Type, from container: Any) throws -> T {
53+
let options = _FirebaseDecoder._Options(
54+
dateDecodingStrategy: dateDecodingStrategy,
55+
dataDecodingStrategy: dataDecodingStrategy,
56+
userInfo: userInfo
57+
)
58+
let decoder = _FirebaseDecoder(referencing: container, options: options)
59+
guard let value = try decoder.unbox(container, as: T.self) else {
60+
throw DecodingError.valueNotFound(T.self, DecodingError.Context(codingPath: [], debugDescription: "The given dictionary was invalid"))
61+
}
62+
63+
return value
64+
}
65+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
//
2+
// FirebaseEncoder.swift
3+
// CodableFirebase
4+
//
5+
// Created by Oleksii on 27/12/2017.
6+
// Copyright © 2017 ViolentOctopus. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
open class FirebaseEncoder {
12+
/// The strategy to use for encoding `Date` values.
13+
public enum DateEncodingStrategy {
14+
/// Defer to `Date` for choosing an encoding. This is the default strategy.
15+
case deferredToDate
16+
17+
/// Encode the `Date` as a UNIX timestamp (as a JSON number).
18+
case secondsSince1970
19+
20+
/// Encode the `Date` as UNIX millisecond timestamp (as a JSON number).
21+
case millisecondsSince1970
22+
23+
/// Encode the `Date` as an ISO-8601-formatted string (in RFC 3339 format).
24+
@available(OSX 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *)
25+
case iso8601
26+
27+
/// Encode the `Date` as a string formatted by the given formatter.
28+
case formatted(DateFormatter)
29+
30+
/// Encode the `Date` as a custom value encoded by the given closure.
31+
///
32+
/// If the closure fails to encode a value into the given encoder, the encoder will encode an empty automatic container in its place.
33+
case custom((Date, Encoder) throws -> Void)
34+
}
35+
36+
/// The strategy to use for encoding `Data` values.
37+
public enum DataEncodingStrategy {
38+
/// Defer to `Data` for choosing an encoding.
39+
case deferredToData
40+
41+
/// Encoded the `Data` as a Base64-encoded string. This is the default strategy.
42+
case base64
43+
44+
/// Encode the `Data` as a custom value encoded by the given closure.
45+
///
46+
/// If the closure fails to encode a value into the given encoder, the encoder will encode an empty automatic container in its place.
47+
case custom((Data, Encoder) throws -> Void)
48+
}
49+
50+
public init() {}
51+
52+
open var userInfo: [CodingUserInfoKey : Any] = [:]
53+
open var dateEncodingStrategy: DateEncodingStrategy = .deferredToDate
54+
open var dataEncodingStrategy: DataEncodingStrategy = .deferredToData
55+
56+
open func encode<Value : Encodable>(_ value: Value) throws -> Any {
57+
let options = _FirebaseEncoder._Options(
58+
dateEncodingStrategy: dateEncodingStrategy,
59+
dataEncodingStrategy: dataEncodingStrategy,
60+
userInfo: userInfo
61+
)
62+
let encoder = _FirebaseEncoder(options: options)
63+
guard let topLevel = try encoder.box_(value) else {
64+
throw EncodingError.invalidValue(value,
65+
EncodingError.Context(codingPath: [],
66+
debugDescription: "Top-level \(Value.self) did not encode any values."))
67+
}
68+
69+
return topLevel
70+
}
71+
}

0 commit comments

Comments
 (0)