瀏覽代碼

[auth-swift] Multi Platform Sample

Paul Beusterien 1 年之前
父節點
當前提交
651fc2d2e1

+ 29 - 0
.github/workflows/auth.yml

@@ -92,6 +92,35 @@ jobs:
         retry_wait_seconds: 120
         command: ([ -z $plist_secret ] || scripts/build.sh Auth iOS)
 
+  multiplatform-sample:
+    # Don't run on private repo unless it is a PR.
+    if: (github.repository == 'Firebase/firebase-ios-sdk' && github.event_name == 'schedule') || github.event_name == 'pull_request'
+
+    env:
+      plist_secret: ${{ secrets.GHASecretsGPGPassphrase1 }}
+    strategy:
+      matrix:
+        target: [iOS, macOS, visionOS]
+    runs-on: macos-14
+    steps:
+    - uses: actions/checkout@v4
+    - uses: mikehardy/buildcache-action@c87cea0ccd718971d6cc39e672c4f26815b6c126
+      with:
+        cache_key: integration-tests${{ matrix.os }}
+    - name: Install Secrets
+      run: |
+        scripts/decrypt_gha_secret.sh scripts/gha-encrypted/AuthSample/GoogleService-Info.plist.gpg \
+          FirebaseAuth/Tests/MultiPlatformSample/GoogleService-Info.plist "$plist_secret"
+    - name: Xcode
+      run: sudo xcode-select -s /Applications/Xcode_15.3.app/Contents/Developer
+    - uses: nick-fields/retry@v3
+      with:
+        timeout_minutes: 120
+        max_attempts: 3
+        retry_on: error
+        retry_wait_seconds: 120
+        command: ([ -z $plist_secret ] || scripts/build.sh Auth ${{ matrix.target }} multiplatform )
+
   spm:
     # Don't run on private repo unless it is a PR.
     if: (github.repository == 'Firebase/firebase-ios-sdk' && github.event_name == 'schedule') || github.event_name == 'pull_request'

+ 1 - 0
.gitignore

@@ -4,6 +4,7 @@ FirebaseAuth/Tests/SampleSwift/GoogleService-Info_multi.plist
 FirebaseAuth/Tests/SampleSwift/GoogleService-Info.plist
 FirebaseAuth/Tests/SampleSwift/Sample.entitlements
 FirebaseAuth/Tests/SampleSwift/SwiftApiTests/Credentials.swift
+FirebaseAuth/Tests/MultiPlatformSample/GoogleService-Info.plist
 
 FirebaseDatabase/Tests/Resources/GoogleService-Info.plist
 

+ 1 - 2
FirebaseAuth/Sources/Swift/SystemService/AuthNotificationManager.swift

@@ -12,11 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#if !os(macOS) && !os(watchOS)
+#if !os(macOS) && !os(watchOS) && !os(visionOS)
   import Foundation
   import UIKit
 
-  /// A class represents a credential that proves the identity of the app.
   @available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *)
   class AuthNotificationManager: NSObject {
     /// The key to locate payload data in the remote notification.

+ 448 - 0
FirebaseAuth/Tests/MultiPlatformSample/MultiPlatformSample.xcodeproj/project.pbxproj

@@ -0,0 +1,448 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 60;
+	objects = {
+
+/* Begin PBXBuildFile section */
+		DE48BA6A2BED85C100EBDE36 /* GoogleSignIn in Frameworks */ = {isa = PBXBuildFile; productRef = DE48BA692BED85C100EBDE36 /* GoogleSignIn */; };
+		DE48BA6C2BED85C100EBDE36 /* GoogleSignInSwift in Frameworks */ = {isa = PBXBuildFile; productRef = DE48BA6B2BED85C100EBDE36 /* GoogleSignInSwift */; };
+		DE48BA6E2BF2733700EBDE36 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = DE48BA6D2BF2733700EBDE36 /* GoogleService-Info.plist */; };
+		DE48BA712BF2B88D00EBDE36 /* AuthViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE48BA702BF2B88D00EBDE36 /* AuthViewModel.swift */; };
+		DE48BA752BF2BFE800EBDE36 /* SwiftUIView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE48BA742BF2BFE800EBDE36 /* SwiftUIView.swift */; };
+		DE48BA772BF2C06C00EBDE36 /* HomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE48BA762BF2C06C00EBDE36 /* HomeView.swift */; };
+		DE48BA7F2BF2DA4700EBDE36 /* GoogleSignIn in Frameworks */ = {isa = PBXBuildFile; productRef = DE48BA7E2BF2DA4700EBDE36 /* GoogleSignIn */; };
+		DE48BA812BF2DA4700EBDE36 /* GoogleSignInSwift in Frameworks */ = {isa = PBXBuildFile; productRef = DE48BA802BF2DA4700EBDE36 /* GoogleSignInSwift */; };
+		DE8B63C12BED3DF500607B82 /* MultiPlatformSampleApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE8B63C02BED3DF500607B82 /* MultiPlatformSampleApp.swift */; };
+		DE8B63C32BED3DF500607B82 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE8B63C22BED3DF500607B82 /* ContentView.swift */; };
+		DE8B63C52BED3DF600607B82 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DE8B63C42BED3DF600607B82 /* Assets.xcassets */; };
+		DE8B63C92BED3DF600607B82 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DE8B63C82BED3DF600607B82 /* Preview Assets.xcassets */; };
+		DE8B63D62BED3F1D00607B82 /* FirebaseAuth in Frameworks */ = {isa = PBXBuildFile; productRef = DE8B63D52BED3F1D00607B82 /* FirebaseAuth */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+		DE48BA6D2BF2733700EBDE36 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = SOURCE_ROOT; };
+		DE48BA6F2BF2734400EBDE36 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
+		DE48BA702BF2B88D00EBDE36 /* AuthViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthViewModel.swift; sourceTree = "<group>"; };
+		DE48BA742BF2BFE800EBDE36 /* SwiftUIView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftUIView.swift; sourceTree = "<group>"; };
+		DE48BA762BF2C06C00EBDE36 /* HomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeView.swift; sourceTree = "<group>"; };
+		DE8B63BD2BED3DF500607B82 /* MultiPlatformSample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MultiPlatformSample.app; sourceTree = BUILT_PRODUCTS_DIR; };
+		DE8B63C02BED3DF500607B82 /* MultiPlatformSampleApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiPlatformSampleApp.swift; sourceTree = "<group>"; };
+		DE8B63C22BED3DF500607B82 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
+		DE8B63C42BED3DF600607B82 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
+		DE8B63C62BED3DF600607B82 /* MultiPlatformSample.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = MultiPlatformSample.entitlements; sourceTree = "<group>"; };
+		DE8B63C82BED3DF600607B82 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+		DE8B63BA2BED3DF500607B82 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				DE48BA812BF2DA4700EBDE36 /* GoogleSignInSwift in Frameworks */,
+				DE48BA6C2BED85C100EBDE36 /* GoogleSignInSwift in Frameworks */,
+				DE48BA7F2BF2DA4700EBDE36 /* GoogleSignIn in Frameworks */,
+				DE8B63D62BED3F1D00607B82 /* FirebaseAuth in Frameworks */,
+				DE48BA6A2BED85C100EBDE36 /* GoogleSignIn in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+		DE8B63B42BED3DF500607B82 = {
+			isa = PBXGroup;
+			children = (
+				DE8B63BF2BED3DF500607B82 /* MultiPlatformSample */,
+				DE8B63BE2BED3DF500607B82 /* Products */,
+			);
+			sourceTree = "<group>";
+		};
+		DE8B63BE2BED3DF500607B82 /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				DE8B63BD2BED3DF500607B82 /* MultiPlatformSample.app */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+		DE8B63BF2BED3DF500607B82 /* MultiPlatformSample */ = {
+			isa = PBXGroup;
+			children = (
+				DE48BA6F2BF2734400EBDE36 /* Info.plist */,
+				DE48BA6D2BF2733700EBDE36 /* GoogleService-Info.plist */,
+				DE8B63C02BED3DF500607B82 /* MultiPlatformSampleApp.swift */,
+				DE8B63C22BED3DF500607B82 /* ContentView.swift */,
+				DE8B63C42BED3DF600607B82 /* Assets.xcassets */,
+				DE8B63C62BED3DF600607B82 /* MultiPlatformSample.entitlements */,
+				DE8B63C72BED3DF600607B82 /* Preview Content */,
+				DE48BA702BF2B88D00EBDE36 /* AuthViewModel.swift */,
+				DE48BA742BF2BFE800EBDE36 /* SwiftUIView.swift */,
+				DE48BA762BF2C06C00EBDE36 /* HomeView.swift */,
+			);
+			path = MultiPlatformSample;
+			sourceTree = "<group>";
+		};
+		DE8B63C72BED3DF600607B82 /* Preview Content */ = {
+			isa = PBXGroup;
+			children = (
+				DE8B63C82BED3DF600607B82 /* Preview Assets.xcassets */,
+			);
+			path = "Preview Content";
+			sourceTree = "<group>";
+		};
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+		DE8B63BC2BED3DF500607B82 /* MultiPlatformSample */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = DE8B63CC2BED3DF600607B82 /* Build configuration list for PBXNativeTarget "MultiPlatformSample" */;
+			buildPhases = (
+				DE8B63B92BED3DF500607B82 /* Sources */,
+				DE8B63BA2BED3DF500607B82 /* Frameworks */,
+				DE8B63BB2BED3DF500607B82 /* Resources */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = MultiPlatformSample;
+			packageProductDependencies = (
+				DE8B63D52BED3F1D00607B82 /* FirebaseAuth */,
+				DE48BA692BED85C100EBDE36 /* GoogleSignIn */,
+				DE48BA6B2BED85C100EBDE36 /* GoogleSignInSwift */,
+				DE48BA7E2BF2DA4700EBDE36 /* GoogleSignIn */,
+				DE48BA802BF2DA4700EBDE36 /* GoogleSignInSwift */,
+			);
+			productName = MultiPlatformSample;
+			productReference = DE8B63BD2BED3DF500607B82 /* MultiPlatformSample.app */;
+			productType = "com.apple.product-type.application";
+		};
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+		DE8B63B52BED3DF500607B82 /* Project object */ = {
+			isa = PBXProject;
+			attributes = {
+				BuildIndependentTargetsInParallel = 1;
+				LastSwiftUpdateCheck = 1540;
+				LastUpgradeCheck = 1540;
+				TargetAttributes = {
+					DE8B63BC2BED3DF500607B82 = {
+						CreatedOnToolsVersion = 15.4;
+					};
+				};
+			};
+			buildConfigurationList = DE8B63B82BED3DF500607B82 /* Build configuration list for PBXProject "MultiPlatformSample" */;
+			compatibilityVersion = "Xcode 14.0";
+			developmentRegion = en;
+			hasScannedForEncodings = 0;
+			knownRegions = (
+				en,
+				Base,
+			);
+			mainGroup = DE8B63B42BED3DF500607B82;
+			packageReferences = (
+				DE8B63D42BED3F1D00607B82 /* XCLocalSwiftPackageReference "../../.." */,
+				DE48BA7D2BF2DA4700EBDE36 /* XCRemoteSwiftPackageReference "GoogleSignIn-iOS" */,
+			);
+			productRefGroup = DE8B63BE2BED3DF500607B82 /* Products */;
+			projectDirPath = "";
+			projectRoot = "";
+			targets = (
+				DE8B63BC2BED3DF500607B82 /* MultiPlatformSample */,
+			);
+		};
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+		DE8B63BB2BED3DF500607B82 /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				DE8B63C92BED3DF600607B82 /* Preview Assets.xcassets in Resources */,
+				DE8B63C52BED3DF600607B82 /* Assets.xcassets in Resources */,
+				DE48BA6E2BF2733700EBDE36 /* GoogleService-Info.plist in Resources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+		DE8B63B92BED3DF500607B82 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				DE8B63C32BED3DF500607B82 /* ContentView.swift in Sources */,
+				DE8B63C12BED3DF500607B82 /* MultiPlatformSampleApp.swift in Sources */,
+				DE48BA772BF2C06C00EBDE36 /* HomeView.swift in Sources */,
+				DE48BA712BF2B88D00EBDE36 /* AuthViewModel.swift in Sources */,
+				DE48BA752BF2BFE800EBDE36 /* SwiftUIView.swift in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+		DE8B63CA2BED3DF600607B82 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
+				CLANG_ANALYZER_NONNULL = YES;
+				CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_ENABLE_OBJC_WEAK = YES;
+				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_COMMA = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INFINITE_RECURSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+				CLANG_WARN_STRICT_PROTOTYPES = YES;
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
+				CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				COPY_PHASE_STRIP = NO;
+				DEBUG_INFORMATION_FORMAT = dwarf;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				ENABLE_TESTABILITY = YES;
+				ENABLE_USER_SCRIPT_SANDBOXING = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu17;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"DEBUG=1",
+					"$(inherited)",
+				);
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
+				MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+				MTL_FAST_MATH = YES;
+				ONLY_ACTIVE_ARCH = YES;
+				SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
+				SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+			};
+			name = Debug;
+		};
+		DE8B63CB2BED3DF600607B82 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
+				CLANG_ANALYZER_NONNULL = YES;
+				CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_ENABLE_OBJC_WEAK = YES;
+				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_COMMA = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INFINITE_RECURSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+				CLANG_WARN_STRICT_PROTOTYPES = YES;
+				CLANG_WARN_SUSPICIOUS_MOVE = YES;
+				CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				COPY_PHASE_STRIP = NO;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				ENABLE_NS_ASSERTIONS = NO;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				ENABLE_USER_SCRIPT_SANDBOXING = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu17;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
+				MTL_ENABLE_DEBUG_INFO = NO;
+				MTL_FAST_MATH = YES;
+				SWIFT_COMPILATION_MODE = wholemodule;
+			};
+			name = Release;
+		};
+		DE8B63CD2BED3DF600607B82 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+				ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+				CODE_SIGN_ENTITLEMENTS = MultiPlatformSample/MultiPlatformSample.entitlements;
+				CODE_SIGN_STYLE = Automatic;
+				CURRENT_PROJECT_VERSION = 1;
+				DEVELOPMENT_ASSET_PATHS = "\"MultiPlatformSample/Preview Content\"";
+				DEVELOPMENT_TEAM = "";
+				ENABLE_PREVIEWS = YES;
+				GENERATE_INFOPLIST_FILE = YES;
+				INFOPLIST_FILE = MultiPlatformSample/Info.plist;
+				"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
+				"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES;
+				"INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES;
+				"INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphonesimulator*]" = YES;
+				"INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphoneos*]" = YES;
+				"INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphonesimulator*]" = YES;
+				"INFOPLIST_KEY_UIStatusBarStyle[sdk=iphoneos*]" = UIStatusBarStyleDefault;
+				"INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault;
+				INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
+				INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
+				IPHONEOS_DEPLOYMENT_TARGET = 17.5;
+				LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
+				"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
+				MACOSX_DEPLOYMENT_TARGET = 14.4;
+				MARKETING_VERSION = 1.0;
+				PRODUCT_BUNDLE_IDENTIFIER = com.google.FirebaseExperimental1;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SDKROOT = auto;
+				SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx xros xrsimulator";
+				SUPPORTS_MACCATALYST = NO;
+				SWIFT_EMIT_LOC_STRINGS = YES;
+				SWIFT_VERSION = 5.0;
+				TARGETED_DEVICE_FAMILY = "1,2,7";
+			};
+			name = Debug;
+		};
+		DE8B63CE2BED3DF600607B82 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+				ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+				CODE_SIGN_ENTITLEMENTS = MultiPlatformSample/MultiPlatformSample.entitlements;
+				CODE_SIGN_STYLE = Automatic;
+				CURRENT_PROJECT_VERSION = 1;
+				DEVELOPMENT_ASSET_PATHS = "\"MultiPlatformSample/Preview Content\"";
+				DEVELOPMENT_TEAM = "";
+				ENABLE_PREVIEWS = YES;
+				GENERATE_INFOPLIST_FILE = YES;
+				INFOPLIST_FILE = MultiPlatformSample/Info.plist;
+				"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
+				"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES;
+				"INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES;
+				"INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphonesimulator*]" = YES;
+				"INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphoneos*]" = YES;
+				"INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphonesimulator*]" = YES;
+				"INFOPLIST_KEY_UIStatusBarStyle[sdk=iphoneos*]" = UIStatusBarStyleDefault;
+				"INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault;
+				INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
+				INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
+				IPHONEOS_DEPLOYMENT_TARGET = 17.5;
+				LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
+				"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
+				MACOSX_DEPLOYMENT_TARGET = 14.4;
+				MARKETING_VERSION = 1.0;
+				PRODUCT_BUNDLE_IDENTIFIER = com.google.FirebaseExperimental1;
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SDKROOT = auto;
+				SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx xros xrsimulator";
+				SUPPORTS_MACCATALYST = NO;
+				SWIFT_EMIT_LOC_STRINGS = YES;
+				SWIFT_VERSION = 5.0;
+				TARGETED_DEVICE_FAMILY = "1,2,7";
+			};
+			name = Release;
+		};
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+		DE8B63B82BED3DF500607B82 /* Build configuration list for PBXProject "MultiPlatformSample" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				DE8B63CA2BED3DF600607B82 /* Debug */,
+				DE8B63CB2BED3DF600607B82 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		DE8B63CC2BED3DF600607B82 /* Build configuration list for PBXNativeTarget "MultiPlatformSample" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				DE8B63CD2BED3DF600607B82 /* Debug */,
+				DE8B63CE2BED3DF600607B82 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+/* End XCConfigurationList section */
+
+/* Begin XCLocalSwiftPackageReference section */
+		DE8B63D42BED3F1D00607B82 /* XCLocalSwiftPackageReference "../../.." */ = {
+			isa = XCLocalSwiftPackageReference;
+			relativePath = ../../..;
+		};
+/* End XCLocalSwiftPackageReference section */
+
+/* Begin XCRemoteSwiftPackageReference section */
+		DE48BA7D2BF2DA4700EBDE36 /* XCRemoteSwiftPackageReference "GoogleSignIn-iOS" */ = {
+			isa = XCRemoteSwiftPackageReference;
+			repositoryURL = "https://github.com/paulb777/GoogleSignIn-iOS.git";
+			requirement = {
+				branch = visionOS;
+				kind = branch;
+			};
+		};
+/* End XCRemoteSwiftPackageReference section */
+
+/* Begin XCSwiftPackageProductDependency section */
+		DE48BA692BED85C100EBDE36 /* GoogleSignIn */ = {
+			isa = XCSwiftPackageProductDependency;
+			productName = GoogleSignIn;
+		};
+		DE48BA6B2BED85C100EBDE36 /* GoogleSignInSwift */ = {
+			isa = XCSwiftPackageProductDependency;
+			productName = GoogleSignInSwift;
+		};
+		DE48BA7E2BF2DA4700EBDE36 /* GoogleSignIn */ = {
+			isa = XCSwiftPackageProductDependency;
+			package = DE48BA7D2BF2DA4700EBDE36 /* XCRemoteSwiftPackageReference "GoogleSignIn-iOS" */;
+			productName = GoogleSignIn;
+		};
+		DE48BA802BF2DA4700EBDE36 /* GoogleSignInSwift */ = {
+			isa = XCSwiftPackageProductDependency;
+			package = DE48BA7D2BF2DA4700EBDE36 /* XCRemoteSwiftPackageReference "GoogleSignIn-iOS" */;
+			productName = GoogleSignInSwift;
+		};
+		DE8B63D52BED3F1D00607B82 /* FirebaseAuth */ = {
+			isa = XCSwiftPackageProductDependency;
+			productName = FirebaseAuth;
+		};
+/* End XCSwiftPackageProductDependency section */
+	};
+	rootObject = DE8B63B52BED3DF500607B82 /* Project object */;
+}

+ 11 - 0
FirebaseAuth/Tests/MultiPlatformSample/MultiPlatformSample/Assets.xcassets/AccentColor.colorset/Contents.json

@@ -0,0 +1,11 @@
+{
+  "colors" : [
+    {
+      "idiom" : "universal"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

+ 63 - 0
FirebaseAuth/Tests/MultiPlatformSample/MultiPlatformSample/Assets.xcassets/AppIcon.appiconset/Contents.json

@@ -0,0 +1,63 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "platform" : "ios",
+      "size" : "1024x1024"
+    },
+    {
+      "idiom" : "mac",
+      "scale" : "1x",
+      "size" : "16x16"
+    },
+    {
+      "idiom" : "mac",
+      "scale" : "2x",
+      "size" : "16x16"
+    },
+    {
+      "idiom" : "mac",
+      "scale" : "1x",
+      "size" : "32x32"
+    },
+    {
+      "idiom" : "mac",
+      "scale" : "2x",
+      "size" : "32x32"
+    },
+    {
+      "idiom" : "mac",
+      "scale" : "1x",
+      "size" : "128x128"
+    },
+    {
+      "idiom" : "mac",
+      "scale" : "2x",
+      "size" : "128x128"
+    },
+    {
+      "idiom" : "mac",
+      "scale" : "1x",
+      "size" : "256x256"
+    },
+    {
+      "idiom" : "mac",
+      "scale" : "2x",
+      "size" : "256x256"
+    },
+    {
+      "idiom" : "mac",
+      "scale" : "1x",
+      "size" : "512x512"
+    },
+    {
+      "idiom" : "mac",
+      "scale" : "2x",
+      "size" : "512x512"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

+ 6 - 0
FirebaseAuth/Tests/MultiPlatformSample/MultiPlatformSample/Assets.xcassets/Contents.json

@@ -0,0 +1,6 @@
+{
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

+ 86 - 0
FirebaseAuth/Tests/MultiPlatformSample/MultiPlatformSample/AuthViewModel.swift

@@ -0,0 +1,86 @@
+// Copyright 2024 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.
+
+import FirebaseAuth
+import FirebaseCore
+import GoogleSignIn
+
+class AuthViewModel: ObservableObject {
+  enum SignInState {
+    case signedIn
+    case signedOut
+  }
+
+  @Published var state: SignInState = .signedOut
+
+  func signIn() {
+    guard let clientID = FirebaseApp.app()?.options.clientID else {
+      fatalError("Missing clientID. Check the GoogleService-Info.plist")
+    }
+
+    GIDSignIn.sharedInstance.configuration = GIDConfiguration(clientID: clientID)
+
+    #if os(iOS) || os(visionOS)
+      guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
+            let rootViewController = windowScene.windows.first?.rootViewController else {
+        print("There is no presenting window!")
+        return
+      }
+    #elseif os(macOS)
+      guard let rootViewController = NSApplication.shared.windows.first else {
+        print("There is no presenting window!")
+        return
+      }
+    #endif
+
+    GIDSignIn.sharedInstance
+      .signIn(withPresenting: rootViewController) { [unowned self] result, error in
+        if let error = error {
+          print("Error doing Google Sign-In, \(error)")
+          return
+        }
+
+        guard let user = result?.user,
+              let idToken = user.idToken?.tokenString
+        else {
+          print("Error accessing Google Sign-In token")
+          return
+        }
+
+        let credential = GoogleAuthProvider.credential(withIDToken: idToken,
+                                                       accessToken: user.accessToken.tokenString)
+
+        Auth.auth().signIn(with: credential) { [unowned self] _, error in
+          if let error {
+            print(error.localizedDescription)
+          } else {
+            print("Signed in with Google")
+            self.state = .signedIn
+          }
+        }
+      }
+  }
+
+  func signOut() {
+    GIDSignIn.sharedInstance.signOut()
+
+    do {
+      try Auth.auth().signOut()
+
+      state = .signedOut
+    } catch {
+      print(error.localizedDescription)
+    }
+  }
+}

+ 30 - 0
FirebaseAuth/Tests/MultiPlatformSample/MultiPlatformSample/ContentView.swift

@@ -0,0 +1,30 @@
+// Copyright 2024 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.
+
+import SwiftUI
+
+struct ContentView: View {
+  @EnvironmentObject var viewModel: AuthViewModel
+
+  var body: some View {
+    switch viewModel.state {
+    case .signedIn: HomeView()
+    case .signedOut: LoginView()
+    }
+  }
+}
+
+#Preview {
+  ContentView()
+}

+ 56 - 0
FirebaseAuth/Tests/MultiPlatformSample/MultiPlatformSample/HomeView.swift

@@ -0,0 +1,56 @@
+// Copyright 2024 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.
+
+import GoogleSignIn
+import SwiftUI
+
+struct HomeView: View {
+  @EnvironmentObject var viewModel: AuthViewModel
+
+  private let user = GIDSignIn.sharedInstance.currentUser
+
+  var body: some View {
+    NavigationView {
+      VStack {
+        HStack {
+          VStack(alignment: .leading) {
+            Text(user?.profile?.name ?? "")
+              .font(.headline)
+
+            Text(user?.profile?.email ?? "")
+              .font(.subheadline)
+          }
+          Spacer()
+        }
+        .padding()
+        .frame(maxWidth: .infinity)
+        .cornerRadius(12)
+        .padding()
+
+        Spacer()
+
+        Button(action: viewModel.signOut) {
+          Text("Sign out")
+            .foregroundColor(.white)
+            .padding()
+            .frame(maxWidth: .infinity)
+            .background(Color(.systemIndigo))
+            .cornerRadius(12)
+            .padding()
+        }
+      }
+      .navigationTitle("Multi Platform")
+    }
+  }
+}

+ 19 - 0
FirebaseAuth/Tests/MultiPlatformSample/MultiPlatformSample/Info.plist

@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleURLTypes</key>
+	<array>
+		<dict>
+			<key>CFBundleTypeRole</key>
+			<string>Editor</string>
+			<key>CFBundleURLName</key>
+			<string>$REVERSE_CLIENT_ID</string>
+			<key>CFBundleURLSchemes</key>
+			<array>
+				<string>com.googleusercontent.apps.636990941390-comoffgboe1r5kk0t6ttp7k3dhs1coal</string>
+			</array>
+		</dict>
+	</array>
+</dict>
+</plist>

+ 10 - 0
FirebaseAuth/Tests/MultiPlatformSample/MultiPlatformSample/MultiPlatformSample.entitlements

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+    <key>com.apple.security.app-sandbox</key>
+    <true/>
+    <key>com.apple.security.files.user-selected.read-only</key>
+    <true/>
+</dict>
+</plist>

+ 42 - 0
FirebaseAuth/Tests/MultiPlatformSample/MultiPlatformSample/MultiPlatformSampleApp.swift

@@ -0,0 +1,42 @@
+// Copyright 2024 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.
+
+import FirebaseCore
+import GoogleSignIn
+import SwiftUI
+
+@main
+struct MultiPlatformSampleApp: App {
+  @StateObject var viewModel = AuthViewModel()
+
+  init() {
+    initFirebase()
+  }
+
+  var body: some Scene {
+    WindowGroup {
+      ContentView()
+        .onOpenURL { url in
+          GIDSignIn.sharedInstance.handle(url)
+        }
+        .environmentObject(viewModel)
+    }
+  }
+}
+
+extension MultiPlatformSampleApp {
+  private func initFirebase() {
+    FirebaseApp.configure()
+  }
+}

+ 6 - 0
FirebaseAuth/Tests/MultiPlatformSample/MultiPlatformSample/Preview Content/Preview Assets.xcassets/Contents.json

@@ -0,0 +1,6 @@
+{
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

+ 40 - 0
FirebaseAuth/Tests/MultiPlatformSample/MultiPlatformSample/SwiftUIView.swift

@@ -0,0 +1,40 @@
+// Copyright 2024 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.
+
+import GoogleSignInSwift
+import SwiftUI
+
+struct LoginView: View {
+  @EnvironmentObject var viewModel: AuthViewModel
+
+  var body: some View {
+    VStack {
+      Spacer()
+
+      Text("Welcome to the Multi Platform App!")
+        .fontWeight(.black)
+        .foregroundColor(Color(.systemIndigo))
+        .font(.largeTitle)
+        .multilineTextAlignment(.center)
+
+      Spacer()
+
+      GoogleSignInButton(action: handleSignInButton)
+    }
+  }
+
+  func handleSignInButton() {
+    viewModel.signIn()
+  }
+}

+ 0 - 40
FirebaseAuth/Tests/SampleSwift/Podfile

@@ -1,40 +0,0 @@
-# Uncomment the next line to define a global platform for your project
-platform :ios, '13.0'
-
-target 'AuthenticationExample' do
-  # Comment the next line if you don't want to use dynamic frameworks
-  use_frameworks!
-
-  # Pods for AuthenticationExample
-  ## Firebase 🔥 Pods
-  pod 'FirebaseCore', :path => '../../../'
-  pod 'FirebaseCoreInternal', :path => '../../../'
-  pod 'FirebaseCoreExtension', :path => '../../../'
-  pod 'FirebaseAuth', :path => '../../../', :testspecs => ['unit']
-  pod 'FirebaseInstallations', :path => '../../..'
-  pod 'FirebaseAuthInterop', :path => '../../..'
-  pod 'FirebaseAppCheckInterop', :path => '../../..'
-
-  pod 'RecaptchaEnterprise', '~> 18.3'
-
-  ## Pod for Sign in with Google
-  pod 'GoogleSignIn'
-
-  ## Pod for Sign in with Facebook
-  pod 'FBSDKLoginKit', '< 13'
-
-  target 'SwiftApiTests' do
-    inherit! :search_paths
-    # Pods for testing
-  end
-
-  target 'ObjCApiTests' do
-    inherit! :search_paths
-    # Pods for testing
-  end
-
-  target 'AuthenticationExampleUITests' do
-    # Pods for testing
-  end
-
-end

+ 10 - 0
scripts/build.sh

@@ -298,6 +298,16 @@ case "$product-$platform-$method" in
         build
     ;;
 
+  Auth-*-multiplatform)
+    if check_secrets; then
+      RunXcodebuild \
+        -project 'FirebaseAuth/Tests/SampleSwift/AuthenticationExample.xcodeproj' \
+        -scheme "MultiPlatformSample" \
+        "${xcb_flags[@]}" \
+        test
+    fi
+    ;;
+
   Auth-*-xcodebuild)
     if check_secrets; then
       RunXcodebuild \