Procházet zdrojové kódy

[Config] Merge RemoteConfig and its Swift extension in a non-breaking way

Nick Cooke před 2 roky
rodič
revize
ddd8ec989e

+ 2 - 0
FirebaseRemoteConfig.podspec

@@ -40,6 +40,7 @@ app update.
     'FirebaseABTesting/Sources/Private/*.h',
     'FirebaseCore/Extension/*.h',
     'FirebaseInstallations/Source/Library/Private/*.h',
+    'FirebaseRemoteConfigSwift/Sources/**/*.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'

+ 1 - 2
FirebaseRemoteConfigSwift.podspec

@@ -35,11 +35,10 @@ app update.
   s.prefix_header_file      = false
 
   s.source_files = [
-    'FirebaseRemoteConfigSwift/Sources/**/*.swift',
+    'FirebaseRemoteConfigSwift/Exporter/**/*.swift',
   ]
 
   s.dependency 'FirebaseRemoteConfig', '~> 10.0'
-  s.dependency 'FirebaseSharedSwift', '~> 10.0'
 
   # Run Swift API tests on a real backend.
   s.test_spec 'swift-api-tests' do |swift_api|

+ 20 - 0
FirebaseRemoteConfigSwift/Exporter/Exporter.swift

@@ -0,0 +1,20 @@
+// 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.
+
+// TODO(ncooke3): Add warning that importing this extension is deprecated.
+
+// The `@_exported` is needed to prevent breaking clients that are using
+// types prefixed with the `FirebaseRemoteConfigSwift` module name (e.g.
+// `FirebaseRemoteConfigSwift.RemoteConfigValueCodableError`).
+@_exported import FirebaseRemoteConfig

+ 18 - 1
FirebaseRemoteConfigSwift/Sources/Codable.swift

@@ -15,9 +15,26 @@
  */
 
 import Foundation
-import FirebaseRemoteConfig
+#if SWIFT_PACKAGE
+  @_exported import FirebaseRemoteConfigInternal
+#endif // SWIFT_PACKAGE
 import FirebaseSharedSwift
 
+#if SWIFT_PACKAGE
+  // 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 hidden for them for the foreseeable future.
+  @available(iOS 100, *)
+  @objc public extension RemoteConfig {
+    var __do_not_call: String { "" }
+  }
+#endif // SWIFT_PACKAGE
+
 public enum RemoteConfigValueCodableError: Error {
   case unsupportedType(String)
 }

+ 3 - 1
FirebaseRemoteConfigSwift/Sources/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

+ 4 - 1
FirebaseRemoteConfigSwift/Sources/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.

+ 3 - 1
FirebaseRemoteConfigSwift/Sources/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
 

+ 3 - 1
FirebaseRemoteConfigSwift/Sources/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.

+ 0 - 1
FirebaseRemoteConfigSwift/Tests/SwiftAPI/Codable.swift

@@ -13,7 +13,6 @@
 // limitations under the License.
 
 import FirebaseRemoteConfig
-import FirebaseRemoteConfigSwift
 
 import XCTest
 

+ 1 - 1
FirebaseRemoteConfigSwift/Tests/SwiftAPI/PropertyWrapperDefaultConfigsTests.swift

@@ -16,7 +16,7 @@
 
 import FirebaseCore
 import FirebaseRemoteConfig
-import FirebaseRemoteConfigSwift
+
 import XCTest
 
 let ConfigKeyForThisTestOnly = "PropertyWrapperDefaultConfigsTestsKey"

+ 1 - 1
FirebaseRemoteConfigSwift/Tests/SwiftAPI/PropertyWrapperTests.swift

@@ -15,7 +15,7 @@
  */
 
 import FirebaseRemoteConfig
-import FirebaseRemoteConfigSwift
+
 import XCTest
 
 #if compiler(>=5.5.2) && canImport(_Concurrency)

+ 0 - 1
FirebaseRemoteConfigSwift/Tests/SwiftAPI/Value.swift

@@ -13,7 +13,6 @@
 // limitations under the License.
 
 import FirebaseRemoteConfig
-import FirebaseRemoteConfigSwift
 
 import XCTest
 

+ 15 - 6
Package.swift

@@ -892,7 +892,9 @@ let package = Package(
       dependencies: [
         "FirebaseCore",
         "FirebaseInstallations",
-        "FirebaseRemoteConfig",
+        // TODO(ncooke3): Consider if this should import the merged module
+        // (`FirebaseRemoteConfig`).
+        "FirebaseRemoteConfigInternal",
         "FirebaseSessions",
         .product(name: "GoogleDataTransport", package: "GoogleDataTransport"),
         .product(name: "GULEnvironment", package: "GoogleUtilities"),
@@ -956,7 +958,7 @@ let package = Package(
     // MARK: - Firebase Remote Config
 
     .target(
-      name: "FirebaseRemoteConfig",
+      name: "FirebaseRemoteConfigInternal",
       dependencies: [
         "FirebaseCore",
         "FirebaseABTesting",
@@ -971,7 +973,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.
@@ -991,16 +993,23 @@ let package = Package(
       ]
     ),
     .target(
-      name: "FirebaseRemoteConfigSwift",
+      name: "FirebaseRemoteConfig",
       dependencies: [
-        "FirebaseRemoteConfig",
+        "FirebaseRemoteConfigInternal",
         "FirebaseSharedSwift",
       ],
       path: "FirebaseRemoteConfigSwift/Sources"
     ),
+    .target(
+      name: "FirebaseRemoteConfigSwift",
+      dependencies: [
+        "FirebaseRemoteConfig",
+      ],
+      path: "FirebaseRemoteConfigSwift/Exporter"
+    ),
     .testTarget(
       name: "RemoteConfigFakeConsole",
-      dependencies: ["FirebaseRemoteConfigSwift",
+      dependencies: ["FirebaseRemoteConfig",
                      "RemoteConfigFakeConsoleObjC"],
       path: "FirebaseRemoteConfigSwift/Tests",
       exclude: [