Skip to content

Commit 2246d8f

Browse files
authored
RC Swift pod and codable (#9084)
1 parent 4377c7c commit 2246d8f

36 files changed

+1039
-277
lines changed

.github/workflows/remoteconfig.yml

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,17 @@ jobs:
3232
run: scripts/setup_bundler.sh
3333
- name: Install Secret GoogleService-Info.plist
3434
run: scripts/decrypt_gha_secret.sh scripts/gha-encrypted/RemoteConfigSwiftAPI/GoogleService-Info.plist.gpg \
35-
FirebaseRemoteConfig/Tests/SwiftAPI/GoogleService-Info.plist "$plist_secret"
35+
FirebaseRemoteConfigSwift/Tests/SwiftAPI/GoogleService-Info.plist "$plist_secret"
3636
- name: Generate Access Token for RemoteConfigConsoleAPI in IntegrationTests
3737
if: matrix.target == 'iOS'
3838
run: ([ -z $plist_secret ] || scripts/generate_access_token.sh "$plist_secret" scripts/gha-encrypted/RemoteConfigSwiftAPI/ServiceAccount.json.gpg
39-
FirebaseRemoteConfig/Tests/SwiftAPI/AccessToken.json)
40-
- name: BuildAndUnitTest # can be replaced with pod lib lint with CocoaPods 1.10
41-
run: scripts/third_party/travis/retry.sh scripts/build.sh RemoteConfig ${{ matrix.target }} unit
39+
FirebaseRemoteConfigSwift/Tests/AccessToken.json)
4240
- name: Fake Console API Tests
4341
run: scripts/third_party/travis/retry.sh scripts/build.sh RemoteConfig iOS fakeconsole
4442
- name: IntegrationTest
4543
if: matrix.target == 'iOS'
46-
run: ([ -z $plist_secret ] || scripts/third_party/travis/retry.sh scripts/build.sh RemoteConfig iOS integration)
44+
# No retry to avoid exhausting AccessToken quota.
45+
run: ([ -z $plist_secret ] || scripts/build.sh RemoteConfig iOS integration)
4746

4847
pod-lib-lint:
4948
# Don't run on private repo unless it is a PR.
@@ -53,13 +52,14 @@ jobs:
5352
strategy:
5453
matrix:
5554
target: [ios, tvos, macos, watchos]
55+
podspec: [FirebaseRemoteConfig.podspec, FirebaseRemoteConfigSwift.podspec --skip-tests]
5656
steps:
5757
- uses: actions/checkout@v2
5858
- name: Setup Bundler
5959
run: scripts/setup_bundler.sh
6060
- name: Build and test
6161
run: |
62-
scripts/third_party/travis/retry.sh scripts/pod_lib_lint.rb FirebaseRemoteConfig.podspec --skip-tests --platforms=${{ matrix.target }}
62+
scripts/third_party/travis/retry.sh scripts/pod_lib_lint.rb ${{ matrix.podspec }} --platforms=${{ matrix.target }}
6363
6464
spm:
6565
# Don't run on private repo unless it is a PR.
@@ -74,6 +74,8 @@ jobs:
7474
run: scripts/setup_spm_tests.sh
7575
- name: iOS Unit Tests
7676
run: scripts/third_party/travis/retry.sh ./scripts/build.sh RemoteConfigUnit iOS spm
77+
- name: Fake Console tests
78+
run: scripts/third_party/travis/retry.sh ./scripts/build.sh RemoteConfigFakeConsole iOS spm
7779

7880
spm-cron:
7981
# Don't run on private repo.

.gitignore

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@ FirebaseAuth/Tests/Sample/SwiftApiTests/Credentials.swift
88

99
FirebaseDatabase/Tests/Resources/GoogleService-Info.plist
1010

11-
FirebaseRemoteConfig/Tests/SwiftAPI/Resources/GoogleService-Info.plist
12-
FirebaseRemoteConfig/Tests/Sample/RemoteConfigSampleApp/GoogleService-Info.plist
13-
FirebaseRemoteConfig/Tests/Sample/RemoteConfigSampleApp/SecondApp-GoogleService-Info.plist
11+
FirebaseRemoteConfig/Tests/Sample/GoogleService-Info.plist
1412

1513
# FirebaseStorage integration tests GoogleService-Info.plist
1614
FirebaseStorage/Tests/Integration/Resources/GoogleService-Info.plist

FirebaseRemoteConfig.podspec

Lines changed: 5 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ app update.
5252

5353
s.test_spec 'unit' do |unit_tests|
5454
unit_tests.scheme = { :code_coverage => true }
55+
unit_tests.platforms = {
56+
:ios => ios_deployment_target,
57+
:osx => osx_deployment_target,
58+
:tvos => tvos_deployment_target
59+
}
5560
# TODO(dmandar) - Update or delete the commented files.
5661
unit_tests.source_files =
5762
'FirebaseRemoteConfig/Tests/Unit/FIRRemoteConfigComponentTest.m',
@@ -79,40 +84,4 @@ app update.
7984
unit_tests.requires_arc = true
8085
end
8186

82-
# Run Swift API tests on a real backend.
83-
s.test_spec 'swift-api-tests' do |swift_api|
84-
swift_api.scheme = { :code_coverage => true }
85-
swift_api.platforms = {
86-
:ios => ios_deployment_target,
87-
:osx => osx_deployment_target,
88-
:tvos => tvos_deployment_target
89-
}
90-
swift_api.source_files = 'FirebaseRemoteConfig/Tests/SwiftAPI/*.swift',
91-
'FirebaseRemoteConfig/Tests/FakeUtils/*.[hm]',
92-
'FirebaseRemoteConfig/Tests/FakeUtils/*.swift'
93-
swift_api.requires_app_host = true
94-
swift_api.pod_target_xcconfig = {
95-
'SWIFT_OBJC_BRIDGING_HEADER' => '$(PODS_TARGET_SRCROOT)/FirebaseRemoteConfig/Tests/FakeUtils/Bridging-Header.h'
96-
}
97-
swift_api.dependency 'OCMock'
98-
end
99-
100-
# Run Swift API tests and tests requiring console changes on a Fake Console.
101-
s.test_spec 'fake-console-tests' do |fake_console|
102-
fake_console.scheme = { :code_coverage => true }
103-
fake_console.platforms = {
104-
:ios => ios_deployment_target,
105-
:osx => osx_deployment_target,
106-
:tvos => tvos_deployment_target
107-
}
108-
fake_console.source_files = 'FirebaseRemoteConfig/Tests/SwiftAPI/*.swift',
109-
'FirebaseRemoteConfig/Tests/FakeUtils/*.[hm]',
110-
'FirebaseRemoteConfig/Tests/FakeUtils/*.swift',
111-
'FirebaseRemoteConfig/Tests/FakeConsole/*.swift'
112-
fake_console.requires_app_host = true
113-
fake_console.pod_target_xcconfig = {
114-
'SWIFT_OBJC_BRIDGING_HEADER' => '$(PODS_TARGET_SRCROOT)/FirebaseRemoteConfig/Tests/FakeUtils/Bridging-Header.h'
115-
}
116-
fake_console.dependency 'OCMock'
117-
end
11887
end

FirebaseRemoteConfig/Tests/Sample/RemoteConfigSampleApp.xcodeproj/project.pbxproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
5BE818FB23271579004DE6BA /* RemoteConfigSampleAppUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5BE818FA23271579004DE6BA /* RemoteConfigSampleAppUITests.m */; };
1818
D5C72761A16C64F0DB522FE9 /* Pods_RemoteConfigSampleAppUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1244CD4C99B6BF70752BE1B6 /* Pods_RemoteConfigSampleAppUITests.framework */; };
1919
DE71200824C92CA800C28FE2 /* SecondApp-GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = DE71200724C92CA800C28FE2 /* SecondApp-GoogleService-Info.plist */; };
20-
DE71200A24C9C1F100C28FE2 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = DE71200924C9C1F000C28FE2 /* GoogleService-Info.plist */; };
20+
DEB1E8792785018F0054A548 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = DEB1E8782785018F0054A548 /* GoogleService-Info.plist */; };
2121
F149334D7027F03ADF9FF9FC /* Pods_RemoteConfigSampleApp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D431F3C235B420372A7847C /* Pods_RemoteConfigSampleApp.framework */; };
2222
/* End PBXBuildFile section */
2323

@@ -53,7 +53,7 @@
5353
5CC24231A56D124F27682F1C /* Pods-RemoteConfigSampleApp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RemoteConfigSampleApp.debug.xcconfig"; path = "Target Support Files/Pods-RemoteConfigSampleApp/Pods-RemoteConfigSampleApp.debug.xcconfig"; sourceTree = "<group>"; };
5454
DA0A0BDC31A76C0D70249412 /* Pods-RemoteConfigSampleApp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RemoteConfigSampleApp.release.xcconfig"; path = "Target Support Files/Pods-RemoteConfigSampleApp/Pods-RemoteConfigSampleApp.release.xcconfig"; sourceTree = "<group>"; };
5555
DE71200724C92CA800C28FE2 /* SecondApp-GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "SecondApp-GoogleService-Info.plist"; path = "../../Unit/SecondApp-GoogleService-Info.plist"; sourceTree = "<group>"; };
56-
DE71200924C9C1F000C28FE2 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "../../FakeUtils/GoogleService-Info.plist"; sourceTree = "<group>"; };
56+
DEB1E8782785018F0054A548 /* GoogleService-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = "GoogleService-Info.plist"; sourceTree = SOURCE_ROOT; };
5757
DEB267EAC843EF4BD455C9EC /* Pods-RemoteConfigSampleAppUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RemoteConfigSampleAppUITests.debug.xcconfig"; path = "Target Support Files/Pods-RemoteConfigSampleAppUITests/Pods-RemoteConfigSampleAppUITests.debug.xcconfig"; sourceTree = "<group>"; };
5858
/* End PBXFileReference section */
5959

@@ -120,7 +120,7 @@
120120
5BE818E023271577004DE6BA /* RemoteConfigSampleApp */ = {
121121
isa = PBXGroup;
122122
children = (
123-
DE71200924C9C1F000C28FE2 /* GoogleService-Info.plist */,
123+
DEB1E8782785018F0054A548 /* GoogleService-Info.plist */,
124124
DE71200724C92CA800C28FE2 /* SecondApp-GoogleService-Info.plist */,
125125
5B1A9B12232846F3001809E9 /* FRCLog.h */,
126126
5B1A9B13232846F3001809E9 /* FRCLog.m */,
@@ -231,7 +231,7 @@
231231
files = (
232232
5BE818EB23271579004DE6BA /* Assets.xcassets in Resources */,
233233
DE71200824C92CA800C28FE2 /* SecondApp-GoogleService-Info.plist in Resources */,
234-
DE71200A24C9C1F100C28FE2 /* GoogleService-Info.plist in Resources */,
234+
DEB1E8792785018F0054A548 /* GoogleService-Info.plist in Resources */,
235235
5B1A9B1723284735001809E9 /* LaunchScreen.xib in Resources */,
236236
5BE818E923271577004DE6BA /* Main.storyboard in Resources */,
237237
);

FirebaseRemoteConfig/Tests/SwiftAPI/APITestBase.swift

Lines changed: 0 additions & 63 deletions
This file was deleted.

FirebaseRemoteConfigSwift.podspec

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
Pod::Spec.new do |s|
2+
s.name = 'FirebaseRemoteConfigSwift'
3+
s.version = '8.11.0-beta'
4+
s.summary = 'Swift Extensions for Firebase Remote Config'
5+
6+
s.description = <<-DESC
7+
Firebase Remote Config is a cloud service that lets you change the
8+
appearance and behavior of your app without requiring users to download an
9+
app update.
10+
DESC
11+
12+
13+
s.homepage = 'https://developers.google.com/'
14+
s.license = { :type => 'Apache', :file => 'LICENSE' }
15+
s.authors = 'Google, Inc.'
16+
17+
s.source = {
18+
:git => 'https://github.com/Firebase/firebase-ios-sdk.git',
19+
:tag => 'CocoaPods-' + s.version.to_s
20+
}
21+
22+
s.swift_version = '5.0'
23+
24+
ios_deployment_target = '10.0'
25+
osx_deployment_target = '10.12'
26+
tvos_deployment_target = '10.0'
27+
watchos_deployment_target = '6.0'
28+
29+
s.ios.deployment_target = ios_deployment_target
30+
s.osx.deployment_target = osx_deployment_target
31+
s.tvos.deployment_target = tvos_deployment_target
32+
s.watchos.deployment_target = watchos_deployment_target
33+
34+
s.cocoapods_version = '>= 1.4.0'
35+
s.prefix_header_file = false
36+
37+
s.source_files = [
38+
'FirebaseRemoteConfigSwift/Sources/*.swift',
39+
]
40+
41+
s.dependency 'FirebaseRemoteConfig', '~> 8.11'
42+
s.dependency 'FirebaseSharedSwift', '~> 8.11-beta'
43+
44+
# Run Swift API tests on a real backend.
45+
s.test_spec 'swift-api-tests' do |swift_api|
46+
swift_api.scheme = { :code_coverage => true }
47+
swift_api.platforms = {
48+
:ios => ios_deployment_target,
49+
:osx => osx_deployment_target,
50+
:tvos => tvos_deployment_target
51+
}
52+
swift_api.source_files = ['FirebaseRemoteConfigSwift/Tests/SwiftAPI/*.swift',
53+
'FirebaseRemoteConfigSwift/Tests/FakeUtils/*.swift',
54+
'FirebaseRemoteConfigSwift/Tests/ObjC/*.[hm]',
55+
]
56+
swift_api.requires_app_host = true
57+
swift_api.pod_target_xcconfig = {
58+
'SWIFT_OBJC_BRIDGING_HEADER' => '$(PODS_TARGET_SRCROOT)/FirebaseRemoteConfigSwift/Tests/ObjC/Bridging-Header.h',
59+
'OTHER_SWIFT_FLAGS' => '$(inherited) -D USE_REAL_CONSOLE',
60+
'HEADER_SEARCH_PATHS' => '"${PODS_TARGET_SRCROOT}"'
61+
}
62+
swift_api.dependency 'OCMock'
63+
end
64+
65+
# Run Swift API tests and tests requiring console changes on a Fake Console.
66+
s.test_spec 'fake-console-tests' do |fake_console|
67+
fake_console.scheme = { :code_coverage => true }
68+
fake_console.platforms = {
69+
:ios => ios_deployment_target,
70+
:osx => osx_deployment_target,
71+
:tvos => tvos_deployment_target
72+
}
73+
fake_console.source_files = ['FirebaseRemoteConfigSwift/Tests/SwiftAPI/*.swift',
74+
'FirebaseRemoteConfigSwift/Tests/FakeUtils/*.swift',
75+
'FirebaseRemoteConfigSwift/Tests/FakeConsole/*.swift',
76+
'FirebaseRemoteConfigSwift/Tests/ObjC/*.[hm]',
77+
]
78+
fake_console.requires_app_host = true
79+
fake_console.pod_target_xcconfig = {
80+
'SWIFT_OBJC_BRIDGING_HEADER' => '$(PODS_TARGET_SRCROOT)/FirebaseRemoteConfigSwift/Tests/ObjC/Bridging-Header.h',
81+
'HEADER_SEARCH_PATHS' => '"${PODS_TARGET_SRCROOT}"'
82+
}
83+
fake_console.dependency 'OCMock'
84+
end
85+
end
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# 8.12.0-beta
2+
- Initial public beta release with Codable support. See example usage in
3+
https://github.com/firebase/firebase-ios-sdk/blob/master/FirebaseRemoteConfigSwift/Tests/Codable.swift
4+
and
5+
https://github.com/firebase/firebase-ios-sdk/blob/master/FirebaseRemoteConfigSwift/Tests/Value.swift. (#6883)
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* Copyright 2021 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import Foundation
18+
import FirebaseRemoteConfig
19+
import FirebaseSharedSwift
20+
21+
public enum RemoteConfigValueCodableError: Error {
22+
case unsupportedType(String)
23+
}
24+
25+
public extension RemoteConfigValue {
26+
/// Extracts a RemoteConfigValue JSON-encoded object and decodes it to the requested type.
27+
///
28+
/// - Parameter asType: The type to decode the JSON-object to
29+
func decoded<Value: Decodable>(asType: Value.Type = Value.self) throws -> Value {
30+
if asType == Date.self {
31+
throw RemoteConfigValueCodableError
32+
.unsupportedType("Date type is not currently supported for " +
33+
" Remote Config Value decoding. Please file a feature request")
34+
}
35+
return try FirebaseDataDecoder()
36+
.decode(Value.self, from: FirebaseRemoteConfigValueDecoderHelper(value: self))
37+
}
38+
}
39+
40+
public enum RemoteConfigCodableError: Error {
41+
case invalidSetDefaultsInput(String)
42+
}
43+
44+
public extension RemoteConfig {
45+
/// Decodes a struct from the respective Remote Config values.
46+
///
47+
/// - Parameter asType: The type to decode to.
48+
func decoded<Value: Decodable>(asType: Value.Type = Value.self) throws -> Value {
49+
let keys = allKeys(from: RemoteConfigSource.default) + allKeys(from: RemoteConfigSource.remote)
50+
let config = keys.reduce(into: [String: FirebaseRemoteConfigValueDecoderHelper]()) {
51+
$0[$1] = FirebaseRemoteConfigValueDecoderHelper(value: configValue(forKey: $1))
52+
}
53+
return try FirebaseDataDecoder().decode(Value.self, from: config)
54+
}
55+
56+
/// Sets config defaults from an encodable struct.
57+
///
58+
/// - Parameter value: The object to use to set the defaults.
59+
func setDefaults<Value: Encodable>(from value: Value) throws {
60+
guard let encoded = try FirebaseDataEncoder().encode(value) as? [String: NSObject] else {
61+
throw RemoteConfigCodableError.invalidSetDefaultsInput(
62+
"The setDefaults input: \(value), must be a Struct that encodes to a Dictionary"
63+
)
64+
}
65+
setDefaults(encoded)
66+
}
67+
}

0 commit comments

Comments
 (0)