diff --git a/.github/workflows/remoteconfig.yml b/.github/workflows/remoteconfig.yml index aa2233a22f7..63cdcba0057 100644 --- a/.github/workflows/remoteconfig.yml +++ b/.github/workflows/remoteconfig.yml @@ -60,7 +60,7 @@ jobs: strategy: matrix: target: [ios, tvos, macos, watchos] - podspec: [FirebaseRemoteConfig.podspec, FirebaseRemoteConfigSwift.podspec --skip-tests] + podspec: [FirebaseRemoteConfig.podspec, FirebaseRemoteConfigSwift.podspec --allow-warnings --skip-tests] steps: - uses: actions/checkout@v3 - uses: ruby/setup-ruby@v1 diff --git a/FirebaseRemoteConfig.podspec b/FirebaseRemoteConfig.podspec index 981c1d151a7..6a1df45f881 100644 --- a/FirebaseRemoteConfig.podspec +++ b/FirebaseRemoteConfig.podspec @@ -40,6 +40,7 @@ app update. 'FirebaseABTesting/Sources/Private/*.h', 'FirebaseCore/Extension/*.h', 'FirebaseInstallations/Source/Library/Private/*.h', + 'FirebaseRemoteConfig/Swift/**/*.swift', ] s.public_header_files = base_dir + 'Public/FirebaseRemoteConfig/*.h' s.pod_target_xcconfig = { @@ -47,6 +48,7 @@ app update. 'HEADER_SEARCH_PATHS' => '"${PODS_TARGET_SRCROOT}"' } s.dependency 'FirebaseABTesting', '~> 10.0' + s.dependency 'FirebaseSharedSwift', '~> 10.0' s.dependency 'FirebaseCore', '~> 10.0' s.dependency 'FirebaseInstallations', '~> 10.0' s.dependency 'GoogleUtilities/Environment', '~> 7.8' diff --git a/FirebaseRemoteConfig/CHANGELOG.md b/FirebaseRemoteConfig/CHANGELOG.md index 06c8fbf5204..5ebd85da5b9 100644 --- a/FirebaseRemoteConfig/CHANGELOG.md +++ b/FirebaseRemoteConfig/CHANGELOG.md @@ -1,3 +1,9 @@ +# Unreleased +- [feature] The `FirebaseRemoteConfig` module now contains Firebase Remote + Config's Swift-only APIs that were previously only available via the + `FirebaseRemoteConfigSwift` extension SDK. See the + `FirebaseRemoteConfigSwift` release note from this release for more details. + # 10.12.0 - [fixed] Fix issue of real-time listeners not being properly removed. (#11458) - [fixed] Fix real-time fetches not being able to fetch the latest template due to an in-progress fetch. (#11465) diff --git a/FirebaseRemoteConfigSwift/Sources/Codable.swift b/FirebaseRemoteConfig/Swift/Codable.swift similarity index 96% rename from FirebaseRemoteConfigSwift/Sources/Codable.swift rename to FirebaseRemoteConfig/Swift/Codable.swift index 193ebf17fe2..d2df8a90db0 100644 --- a/FirebaseRemoteConfigSwift/Sources/Codable.swift +++ b/FirebaseRemoteConfig/Swift/Codable.swift @@ -15,7 +15,9 @@ */ import Foundation -import FirebaseRemoteConfig +#if SWIFT_PACKAGE + @_exported import FirebaseRemoteConfigInternal +#endif // SWIFT_PACKAGE import FirebaseSharedSwift public enum RemoteConfigValueCodableError: Error { diff --git a/FirebaseRemoteConfigSwift/Sources/FirebaseRemoteConfigValueDecoderHelper.swift b/FirebaseRemoteConfig/Swift/FirebaseRemoteConfigValueDecoderHelper.swift similarity index 94% rename from FirebaseRemoteConfigSwift/Sources/FirebaseRemoteConfigValueDecoderHelper.swift rename to FirebaseRemoteConfig/Swift/FirebaseRemoteConfigValueDecoderHelper.swift index 2a7b79a135e..d0cea378995 100644 --- a/FirebaseRemoteConfigSwift/Sources/FirebaseRemoteConfigValueDecoderHelper.swift +++ b/FirebaseRemoteConfig/Swift/FirebaseRemoteConfigValueDecoderHelper.swift @@ -15,7 +15,9 @@ */ import Foundation -import FirebaseRemoteConfig +#if SWIFT_PACKAGE + @_exported import FirebaseRemoteConfigInternal +#endif // SWIFT_PACKAGE import FirebaseSharedSwift /// Implement the FirebaseRemoteConfigValueDecoding protocol for the shared Firebase decoder to diff --git a/FirebaseRemoteConfigSwift/Sources/PropertyWrapper/RemoteConfigProperty.swift b/FirebaseRemoteConfig/Swift/PropertyWrapper/RemoteConfigProperty.swift similarity index 94% rename from FirebaseRemoteConfigSwift/Sources/PropertyWrapper/RemoteConfigProperty.swift rename to FirebaseRemoteConfig/Swift/PropertyWrapper/RemoteConfigProperty.swift index 0df0e71bac8..05d1df52303 100644 --- a/FirebaseRemoteConfigSwift/Sources/PropertyWrapper/RemoteConfigProperty.swift +++ b/FirebaseRemoteConfig/Swift/PropertyWrapper/RemoteConfigProperty.swift @@ -14,7 +14,10 @@ * limitations under the License. */ -import FirebaseRemoteConfig +#if SWIFT_PACKAGE + @_exported import FirebaseRemoteConfigInternal +#endif // SWIFT_PACKAGE + import SwiftUI /// A property wrapper that listens to a Remote Config value. diff --git a/FirebaseRemoteConfigSwift/Sources/PropertyWrapper/RemoteConfigValueObservable.swift b/FirebaseRemoteConfig/Swift/PropertyWrapper/RemoteConfigValueObservable.swift similarity index 96% rename from FirebaseRemoteConfigSwift/Sources/PropertyWrapper/RemoteConfigValueObservable.swift rename to FirebaseRemoteConfig/Swift/PropertyWrapper/RemoteConfigValueObservable.swift index b35c1685883..cd20422d9e6 100644 --- a/FirebaseRemoteConfigSwift/Sources/PropertyWrapper/RemoteConfigValueObservable.swift +++ b/FirebaseRemoteConfig/Swift/PropertyWrapper/RemoteConfigValueObservable.swift @@ -14,7 +14,9 @@ * limitations under the License. */ -import FirebaseRemoteConfig +#if SWIFT_PACKAGE + @_exported import FirebaseRemoteConfigInternal +#endif // SWIFT_PACKAGE import FirebaseCore import SwiftUI diff --git a/FirebaseRemoteConfig/Swift/SPMSwiftHeaderWorkaround.swift b/FirebaseRemoteConfig/Swift/SPMSwiftHeaderWorkaround.swift new file mode 100644 index 00000000000..b83a981606d --- /dev/null +++ b/FirebaseRemoteConfig/Swift/SPMSwiftHeaderWorkaround.swift @@ -0,0 +1,30 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#if SWIFT_PACKAGE + @_exported import FirebaseRemoteConfigInternal + + // This is a trick to force generate a `FirebaseRemoteConfig-Swift.h` header + // that re-exports `FirebaseRemoteConfigInternal` for Objective-C clients. It + // is important for the below code to reference a Remote Config symbol defined + // in Objective-C as that will import the symbol's module + // (`FirebaseRemoteConfigInternal`) in the generated header. This allows + // Objective-C clients to import Remote Config's Objective-C API using + // `@import FirebaseRemoteConfig;`. This API is not needed for Swift clients + // and is therefore unavailable in a Swift context. + @available(*, unavailable) + @objc public extension RemoteConfig { + static var __no_op: () -> Void { {} } + } +#endif // SWIFT_PACKAGE diff --git a/FirebaseRemoteConfigSwift/Sources/Value.swift b/FirebaseRemoteConfig/Swift/Value.swift similarity index 94% rename from FirebaseRemoteConfigSwift/Sources/Value.swift rename to FirebaseRemoteConfig/Swift/Value.swift index 0e81056511d..8a66eda8bc3 100644 --- a/FirebaseRemoteConfigSwift/Sources/Value.swift +++ b/FirebaseRemoteConfig/Swift/Value.swift @@ -15,7 +15,9 @@ */ import Foundation -import FirebaseRemoteConfig +#if SWIFT_PACKAGE + @_exported import FirebaseRemoteConfigInternal +#endif // SWIFT_PACKAGE /// Implements subscript overloads to enable Remote Config values to be accessed /// in a type-safe way directly from the current config. diff --git a/FirebaseRemoteConfigSwift.podspec b/FirebaseRemoteConfigSwift.podspec index b671ed16ea0..90dab0140f6 100644 --- a/FirebaseRemoteConfigSwift.podspec +++ b/FirebaseRemoteConfigSwift.podspec @@ -39,8 +39,7 @@ app update. ] s.dependency 'FirebaseCore', '~> 10.0' - s.dependency 'FirebaseRemoteConfig', '~> 10.0' - s.dependency 'FirebaseSharedSwift', '~> 10.0' + s.dependency 'FirebaseRemoteConfig', '~> 10.17' # Run Swift API tests on a real backend. s.test_spec 'swift-api-tests' do |swift_api| diff --git a/FirebaseRemoteConfigSwift/CHANGELOG.md b/FirebaseRemoteConfigSwift/CHANGELOG.md index 7317a361718..31e0c3cd5e3 100644 --- a/FirebaseRemoteConfigSwift/CHANGELOG.md +++ b/FirebaseRemoteConfigSwift/CHANGELOG.md @@ -1,3 +1,10 @@ +# Unreleased +- [deprecated] All of the public API from `FirebaseRemoteConfigSwift` can now + be accessed through the `FirebaseRemoteConfig` module. Therefore, + `FirebaseRemoteConfigSwift` has been deprecated, and will be removed in a + future release. See https://firebase.google.com/docs/ios/swift-migration for + migration instructions. + # 10.1.0 - [fixed] Fix CocoaPods release did not include the RemoteConfigProperty feature. (#10371) diff --git a/FirebaseRemoteConfigSwift/Sources/FirebaseRemoteConfigSwift.swift b/FirebaseRemoteConfigSwift/Sources/FirebaseRemoteConfigSwift.swift new file mode 100644 index 00000000000..c85b40d1532 --- /dev/null +++ b/FirebaseRemoteConfigSwift/Sources/FirebaseRemoteConfigSwift.swift @@ -0,0 +1,24 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#warning( + "All of the public API from `FirebaseRemoteConfigSwift` can now be accessed through the `FirebaseRemoteConfig` module. Therefore, the `FirebaseRemoteConfigSwift` module is deprecated and will be removed in the future. See https://firebase.google.com/docs/ios/swift-migration for migration instructions." +) + +// The `@_exported` is needed to prevent breaking clients that are using +// types prefixed with the `FirebaseRemoteConfigSwift` module name (e.g. +// `FirebaseRemoteConfigSwift.RemoteConfigValueCodableError`). +@_exported import enum FirebaseRemoteConfig.RemoteConfigValueCodableError +@_exported import enum FirebaseRemoteConfig.RemoteConfigCodableError +@_exported import struct FirebaseRemoteConfig.RemoteConfigProperty diff --git a/FirebaseRemoteConfigSwift/Tests/SwiftAPI/Codable.swift b/FirebaseRemoteConfigSwift/Tests/SwiftAPI/Codable.swift index 5ebf90dfe00..5319cd5bcea 100644 --- a/FirebaseRemoteConfigSwift/Tests/SwiftAPI/Codable.swift +++ b/FirebaseRemoteConfigSwift/Tests/SwiftAPI/Codable.swift @@ -13,7 +13,6 @@ // limitations under the License. import FirebaseRemoteConfig -import FirebaseRemoteConfigSwift import XCTest diff --git a/FirebaseRemoteConfigSwift/Tests/SwiftAPI/PropertyWrapperDefaultConfigsTests.swift b/FirebaseRemoteConfigSwift/Tests/SwiftAPI/PropertyWrapperDefaultConfigsTests.swift index b636778d6a2..5e5b304ebac 100644 --- a/FirebaseRemoteConfigSwift/Tests/SwiftAPI/PropertyWrapperDefaultConfigsTests.swift +++ b/FirebaseRemoteConfigSwift/Tests/SwiftAPI/PropertyWrapperDefaultConfigsTests.swift @@ -16,7 +16,7 @@ import FirebaseCore import FirebaseRemoteConfig -import FirebaseRemoteConfigSwift + import XCTest let ConfigKeyForThisTestOnly = "PropertyWrapperDefaultConfigsTestsKey" diff --git a/FirebaseRemoteConfigSwift/Tests/SwiftAPI/PropertyWrapperTests.swift b/FirebaseRemoteConfigSwift/Tests/SwiftAPI/PropertyWrapperTests.swift index a7c4f86cd75..f868be7f9c0 100644 --- a/FirebaseRemoteConfigSwift/Tests/SwiftAPI/PropertyWrapperTests.swift +++ b/FirebaseRemoteConfigSwift/Tests/SwiftAPI/PropertyWrapperTests.swift @@ -15,7 +15,7 @@ */ import FirebaseRemoteConfig -import FirebaseRemoteConfigSwift + import XCTest #if compiler(>=5.5.2) && canImport(_Concurrency) diff --git a/FirebaseRemoteConfigSwift/Tests/SwiftAPI/Value.swift b/FirebaseRemoteConfigSwift/Tests/SwiftAPI/Value.swift index ca483df22ca..a8afdf50fc9 100644 --- a/FirebaseRemoteConfigSwift/Tests/SwiftAPI/Value.swift +++ b/FirebaseRemoteConfigSwift/Tests/SwiftAPI/Value.swift @@ -13,7 +13,6 @@ // limitations under the License. import FirebaseRemoteConfig -import FirebaseRemoteConfigSwift import XCTest diff --git a/Package.swift b/Package.swift index 6616a465606..89033d228b6 100644 --- a/Package.swift +++ b/Package.swift @@ -880,7 +880,10 @@ let package = Package( dependencies: [ "FirebaseCore", "FirebaseInstallations", - "FirebaseRemoteConfig", + // Performance depends on the Obj-C target of FirebaseRemoteConfig to + // avoid including Swift code from the `FirebaseRemoteConfig` target + // that is unneeded. + "FirebaseRemoteConfigInternal", "FirebaseSessions", .product(name: "GoogleDataTransport", package: "GoogleDataTransport"), .product(name: "GULEnvironment", package: "GoogleUtilities"), @@ -944,7 +947,7 @@ let package = Package( // MARK: - Firebase Remote Config .target( - name: "FirebaseRemoteConfig", + name: "FirebaseRemoteConfigInternal", dependencies: [ "FirebaseCore", "FirebaseABTesting", @@ -959,7 +962,7 @@ let package = Package( ), .testTarget( name: "RemoteConfigUnit", - dependencies: ["FirebaseRemoteConfig", .product(name: "OCMock", package: "ocmock")], + dependencies: ["FirebaseRemoteConfigInternal", .product(name: "OCMock", package: "ocmock")], path: "FirebaseRemoteConfig/Tests/Unit", exclude: [ // Need to be evaluated/ported to RC V2. @@ -978,17 +981,25 @@ let package = Package( .headerSearchPath("../../.."), ] ), + .target( + name: "FirebaseRemoteConfig", + dependencies: [ + "FirebaseRemoteConfigInternal", + "FirebaseSharedSwift", + ], + path: "FirebaseRemoteConfig/Swift" + ), .target( name: "FirebaseRemoteConfigSwift", dependencies: [ "FirebaseRemoteConfig", - "FirebaseSharedSwift", ], path: "FirebaseRemoteConfigSwift/Sources" ), .testTarget( name: "RemoteConfigFakeConsole", - dependencies: ["FirebaseRemoteConfigSwift", + dependencies: ["FirebaseRemoteConfig", + "FirebaseRemoteConfigSwift", "RemoteConfigFakeConsoleObjC"], path: "FirebaseRemoteConfigSwift/Tests", exclude: [ diff --git a/ReleaseTooling/Sources/FirebaseManifest/FirebaseManifest.swift b/ReleaseTooling/Sources/FirebaseManifest/FirebaseManifest.swift index 48eeb534434..0860f9197bb 100755 --- a/ReleaseTooling/Sources/FirebaseManifest/FirebaseManifest.swift +++ b/ReleaseTooling/Sources/FirebaseManifest/FirebaseManifest.swift @@ -40,7 +40,7 @@ public let shared = Manifest( Pod("FirebaseABTesting", zip: true), Pod("FirebaseAppCheck", zip: true), Pod("FirebaseRemoteConfig"), - Pod("FirebaseRemoteConfigSwift", zip: true), + Pod("FirebaseRemoteConfigSwift", allowWarnings: true, zip: true), Pod("FirebaseAppDistribution", isBeta: true, platforms: ["ios"], zip: true), Pod("FirebaseAuth", zip: true), Pod("FirebaseCrashlytics", zip: true),