Skip to content

Commit bdb0088

Browse files
authored
Add FirAuthUrlPresenter (firebase#222)
* Adds FIRAuthURLPResenter and FIRAuthUIDelegate
1 parent ca9fb2e commit bdb0088

File tree

12 files changed

+588
-0
lines changed

12 files changed

+588
-0
lines changed

AuthSamples/Samples.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
52C975C71EE10B1304EBBEB2 /* Pods_SwiftSample.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BC8C39EF1F42A0C750FF5186 /* Pods_SwiftSample.framework */; };
2727
569C3F4E18627674CABE02AE /* Pods_EarlGreyTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AEE2E563FADF8C3382956B4F /* Pods_EarlGreyTests.framework */; };
2828
67AFFB52FF0FC4668D92F2E4 /* Pods_Sample.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D5FE06BD9AA795DFBA9EFAAD /* Pods_Sample.framework */; };
29+
7E04ACA41F565EA900788114 /* FIRAuthURLPresenterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7E04ACA31F565EA900788114 /* FIRAuthURLPresenterTests.m */; };
2930
7E9969EE1F4E277900627C2B /* FIRGetProjectConfigRequestTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7E9969EC1F4E277900627C2B /* FIRGetProjectConfigRequestTests.m */; };
3031
7EDFD35B1F0EA29200B29DC5 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7EDFD35D1F0EA29200B29DC5 /* Localizable.strings */; };
3132
7EEEFEE61F4E4F75000FF966 /* FIRGetProjectConfigResponseTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7EEA8ADD1F4E4E840014A23B /* FIRGetProjectConfigResponseTests.m */; };
@@ -183,6 +184,7 @@
183184
4FFAD3F37BC4D7CEF0CAD579 /* Pods_FirebaseAuthUnitTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_FirebaseAuthUnitTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
184185
57150555A6B03949ECB58AD9 /* Pods-TestApp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TestApp.debug.xcconfig"; path = "Pods/Target Support Files/Pods-TestApp/Pods-TestApp.debug.xcconfig"; sourceTree = "<group>"; };
185186
6EC09307D636721EAAB89BB2 /* Pods_ApiTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ApiTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
187+
7E04ACA31F565EA900788114 /* FIRAuthURLPresenterTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FIRAuthURLPresenterTests.m; path = ../../Example/Auth/Tests/FIRAuthURLPresenterTests.m; sourceTree = "<group>"; };
186188
7E0BC64A1F199D86008BE4E0 /* fr-FR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "fr-FR"; path = "fr-FR.lproj/Localizable.strings"; sourceTree = "<group>"; };
187189
7E0BC64E1F19A77C008BE4E0 /* ru-RU */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "ru-RU"; path = "ru-RU.lproj/Localizable.strings"; sourceTree = "<group>"; };
188190
7E9969EC1F4E277900627C2B /* FIRGetProjectConfigRequestTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FIRGetProjectConfigRequestTests.m; path = ../../Example/Auth/Tests/FIRGetProjectConfigRequestTests.m; sourceTree = "<group>"; };
@@ -557,6 +559,7 @@
557559
DE5371B21EA7E89D000DA57F /* Tests-Info.plist */,
558560
7E9969EC1F4E277900627C2B /* FIRGetProjectConfigRequestTests.m */,
559561
7EEA8ADD1F4E4E840014A23B /* FIRGetProjectConfigResponseTests.m */,
562+
7E04ACA31F565EA900788114 /* FIRAuthURLPresenterTests.m */,
560563
);
561564
path = UnitTests;
562565
sourceTree = "<group>";
@@ -1332,6 +1335,7 @@
13321335
DECEA56E1EBBED1200273585 /* FIRAuthAppCredentialManagerTests.m in Sources */,
13331336
DE5371DE1EA7E89D000DA57F /* OCMStubRecorder+FIRAuthUnitTests.m in Sources */,
13341337
DE5371DC1EA7E89D000DA57F /* FIRVerifyPhoneNumberRequestTests.m in Sources */,
1338+
7E04ACA41F565EA900788114 /* FIRAuthURLPresenterTests.m in Sources */,
13351339
DE5371B51EA7E89D000DA57F /* FIRAuthAppCredentialTests.m in Sources */,
13361340
DE5371CE1EA7E89D000DA57F /* FIRSetAccountInfoRequestTests.m in Sources */,
13371341
DE5371D41EA7E89D000DA57F /* FIRVerifyAssertionRequestTests.m in Sources */,
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
/*
2+
* Copyright 2017 Google
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/Foundation.h>
18+
#import <SafariServices/SafariServices.h>
19+
#import <XCTest/XCTest.h>
20+
21+
#import "FIRAuthURLPresenter.h"
22+
#import "FIRAuthUIDelegate.h"
23+
#import <OCMock/OCMock.h>
24+
25+
/** @var kExpectationTimeout
26+
@brief The maximum time waiting for expectations to fulfill.
27+
*/
28+
static NSTimeInterval kExpectationTimeout = 1;
29+
30+
@interface FIRAuthDefaultUIDelegate : NSObject <FIRAuthUIDelegate>
31+
/** @fn defaultUIDelegate
32+
@brief Returns a default FIRAuthUIDelegate object.
33+
@return The default FIRAuthUIDelegate object.
34+
*/
35+
+ (id<FIRAuthUIDelegate>)defaultUIDelegate;
36+
@end
37+
38+
@interface FIRAuthURLPresenterTests : XCTestCase
39+
40+
@end
41+
42+
@implementation FIRAuthURLPresenterTests
43+
44+
/** @fn testFIRAuthURLPresenterNonNilUIDelegate
45+
@brief Tests @c FIRAuthURLPresenter class showing UI with a non-nil UIDelegate.
46+
*/
47+
- (void)testFIRAuthURLPresenterNonNilUIDelegate {
48+
id mockUIDelegate = OCMProtocolMock(@protocol(FIRAuthUIDelegate));
49+
NSURL *presenterURL = [NSURL URLWithString:@"https://presenter.url"];
50+
FIRAuthURLPresenter *presenter = [[FIRAuthURLPresenter alloc] init];
51+
52+
if ([SFSafariViewController class]) {
53+
XCTestExpectation *callbackMatcherExpectation =
54+
[self expectationWithDescription:@"callbackMatcher callback"];
55+
FIRAuthURLCallbackMatcher callbackMatcher = ^BOOL(NSURL *_Nonnull callbackURL) {
56+
XCTAssertEqualObjects(callbackURL, presenterURL);
57+
[callbackMatcherExpectation fulfill];
58+
return YES;
59+
};
60+
61+
XCTestExpectation *completionBlockExpectation =
62+
[self expectationWithDescription:@"completion callback"];
63+
FIRAuthURLPresentationCompletion completionBlock = ^(NSURL *_Nullable callbackURL,
64+
NSError *_Nullable error) {
65+
XCTAssertEqualObjects(callbackURL, presenterURL);
66+
XCTAssertNil(error);
67+
[completionBlockExpectation fulfill];
68+
};
69+
70+
id presenterArg = [OCMArg isKindOfClass:[SFSafariViewController class]];
71+
OCMExpect([mockUIDelegate presentViewController:presenterArg
72+
animated:YES
73+
completion:nil]).andDo(^(NSInvocation *invocation) {
74+
__unsafe_unretained id unretainedArgument;
75+
// Indices 0 and 1 indicate the hidden arguments self and _cmd.
76+
// `presentViewController` is at index 2.
77+
[invocation getArgument:&unretainedArgument atIndex:2];
78+
79+
SFSafariViewController *viewController = unretainedArgument;
80+
XCTAssertEqual(viewController.delegate, presenter);
81+
XCTAssertTrue([viewController isKindOfClass:[SFSafariViewController class]]);
82+
});
83+
[presenter presentURL:presenterURL
84+
UIDelegate:mockUIDelegate
85+
callbackMatcher:callbackMatcher
86+
completion:completionBlock];
87+
OCMVerifyAll(mockUIDelegate);
88+
OCMExpect([mockUIDelegate dismissViewControllerAnimated:OCMOCK_ANY
89+
completion:OCMOCK_ANY]).
90+
andDo(^(NSInvocation *invocation) {
91+
__unsafe_unretained id unretainedArgument;
92+
// Indices 0 and 1 indicate the hidden arguments self and _cmd.
93+
// `completion` is at index 3.
94+
[invocation getArgument:&unretainedArgument atIndex:3];
95+
void (^finishBlock)() = unretainedArgument;
96+
finishBlock();
97+
});
98+
[presenter canHandleURL:presenterURL];
99+
[self waitForExpectationsWithTimeout:kExpectationTimeout handler:nil];
100+
OCMVerifyAll(mockUIDelegate);
101+
}
102+
}
103+
104+
/** @fn testFIRAuthURLPresenterNilUIDelegate
105+
@brief Tests @c FIRAuthURLPresenter class showing UI with a nil UIDelegate.
106+
*/
107+
- (void)testFIRAuthURLPresenterNilUIDelegate {
108+
NSURL *presenterURL = [NSURL URLWithString:@"https://presenter.url"];
109+
FIRAuthURLPresenter *presenter = [[FIRAuthURLPresenter alloc] init];
110+
111+
if ([SFSafariViewController class]) {
112+
XCTestExpectation *callbackMatcherExpectation =
113+
[self expectationWithDescription:@"callbackMatcher callback"];
114+
FIRAuthURLCallbackMatcher callbackMatcher = ^BOOL(NSURL *_Nonnull callbackURL) {
115+
XCTAssertEqualObjects(callbackURL, presenterURL);
116+
[callbackMatcherExpectation fulfill];
117+
return YES;
118+
};
119+
XCTestExpectation *completionBlockExpectation =
120+
[self expectationWithDescription:@"completion callback"];
121+
FIRAuthURLPresentationCompletion completionBlock = ^(NSURL *_Nullable callbackURL,
122+
NSError *_Nullable error) {
123+
XCTAssertEqualObjects(callbackURL, presenterURL);
124+
XCTAssertNil(error);
125+
[completionBlockExpectation fulfill];
126+
};
127+
128+
id mockUIDelegate = OCMProtocolMock(@protocol(FIRAuthUIDelegate));
129+
130+
// Swizzle default UIDelegate
131+
Method method = class_getClassMethod([FIRAuthDefaultUIDelegate class],
132+
@selector(defaultUIDelegate));
133+
__block IMP originalImplementation;
134+
IMP newImplmentation = imp_implementationWithBlock(^id(id object) {
135+
return mockUIDelegate;
136+
});
137+
originalImplementation = method_setImplementation(method, newImplmentation);
138+
if ([SFSafariViewController class]) {
139+
id presenterArg = [OCMArg isKindOfClass:[SFSafariViewController class]];
140+
OCMExpect([mockUIDelegate presentViewController:presenterArg
141+
animated:[OCMArg any]
142+
completion:[OCMArg any]]).
143+
andDo(^(NSInvocation *invocation) {
144+
__unsafe_unretained id unretainedArgument;
145+
// Indices 0 and 1 indicate the hidden arguments self and _cmd.
146+
// `presentViewController` is at index 2.
147+
[invocation getArgument:&unretainedArgument atIndex:2];
148+
SFSafariViewController *viewController = unretainedArgument;
149+
XCTAssertEqual(viewController.delegate, presenter);
150+
XCTAssertTrue([viewController isKindOfClass:[SFSafariViewController class]]);
151+
});
152+
}
153+
[presenter presentURL:presenterURL
154+
UIDelegate:nil
155+
callbackMatcher:callbackMatcher
156+
completion:completionBlock];
157+
OCMVerifyAll(mockUIDelegate);
158+
159+
OCMExpect([mockUIDelegate dismissViewControllerAnimated:OCMOCK_ANY
160+
completion:OCMOCK_ANY]).
161+
andDo(^(NSInvocation *invocation) {
162+
__unsafe_unretained id unretainedArgument;
163+
// Indices 0 and 1 indicate the hidden arguments self and _cmd.
164+
// `completion` is at index 3.
165+
[invocation getArgument:&unretainedArgument atIndex:3];
166+
void (^finishBlock)() = unretainedArgument;
167+
finishBlock();
168+
});
169+
[presenter canHandleURL:presenterURL];
170+
[self waitForExpectationsWithTimeout:kExpectationTimeout handler:nil];
171+
OCMVerifyAll(mockUIDelegate);
172+
// Unswizzle.
173+
imp_removeBlock(method_setImplementation(method, originalImplementation));
174+
}
175+
}
176+
177+
#pragma mark - Method Swizzling
178+
179+
+ (id)mockDefaultUIDelegate {
180+
return OCMProtocolMock(@protocol(FIRAuthUIDelegate));
181+
}
182+
183+
@end

Example/Firebase.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@
104104
79A15731AA31012CD937CF3A /* Pods_Core_Example_iOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CAD129FFEC477E1129AE6AA1 /* Pods_Core_Example_iOS.framework */; };
105105
7A02646DEF386689CCFB9011 /* Pods_Core_Tests_iOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AE6C9DD139E1FD21DC0F1082 /* Pods_Core_Tests_iOS.framework */; };
106106
7AE9A7433F2BD9A52022AC71 /* Pods_Messaging_Tests_iOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4F902A29FA956ADD762F6921 /* Pods_Messaging_Tests_iOS.framework */; };
107+
7E9485421F578AC4005A3939 /* FIRAuthURLPresenterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 7E94853F1F578A9D005A3939 /* FIRAuthURLPresenterTests.m */; };
107108
960665EC1C5F7A0E843A354F /* Pods_Database_Tests_macOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 97768125F45377F35CA86EDC /* Pods_Database_Tests_macOS.framework */; };
108109
AFAF36F51EC28C25004BDEE5 /* Shared.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = AFAF36F41EC28C25004BDEE5 /* Shared.xcassets */; };
109110
AFAF36F61EC28C25004BDEE5 /* Shared.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = AFAF36F41EC28C25004BDEE5 /* Shared.xcassets */; };
@@ -739,6 +740,7 @@
739740
6F7376F39846E902979416D4 /* Pods_Database_Example_iOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Database_Example_iOS.framework; sourceTree = BUILT_PRODUCTS_DIR; };
740741
6FAA689FDCBD3261300292D5 /* Pods-Database_IntegrationTests_macOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Database_IntegrationTests_macOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Database_IntegrationTests_macOS/Pods-Database_IntegrationTests_macOS.debug.xcconfig"; sourceTree = "<group>"; };
741742
73B480AA654FC97FA72C6293 /* Pods_Storage_Example_macOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Storage_Example_macOS.framework; sourceTree = BUILT_PRODUCTS_DIR; };
743+
7E94853F1F578A9D005A3939 /* FIRAuthURLPresenterTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FIRAuthURLPresenterTests.m; sourceTree = "<group>"; };
742744
81E83B5ABAE219234F213B27 /* Pods_Database_Tests_iOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Database_Tests_iOS.framework; sourceTree = BUILT_PRODUCTS_DIR; };
743745
8496034D8156555C5FCF8F14 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = "<group>"; };
744746
862CC98282A6123508E8CA49 /* Pods-Database_Example_macOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Database_Example_macOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-Database_Example_macOS/Pods-Database_Example_macOS.release.xcconfig"; sourceTree = "<group>"; };
@@ -1690,6 +1692,7 @@
16901692
DE9314F91E86C6FF0083EDBF /* Tests */ = {
16911693
isa = PBXGroup;
16921694
children = (
1695+
7E94853F1F578A9D005A3939 /* FIRAuthURLPresenterTests.m */,
16931696
DE750DB51EB3DD4000A75E47 /* FIRAuthAPNSTokenManagerTests.m */,
16941697
DE750DB61EB3DD4000A75E47 /* FIRAuthAPNSTokenTests.m */,
16951698
DE750DB71EB3DD4000A75E47 /* FIRAuthAppCredentialManagerTests.m */,
@@ -4187,6 +4190,7 @@
41874190
D9B0D4201F578F7200A567C2 /* FIRGetProjectConfigResponseTests.m in Sources */,
41884191
DE9315711E86C71C0083EDBF /* FIRSetAccountInfoResponseTests.m in Sources */,
41894192
DE93155F1E86C71C0083EDBF /* FIRAuthTests.m in Sources */,
4193+
7E9485421F578AC4005A3939 /* FIRAuthURLPresenterTests.m in Sources */,
41904194
DE750DBD1EB3DD5B00A75E47 /* FIRAuthAPNSTokenTests.m in Sources */,
41914195
DE0E5BBE1EA7D93500FAA825 /* FIRAuthAppDelegateProxyTests.m in Sources */,
41924196
DE0E5BBC1EA7D92E00FAA825 /* FIRVerifyClientResponseTests.m in Sources */,

Firebase/Auth/FirebaseAuth.podspec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ Simplify your iOS development, grow your user base, and monetize more effectivel
3131
'Source/**/FIRAuthAPNSTokenType.[mh]',
3232
'Source/**/FIRAuthAPNSToken.[mh]',
3333
'Source/**/FIRPhoneAuthCredential.[mh]',
34+
'Source/**/FIRAuthDefaultUIDelegate.[mh]',
3435
'Source/**/FIRPhoneAuthProvider.[mh]'
3536
s.public_header_files = 'Source/Public/*.h'
3637
s.preserve_paths =
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
* Copyright 2017 Google
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/Foundation.h>
18+
19+
#import "FIRAuthUIDelegate.h"
20+
21+
NS_ASSUME_NONNULL_BEGIN
22+
23+
@interface FIRAuthDefaultUIDelegate : NSObject <FIRAuthUIDelegate>
24+
/** @fn defaultUIDelegate
25+
@brief Unavailable. Please use initWithViewController:
26+
*/
27+
- (instancetype)init NS_UNAVAILABLE;
28+
29+
/** @fn initWithViewController:
30+
@brief Initializes the instance with a view controller.
31+
@param viewController The view controller as the presenting view controller in @c GOIUIDelegate.
32+
@return The initialized instance.
33+
*/
34+
- (instancetype)initWithViewController:(UIViewController *)viewController NS_DESIGNATED_INITIALIZER;
35+
@end
36+
37+
@implementation FIRAuthDefaultUIDelegate {
38+
/** @var _viewController
39+
@brief The presenting view controller.
40+
*/
41+
UIViewController *_viewController;
42+
}
43+
44+
- (instancetype)initWithViewController:(UIViewController *)viewController {
45+
self = [super init];
46+
if (self) {
47+
_viewController = viewController;
48+
}
49+
return self;
50+
}
51+
52+
- (void)presentViewController:(UIViewController *)viewControllerToPresent
53+
animated:(BOOL)flag
54+
completion:(nullable void (^)(void))completion {
55+
[_viewController presentViewController:viewControllerToPresent
56+
animated:flag
57+
completion:completion];
58+
}
59+
60+
- (void)dismissViewControllerAnimated:(BOOL)flag completion:(nullable void (^)(void))completion {
61+
[_viewController dismissViewControllerAnimated:flag completion:completion];
62+
}
63+
64+
+ (id<FIRAuthUIDelegate>)defaultUIDelegate {
65+
UIViewController *topViewController =
66+
[UIApplication sharedApplication].keyWindow.rootViewController;
67+
while (true){
68+
if (topViewController.presentedViewController) {
69+
topViewController = topViewController.presentedViewController;
70+
} else if ([topViewController isKindOfClass:[UINavigationController class]]) {
71+
UINavigationController *nav = (UINavigationController *)topViewController;
72+
topViewController = nav.topViewController;
73+
} else if ([topViewController isKindOfClass:[UITabBarController class]]) {
74+
UITabBarController *tab = (UITabBarController *)topViewController;
75+
topViewController = tab.selectedViewController;
76+
} else {
77+
break;
78+
}
79+
}
80+
return [[FIRAuthDefaultUIDelegate alloc] initWithViewController:topViewController];
81+
}
82+
83+
@end
84+
85+
NS_ASSUME_NONNULL_END

Firebase/Auth/Source/FIRAuthErrorUtils.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,20 @@ NS_ASSUME_NONNULL_BEGIN
451451
*/
452452
+ (NSError *)captchaCheckFailedErrorWithMessage:(nullable NSString *)message;
453453

454+
/** @fn webContextAlreadyPresentedErrorWithMessage:
455+
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeWebContextAlreadyPresented code.
456+
@param message Error message from the backend, if any.
457+
@return The NSError instance associated with the given FIRAuthError.
458+
*/
459+
+ (NSError *)webContextAlreadyPresentedErrorWithMessage:(nullable NSString *)message;
460+
461+
/** @fn webContextCancelledErrorWithMessage:
462+
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeWebContextCancelledcode.
463+
@param message Error message from the backend, if any.
464+
@return The NSError instance associated with the given FIRAuthError.
465+
*/
466+
+ (NSError *)webContextCancelledErrorWithMessage:(nullable NSString *)message;
467+
454468
/** @fn keychainErrorWithFunction:status:
455469
@brief Constructs an @c NSError with the @c FIRAuthErrorCodeKeychainError code.
456470
@param keychainFunction The keychain function which was invoked and yielded an unexpected

0 commit comments

Comments
 (0)