Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
b8a4e4d
Support using a debug app check provider during configuration
mdmathias Aug 25, 2023
fd77924
Update Podfile
mdmathias Aug 25, 2023
5aa30fd
Use debug provider in example app running in DEBUG
mdmathias Aug 25, 2023
d21b7b2
Add convenience class methods for creating GIDAppCheck
mdmathias Aug 25, 2023
b8083da
Use targetEnvironment(simulator) instead of DEBUG
mdmathias Aug 30, 2023
1332eaf
Some changes for the debug provider
mdmathias Aug 30, 2023
8745b14
Clarify that configure method on GIDSignIn takes a bool
mdmathias Aug 30, 2023
d8fed0a
Update swift name for GIDSignIn configure method
mdmathias Aug 30, 2023
f25ca3f
Use new configure method in GIDSignInTest
mdmathias Aug 30, 2023
de9f81d
Remove use of GACAppCheckTokenProtocol per AppCheckCore api changes (…
mdmathias Aug 31, 2023
d35b8d9
Support using a debug app check provider during configuration
mdmathias Aug 25, 2023
77ff986
Update Podfile
mdmathias Aug 25, 2023
7a0f2e7
Use debug provider in example app running in DEBUG
mdmathias Aug 25, 2023
8607395
Add convenience class methods for creating GIDAppCheck
mdmathias Aug 25, 2023
ff0d27a
Use targetEnvironment(simulator) instead of DEBUG
mdmathias Aug 30, 2023
f26e917
Some changes for the debug provider
mdmathias Aug 30, 2023
481c3d0
Clarify that configure method on GIDSignIn takes a bool
mdmathias Aug 30, 2023
7ab2910
Update swift name for GIDSignIn configure method
mdmathias Aug 30, 2023
862f870
Use new configure method in GIDSignInTest
mdmathias Aug 30, 2023
9d08033
Support for debug tokens including a config for secrets
mdmathias Sep 5, 2023
8b08899
Resolve merge conflicts
mdmathias Sep 5, 2023
39cd414
Fix xcscheme conflict
mdmathias Sep 6, 2023
a3a531f
Fix conflicts in GIDSignInTes
mdmathias Sep 6, 2023
1920244
Remove unused param from doc comment
mdmathias Sep 6, 2023
ac495f0
Add AppCheckSecretReader
mdmathias Sep 6, 2023
59c92de
Update GoogleSignIn.podspec dep on AppCheckCore to alpha.8
mdmathias Sep 7, 2023
d966e2b
Update nullability declarations for token
mdmathias Sep 8, 2023
53afe33
Replace nullable with nil in doc comment
mdmathias Sep 8, 2023
b89114f
Update to AppCheckCore alpha.9
mdmathias Sep 8, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ Podfile.lock

# Firebase App Check Example
**/GoogleService-Info.plist
**/AppCheckSecrets.xcconfig
2 changes: 1 addition & 1 deletion GoogleSignIn.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ The Google Sign-In SDK allows users to sign in with their Google account from th
]
s.ios.framework = 'UIKit'
s.osx.framework = 'AppKit'
s.dependency 'AppCheckCore', '~> 0.1.0-alpha.4'
s.dependency 'AppCheckCore', '~> 0.1.0-alpha.9'
s.dependency 'AppAuth', '~> 1.6'
s.dependency 'GTMAppAuth', '~> 4.0'
s.dependency 'GTMSessionFetcher/Core', '>= 1.1', '< 4.0'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ NS_CLASS_AVAILABLE_IOS(14)
/// error.
///
/// @param token The `GACAppCheckToken` instance to pass into the completion called from
/// `getTokenWithCompletion:`.
/// `getTokenWithCompletion:`. Use `nil` if you would like a placeholder token from
/// AppCheckCore.
/// @param error The `NSError` to pass into the completion called from
/// `getTokenWithCompletion:`.
- (instancetype)initWithAppCheckToken:(nullable GACAppCheckToken *)token
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@

@interface GIDAppCheckProviderFake ()

@property(nonatomic, strong, nullable) id<GACAppCheckTokenProtocol> token;
@property(nonatomic, strong, nullable) GACAppCheckToken *token;
@property(nonatomic, strong, nullable) NSError *error;

@end

@implementation GIDAppCheckProviderFake

- (instancetype)initWithAppCheckToken:(nullable id<GACAppCheckTokenProtocol>)token
- (instancetype)initWithAppCheckToken:(nullable GACAppCheckToken *)token
error:(nullable NSError *)error {
if (self = [super init]) {
_token = token;
Expand All @@ -38,14 +38,13 @@ - (instancetype)initWithAppCheckToken:(nullable id<GACAppCheckTokenProtocol>)tok
return self;
}

- (void)getTokenWithCompletion:(nonnull void (^)(id<GACAppCheckTokenProtocol> _Nullable,
NSError * _Nullable))handler {
- (void)getTokenWithCompletion:(void (^)(GACAppCheckToken *, NSError * _Nullable))handler {
dispatch_async(dispatch_get_main_queue(), ^{
handler(self.token, self.error);
});
}

- (void)getLimitedUseTokenWithCompletion:(void (^)(id<GACAppCheckTokenProtocol> _Nullable,
- (void)getLimitedUseTokenWithCompletion:(void (^)(GACAppCheckToken *,
NSError * _Nullable))handler {
dispatch_async(dispatch_get_main_queue(), ^{
handler(self.token, self.error);
Expand Down
24 changes: 14 additions & 10 deletions GoogleSignIn/Sources/GIDAppCheck/Implementations/GIDAppCheck.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,26 @@
NS_ASSUME_NONNULL_BEGIN

@protocol GACAppCheckProvider;
@protocol GACAppCheckTokenProtocol;
@class GACAppCheckToken;

extern NSString *const kGIDAppCheckPreparedKey;

NS_CLASS_AVAILABLE_IOS(14)
@interface GIDAppCheck : NSObject

/// Creates the instance of this App Check wrapper class.
- (instancetype)init NS_UNAVAILABLE;

/// Creates the instance of this App Check wrapper class using `GACAppCheckDebugProvider`.
///
/// The instance is created using `+[NSUserDefaults standardUserDefaults]` and the standard App
/// Check provider.
/// @param APIKey The API Key to use when creating the debug App Check provider.
///
/// The instance is created using `+[NSUserDefaults standardUserDefaults]`.
+ (instancetype)appCheckUsingDebugProviderWithAPIKey:(NSString *)APIKey;

/// Creates the instance of this App Check wrapper class using `GACAppAttestProvider`.
///
/// @SeeAlso The App Check provider is constructed with `+[GIDAppCheck standardAppCheckProvider]`.
- (instancetype)init;
/// The instance is created using `+[NSUserDefaults standardUserDefaults]`.
+ (instancetype)appCheckUsingAppAttestProvider;

/// Creates the instance of this App Check wrapper class.
///
Expand All @@ -55,11 +61,9 @@ NS_CLASS_AVAILABLE_IOS(14)

/// Fetches the limited use Firebase token.
///
/// @param completion A `nullable` callback with the `FIRAppCheckToken` if present, or an `NSError`
/// otherwise.
/// @param completion A `nullable` callback with the `FIRAppCheckToken`, or an `NSError` otherwise.
- (void)getLimitedUseTokenWithCompletion:
(nullable void (^)(id<GACAppCheckTokenProtocol> _Nullable token,
NSError * _Nullable error))completion;
(nullable void (^)(GACAppCheckToken *token, NSError * _Nullable error))completion;

/// Whether or not the App Attest key ID created and the attestation object has been fetched.
- (BOOL)isPrepared;
Expand Down
44 changes: 27 additions & 17 deletions GoogleSignIn/Sources/GIDAppCheck/Implementations/GIDAppCheck.m
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@

#import <AppCheckCore/GACAppCheck.h>
#import <AppCheckCore/GACAppCheckSettings.h>
#import <AppCheckCore/GACAppCheckToken.h>
#import <AppCheckCore/GACAppCheckTokenResult.h>
#import <AppCheckCore/GACAppAttestProvider.h>
#import <AppCheckCore/GACAppCheckDebugProvider.h>

#import "GoogleSignIn/Sources/GIDAppCheck/Implementations/GIDAppCheck.h"
#import "GoogleSignIn/Sources/Public/GoogleSignIn/GIDAppCheckError.h"
Expand All @@ -35,8 +36,7 @@
static NSString *const kGIDAppAttestBaseURL = @"https://firebaseappcheck.googleapis.com/v1beta";

typedef void (^GIDAppCheckPrepareCompletion)(NSError * _Nullable);
typedef void (^GIDAppCheckTokenCompletion)(id<GACAppCheckTokenProtocol> _Nullable,
NSError * _Nullable);
typedef void (^GIDAppCheckTokenCompletion)(GACAppCheckToken *,NSError * _Nullable);

@interface GIDAppCheck ()

Expand All @@ -50,10 +50,14 @@ @interface GIDAppCheck ()

@implementation GIDAppCheck

- (instancetype)init {
id<GACAppCheckProvider> provider = [GIDAppCheck standardAppCheckProvider];
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
return [self initWithAppCheckProvider:provider userDefaults:userDefaults];
+ (instancetype)appCheckUsingDebugProviderWithAPIKey:(NSString *)APIKey {
return [[self alloc] initWithAppCheckProvider:[GIDAppCheck debugAppCheckProviderWithAPIKey:APIKey]
userDefaults:[NSUserDefaults standardUserDefaults]];
}

+ (instancetype)appCheckUsingAppAttestProvider {
return [[self alloc] initWithAppCheckProvider:[GIDAppCheck appAttestProvider]
userDefaults:[NSUserDefaults standardUserDefaults]];
}

- (instancetype)initWithAppCheckProvider:(id<GACAppCheckProvider>)appCheckProvider
Expand Down Expand Up @@ -110,17 +114,16 @@ - (void)prepareForAppCheckWithCompletion:(nullable GIDAppCheckPrepareCompletion)
return;
}

[self.appCheck limitedUseTokenWithCompletion:^(id<GACAppCheckTokenProtocol> _Nullable token,
NSError * _Nullable error) {
NSError * __block maybeError = error;
[self.appCheck limitedUseTokenWithCompletion:^(GACAppCheckTokenResult * _Nonnull result) {
NSError * __block maybeError = result.error;
@synchronized (self) {
if (!token && !error) {
if (!result.token && !result.error) {
maybeError = [NSError errorWithDomain:kGIDAppCheckErrorDomain
code:kGIDAppCheckUnexpectedError
userInfo:nil];
}

if (token) {
if (result.token) {
[self.userDefaults setBool:YES forKey:kGIDAppCheckPreparedKey];
}

Expand All @@ -139,13 +142,12 @@ - (void)prepareForAppCheckWithCompletion:(nullable GIDAppCheckPrepareCompletion)

- (void)getLimitedUseTokenWithCompletion:(nullable GIDAppCheckTokenCompletion)completion {
dispatch_async(self.workerQueue, ^{
[self.appCheck limitedUseTokenWithCompletion:^(id<GACAppCheckTokenProtocol> _Nullable token,
NSError * _Nullable error) {
if (token) {
[self.appCheck limitedUseTokenWithCompletion:^(GACAppCheckTokenResult * _Nonnull result) {
if (result.token) {
[self.userDefaults setBool:YES forKey:kGIDAppCheckPreparedKey];
}
if (completion) {
completion(token, error);
completion(result.token, result.error);
}
}];
});
Expand All @@ -156,7 +158,7 @@ + (NSString *)appAttestResourceName {
return [NSString stringWithFormat:kGIDAppAttestResourceNameFormat, clientID];
}

+ (id<GACAppCheckProvider>)standardAppCheckProvider {
+ (id<GACAppCheckProvider>)appAttestProvider {
return [[GACAppAttestProvider alloc] initWithServiceName:kGIDAppAttestServiceName
resourceName:[GIDAppCheck appAttestResourceName]
baseURL:kGIDAppAttestBaseURL
Expand All @@ -165,6 +167,14 @@ + (NSString *)appAttestResourceName {
requestHooks:nil];
}

+ (id<GACAppCheckProvider>)debugAppCheckProviderWithAPIKey:(NSString *)APIKey {
return [[GACAppCheckDebugProvider alloc] initWithServiceName:kGIDAppAttestServiceName
resourceName:[GIDAppCheck appAttestResourceName]
baseURL:kGIDAppAttestBaseURL
APIKey:APIKey
requestHooks:nil];
}

@end

#endif // TARGET_OS_IOS && !TARGET_OS_MACCATALYST
18 changes: 15 additions & 3 deletions GoogleSignIn/Sources/GIDSignIn.m
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,7 @@ + (GIDSignIn *)sharedInstance {
[[GTMKeychainStore alloc] initWithItemName:kGTMAppAuthKeychainName];
#if TARGET_OS_IOS && !TARGET_OS_MACCATALYST
if (@available(iOS 14.0, *)) {
GIDAppCheck *appCheck = [[GIDAppCheck alloc] init];
GIDAppCheck *appCheck = [GIDAppCheck appCheckUsingAppAttestProvider];
sharedInstance = [[self alloc] initWithKeychainStore:keychainStore
appCheck:appCheck];
}
Expand All @@ -488,6 +488,18 @@ - (void)configureWithCompletion:(nullable void (^)(NSError * _Nullable))completi
}];
}
}

- (void)configureDebugProviderWithAPIKey:(NSString *)APIKey
completion:(nullable void (^)(NSError * _Nullable))completion {
@synchronized(self) {
_appCheck = [GIDAppCheck appCheckUsingDebugProviderWithAPIKey:APIKey];
[_appCheck prepareForAppCheckWithCompletion:^(NSError * _Nullable error) {
if (completion) {
completion(error);
}
}];
}
}
#endif // TARGET_OS_IOS && !TARGET_OS_MACCATALYST

#pragma mark - Private methods
Expand Down Expand Up @@ -646,8 +658,8 @@ - (void)authorizationRequestWithOptions:(GIDSignInInternalOptions *)options comp
_timedLoader = [[GIDTimedLoader alloc] initWithPresentingViewController:presentingVC];
}
[_timedLoader startTiming];
[self->_appCheck getLimitedUseTokenWithCompletion:
^(id<GACAppCheckTokenProtocol> _Nullable token, NSError * _Nullable error) {
[self->_appCheck getLimitedUseTokenWithCompletion:^(GACAppCheckToken * _Nullable token,
NSError * _Nullable error) {
OIDAuthorizationRequest *request = nil;
if (token) {
additionalParameters[kClientAssertionTypeParameter] = kClientAssertionTypeParameterValue;
Expand Down
17 changes: 15 additions & 2 deletions GoogleSignIn/Sources/Public/GoogleSignIn/GIDSignIn.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,27 @@ typedef NS_ERROR_ENUM(kGIDSignInErrorDomain, GIDSignInErrorCode) {
/// Configures `GIDSignIn` for use.
///
/// @param completion A nullable callback block passing back any error arising from the
/// configuration process if any exists.
/// configuration process if any exists.
///
/// Call this method on `GIDSignIn` prior to use and as early as possible. This method generates App
/// Attest key IDs and the attestation object eagerly to minimize latency later on during the sign
/// in or add scopes flows.
- (void)configureWithCompletion:(nullable void (^)(NSError * _Nullable error))completion
NS_SWIFT_NAME(configure(completion:));

/// Configures `GIDSignIn` for use in debug or test environments.
///
/// @param APIKey The API Key to use during configuration of the App Check debug provider.
/// @param completion A nullable callback block passing back any error arising from the
/// configuration process if any exists.
///
/// Call this method on `GIDSignIn` prior to use and as early as possible. This method generates App
/// Attest key IDs and the attestation object eagerly to minimize latency later on during the sign
/// in or add scopes flows.
- (void)configureDebugProviderWithAPIKey:(NSString *)APIKey
completion:(nullable void (^)(NSError * _Nullable error))completion
API_AVAILABLE(ios(14))
NS_SWIFT_NAME(configureWithCompletion(completion:));
NS_SWIFT_NAME(configureDebugProvider(withAPIKey:completion:));

#endif // TARGET_OS_IOS && !TARGET_OS_MACCATALYST

Expand Down
8 changes: 4 additions & 4 deletions GoogleSignIn/Tests/Unit/GIDAppCheckTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ - (void)tearDown {
[self.userDefaults removeSuiteNamed:kUserDefaultsTestSuiteName];
}

- (void)testGetLimitedUseTokenFailure {
- (void)testGetLimitedUseTokenFailureReturnsPlaceholder {
XCTestExpectation *tokenFailExpectation =
[self expectationWithDescription:@"App check token fail"];
NSError *expectedError = [NSError errorWithDomain:kGIDAppCheckErrorDomain
Expand All @@ -57,10 +57,10 @@ - (void)testGetLimitedUseTokenFailure {
GIDAppCheck *appCheck = [[GIDAppCheck alloc] initWithAppCheckProvider:fakeProvider
userDefaults:self.userDefaults];

[appCheck getLimitedUseTokenWithCompletion:^(id<GACAppCheckTokenProtocol> _Nullable token,
[appCheck getLimitedUseTokenWithCompletion:^(GACAppCheckToken *token,
NSError * _Nullable error) {
XCTAssertNil(token);
XCTAssertEqualObjects(expectedError, error);
XCTAssertNotNil(token); // If there is an error, we expect a placeholder token
[tokenFailExpectation fulfill];
}];

Expand Down Expand Up @@ -126,7 +126,7 @@ - (void)testGetLimitedUseTokenSucceeds {
XCTestExpectation *getLimitedUseTokenSucceedsExpectation =
[self expectationWithDescription:@"getLimitedUseToken should succeed"];

[appCheck getLimitedUseTokenWithCompletion:^(id<GACAppCheckTokenProtocol> _Nullable token,
[appCheck getLimitedUseTokenWithCompletion:^(GACAppCheckToken *token,
NSError * _Nullable error) {
XCTAssertNil(error);
XCTAssertNotNil(token);
Expand Down
2 changes: 1 addition & 1 deletion GoogleSignIn/Tests/Unit/GIDSignInTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ - (void)testConfigureFailsNoTokenOrError {
GIDSignIn *signIn = [[GIDSignIn alloc] initWithKeychainStore:_keychainStore
appCheck:appCheck];

// `configureWithCompletion:` should fail if neither a token or error is present
// Should fail if missing both token and error
[signIn configureWithCompletion:^(NSError * _Nullable error) {
XCTAssertNotNil(error);
XCTAssertEqual(error.code, kGIDAppCheckUnexpectedError);
Expand Down
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ let package = Package(
.package(
name: "AppCheck",
url: "https://github.com/google/app-check.git",
.branch("main")),
.branch("CocoaPods-0.1.0-alpha.6")),
.package(
name: "GTMAppAuth",
url: "https://github.com/google/GTMAppAuth.git",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

/* Begin PBXBuildFile section */
4D8DB53AAE2F7D0055DCEA7F /* Pods_AppAttestExample.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 91F3A930BB86D9E0648046BC /* Pods_AppAttestExample.framework */; };
738B4A322AA8FE800056885D /* AppCheckSecretReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 738B4A312AA8FE800056885D /* AppCheckSecretReader.swift */; };
738D5F732A26BC3B00A7F11B /* BirthdayLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 738D5F722A26BC3B00A7F11B /* BirthdayLoader.swift */; };
73A464042A1C3B3400BA8528 /* AppAttestExampleApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 73A464032A1C3B3400BA8528 /* AppAttestExampleApp.swift */; };
73A464062A1C3B3400BA8528 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 73A464052A1C3B3400BA8528 /* ContentView.swift */; };
Expand All @@ -17,6 +18,8 @@
/* Begin PBXFileReference section */
1C96B5B2B34E31F1A1CEE95E /* Pods-AppAttestExample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AppAttestExample.release.xcconfig"; path = "Target Support Files/Pods-AppAttestExample/Pods-AppAttestExample.release.xcconfig"; sourceTree = "<group>"; };
73443A232A55F56900A4932E /* AppAttestExample.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = AppAttestExample.entitlements; sourceTree = "<group>"; };
738B4A302AA7EB840056885D /* AppCheckSecrets.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppCheckSecrets.xcconfig; sourceTree = "<group>"; };
738B4A312AA8FE800056885D /* AppCheckSecretReader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppCheckSecretReader.swift; sourceTree = "<group>"; };
738D5F722A26BC3B00A7F11B /* BirthdayLoader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BirthdayLoader.swift; sourceTree = "<group>"; };
73A065612A786D10007BC7FC /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
73A464002A1C3B3400BA8528 /* AppAttestExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AppAttestExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -73,6 +76,8 @@
73A464032A1C3B3400BA8528 /* AppAttestExampleApp.swift */,
73A464052A1C3B3400BA8528 /* ContentView.swift */,
738D5F722A26BC3B00A7F11B /* BirthdayLoader.swift */,
738B4A312AA8FE800056885D /* AppCheckSecretReader.swift */,
738B4A302AA7EB840056885D /* AppCheckSecrets.xcconfig */,
73A065612A786D10007BC7FC /* Info.plist */,
73A464092A1C3B3500BA8528 /* Preview Content */,
);
Expand Down Expand Up @@ -209,6 +214,7 @@
buildActionMask = 2147483647;
files = (
738D5F732A26BC3B00A7F11B /* BirthdayLoader.swift in Sources */,
738B4A322AA8FE800056885D /* AppCheckSecretReader.swift in Sources */,
73A464062A1C3B3400BA8528 /* ContentView.swift in Sources */,
73A464042A1C3B3400BA8528 /* AppAttestExampleApp.swift in Sources */,
);
Expand All @@ -219,6 +225,7 @@
/* Begin XCBuildConfiguration section */
73A4640C2A1C3B3500BA8528 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 738B4A302AA7EB840056885D /* AppCheckSecrets.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,6 @@
ReferencedContainer = "container:AppAttestExample.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<EnvironmentVariables>
<EnvironmentVariable
key = "FIRAppCheckDebugToken"
value = "F40DF0E8-9CCC-46DF-AC01-43DE96FCEDD8"
isEnabled = "YES">
</EnvironmentVariable>
</EnvironmentVariables>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
Expand Down
Loading