Skip to content

Commit

Permalink
[auth-swift] Add Objective C API build tests
Browse files Browse the repository at this point in the history
  • Loading branch information
paulb777 committed Nov 20, 2023
1 parent 9a3ea6f commit 8dbf4e4
Show file tree
Hide file tree
Showing 12 changed files with 715 additions and 65 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import Foundation
/** @property iOSBundleID
@brief The iOS bundle ID, if available. The default value is the current app's bundle ID.
*/
public var iOSBundleID: String?
@objc public var iOSBundleID: String?

/** @property androidPackageName
@brief The Android package name, if available.
Expand Down Expand Up @@ -84,7 +84,7 @@ import Foundation
androidMinimumVersion = minimumVersion
}

@objc public func setIOSBundleID(_ bundleID: String) {
public func setIOSBundleID(_ bundleID: String) {
iOSBundleID = bundleID
}
}
51 changes: 30 additions & 21 deletions FirebaseAuth/Sources/Swift/Auth/Auth.swift
Original file line number Diff line number Diff line change
Expand Up @@ -560,25 +560,17 @@ extension Auth: AuthInterop {
uiDelegate: AuthUIDelegate?,
completion: ((AuthDataResult?, Error?) -> Void)?) {
kAuthGlobalWorkQueue.async {
let decoratedCallback = self.signInFlowAuthDataResultCallback(byDecorating: completion)
provider.getCredentialWith(uiDelegate) { rawCredential, error in
if let error {
Task {
let decoratedCallback = self.signInFlowAuthDataResultCallback(byDecorating: completion)
do {
let credential = try await provider.credential(with: uiDelegate)
let authData = try await self.internalSignInAndRetrieveData(
withCredential: credential,
isReauthentication: false
)
decoratedCallback(authData, nil)
} catch {
decoratedCallback(nil, error)
return
}
guard let credential = rawCredential else {
fatalError("Internal Auth Error: Failed to get a AuthCredential")
}
Task {
do {
let authData = try await self.internalSignInAndRetrieveData(
withCredential: credential,
isReauthentication: false
)
decoratedCallback(authData, nil)
} catch {
decoratedCallback(nil, error)
}
}
}
}
Expand Down Expand Up @@ -1170,7 +1162,7 @@ extension Auth: AuthInterop {
asynchronously on the main thread in the future.
*/
@available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *)
@objc public func verifyPasswordResetCode(_ code: String) async throws -> String {
public func verifyPasswordResetCode(_ code: String) async throws -> String {
return try await withCheckedThrowingContinuation { continuation in
self.verifyPasswordResetCode(code) { code, error in
if let code {
Expand Down Expand Up @@ -1594,7 +1586,7 @@ extension Auth: AuthInterop {
kAuthGlobalWorkQueue.sync {
self.requestConfiguration.emulatorHostAndPort = "\(formattedHost):\(port)"
#if os(iOS)
self.settings?.isAppVerificationDisabledForTesting = true
self.settings?.appVerificationDisabledForTesting = true
#endif
}
}
Expand Down Expand Up @@ -1667,6 +1659,23 @@ extension Auth: AuthInterop {
This case will return `nil`.
Please refer to https://github.com/firebase/firebase-ios-sdk/issues/8878 for details.
*/
@objc(getStoredUserForAccessGroup:error:)
public func __getStoredUser(forAccessGroup accessGroup: String?,
error outError: NSErrorPointer) -> User? {
do {
return try getStoredUser(forAccessGroup: accessGroup)
} catch {
outError?.pointee = error as NSError
return nil
}
}

/** @fn getStoredUserForAccessGroup
@brief Get the stored user in the given accessGroup.
@note This API is not supported on tvOS when `shareAuthStateAcrossDevices` is set to `true`.
This case will return `nil`.
Please refer to https://github.com/firebase/firebase-ios-sdk/issues/8878 for details.
*/
public func getStoredUser(forAccessGroup accessGroup: String?) throws -> User? {
var user: User?
if let accessGroup {
Expand Down Expand Up @@ -1717,7 +1726,7 @@ extension Auth: AuthInterop {
}
}

@objc public func canHandle(_ url: URL) -> Bool {
@objc(canHandleURL:) public func canHandle(_ url: URL) -> Bool {
kAuthGlobalWorkQueue.sync {
guard let authURLPresenter = self.authURLPresenter as? AuthURLPresenter else {
return false
Expand Down
14 changes: 11 additions & 3 deletions FirebaseAuth/Sources/Swift/Auth/AuthSettings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,25 @@ import Foundation
/** @property appVerificationDisabledForTesting
@brief Flag to determine whether app verification should be disabled for testing or not.
*/
@objc public var isAppVerificationDisabledForTesting: Bool
@objc public var appVerificationDisabledForTesting: Bool
@objc public var isAppVerificationDisabledForTesting: Bool {
get {
return appVerificationDisabledForTesting
}
set {
appVerificationDisabledForTesting = newValue
}
}

override init() {
isAppVerificationDisabledForTesting = false
appVerificationDisabledForTesting = false
}

// MARK: NSCopying

public func copy(with zone: NSZone? = nil) -> Any {
let settings = AuthSettings()
settings.isAppVerificationDisabledForTesting = isAppVerificationDisabledForTesting
settings.appVerificationDisabledForTesting = appVerificationDisabledForTesting
return settings
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import Foundation
@param completion Optionally; a block which is invoked asynchronously on the main thread when
the mobile web flow is completed.
*/
@objc(getCredentialWithUIDelegate:completion:)
@objc optional
func getCredentialWith(_ UIDelegate: AuthUIDelegate?,
completion: ((AuthCredential?, Error?) -> Void)?)

Expand All @@ -37,6 +37,7 @@ import Foundation
@param UIDelegate An optional UI delegate used to present the mobile web flow.
*/
@available(iOS 13, tvOS 13, macOS 10.15, watchOS 8, *)
@objc(getCredentialWithUIDelegate:completion:)
func credential(with UIDelegate: AuthUIDelegate?) async throws -> AuthCredential
#endif
}
7 changes: 3 additions & 4 deletions FirebaseAuth/Sources/Swift/AuthProvider/OAuthProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -181,11 +181,10 @@ import CommonCrypto
/** @fn getCredentialWithUIDelegate:completion:
@brief Used to obtain an auth credential via a mobile web flow.
This method is available on iOS only.
@param UIDelegate An optional UI delegate used to present the mobile web flow.
@param uiDelegate An optional UI delegate used to present the mobile web flow.
@param completion Optionally; a block which is invoked asynchronously on the main thread when
the mobile web flow is completed.
*/
@objc(getCredentialWithUIDelegate:completion:)
public func getCredentialWith(_ uiDelegate: AuthUIDelegate?,
completion: ((AuthCredential?, Error?) -> Void)? = nil) {
guard let urlTypes = auth.mainBundleUrlTypes,
Expand Down Expand Up @@ -256,10 +255,10 @@ import CommonCrypto
/** @fn getCredentialWithUIDelegate:completion:
@brief Used to obtain an auth credential via a mobile web flow.
This method is available on iOS only.
@param UIDelegate An optional UI delegate used to present the mobile web flow.
@return An `AuthCredential`.
@param uiDelegate An optional UI delegate used to present the mobile web flow.
*/
@available(iOS 13, tvOS 13, macOS 10.15, watchOS 8, *)
@objc(getCredentialWithUIDelegate:completion:)
public func credential(with uiDelegate: AuthUIDelegate?) async throws -> AuthCredential {
return try await withCheckedThrowingContinuation { continuation in
getCredentialWith(uiDelegate) { credential, error in
Expand Down
31 changes: 21 additions & 10 deletions FirebaseAuth/Sources/Swift/AuthProvider/PhoneAuthProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,10 @@ import FirebaseCore
factor challenge.
@param completion The callback to be invoked when the verification flow is finished.
*/

@objc(verifyPhoneNumber:UIDelegate:multiFactorSession:completion:)
public func verifyPhoneNumber(_ phoneNumber: String,
uiDelegate: AuthUIDelegate? = nil,
multiFactorSession session: MultiFactorSession? = nil,
multiFactorSession: MultiFactorSession? = nil,
completion: ((_: String?, _: Error?) -> Void)?) {
guard AuthWebUtils.isCallbackSchemeRegistered(forCustomURLScheme: callbackScheme,
urlTypes: auth.mainBundleUrlTypes) else {
Expand All @@ -93,9 +92,11 @@ import FirebaseCore
kAuthGlobalWorkQueue.async {
Task {
do {
let verificationID = try await self.internalVerify(phoneNumber: phoneNumber,
uiDelegate: uiDelegate,
multiFactorSession: session)
let verificationID = try await self.internalVerify(
phoneNumber: phoneNumber,
uiDelegate: uiDelegate,
multiFactorSession: multiFactorSession
)
Auth.wrapMainAsync(callback: completion, withParam: verificationID, error: nil)
} catch {
Auth.wrapMainAsync(callback: completion, withParam: nil, error: error)
Expand All @@ -104,6 +105,16 @@ import FirebaseCore
}
}

/**
@brief Verify ownership of the second factor phone number by the current user.
@param phoneNumber The phone number to be verified.
@param uiDelegate An object used to present the SFSafariViewController. The object is retained
by this method until the completion block is executed.
@param multiFactorSession A session to identify the MFA flow. For enrollment, this identifies the user
trying to enroll. For sign-in, this identifies that the user already passed the first
factor challenge.
@returns The verification ID
*/
@available(iOS 13, tvOS 13, macOS 10.15, watchOS 8, *)
public func verifyPhoneNumber(_ phoneNumber: String,
uiDelegate: AuthUIDelegate? = nil,
Expand Down Expand Up @@ -135,12 +146,12 @@ import FirebaseCore
@objc(verifyPhoneNumberWithMultiFactorInfo:UIDelegate:multiFactorSession:completion:)
public func verifyPhoneNumber(with multiFactorInfo: PhoneMultiFactorInfo,
uiDelegate: AuthUIDelegate? = nil,
multiFactorSession session: MultiFactorSession?,
multiFactorSession: MultiFactorSession?,
completion: ((_: String?, _: Error?) -> Void)?) {
session?.multiFactorInfo = multiFactorInfo
multiFactorSession?.multiFactorInfo = multiFactorInfo
verifyPhoneNumber(multiFactorInfo.phoneNumber,
uiDelegate: uiDelegate,
multiFactorSession: session,
multiFactorSession: multiFactorSession,
completion: completion)
}

Expand Down Expand Up @@ -181,7 +192,7 @@ import FirebaseCore

private func internalVerify(phoneNumber: String,
uiDelegate: AuthUIDelegate?,
multiFactorSession session: MultiFactorSession? = nil) async throws
multiFactorSession: MultiFactorSession? = nil) async throws
-> String? {
guard phoneNumber.count > 0 else {
throw AuthErrorUtils.missingPhoneNumberError(message: nil)
Expand All @@ -194,7 +205,7 @@ import FirebaseCore
}
return try await verifyClAndSendVerificationCode(toPhoneNumber: phoneNumber,
retryOnInvalidAppCredential: true,
multiFactorSession: session,
multiFactorSession: multiFactorSession,
uiDelegate: uiDelegate)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import Foundation
This class is available on iOS only.
*/
@available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *)
class PhoneMultiFactorAssertion: MultiFactorAssertion {
@objc(FIRPhoneMultiFactorAssertion) public class PhoneMultiFactorAssertion: MultiFactorAssertion {
var authCredential: PhoneAuthCredential?

init() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import Foundation
*/
@objc(assertionWithCredential:)
public class func assertion(with phoneAuthCredential: PhoneAuthCredential)
-> MultiFactorAssertion {
-> PhoneMultiFactorAssertion {
let assertion = PhoneMultiFactorAssertion()
assertion.authCredential = phoneAuthCredential
return assertion
Expand Down
23 changes: 10 additions & 13 deletions FirebaseAuth/Sources/Swift/User/User.swift
Original file line number Diff line number Diff line change
Expand Up @@ -496,15 +496,14 @@ extension User: NSSecureCoding {}
uiDelegate: AuthUIDelegate?,
completion: ((AuthDataResult?, Error?) -> Void)? = nil) {
kAuthGlobalWorkQueue.async {
provider.getCredentialWith(uiDelegate) { credential, error in
if let error {
Task {
do {
let credential = try await provider.credential(with: uiDelegate)
self.reauthenticate(with: credential, completion: completion)
} catch {
if let completion {
completion(nil, error)
}
return
}
if let credential {
self.reauthenticate(with: credential, completion: completion)
}
}
}
Expand Down Expand Up @@ -837,16 +836,14 @@ extension User: NSSecureCoding {}
uiDelegate: AuthUIDelegate?,
completion: ((AuthDataResult?, Error?) -> Void)? = nil) {
kAuthGlobalWorkQueue.async {
provider.getCredentialWith(uiDelegate) { credential, error in
if let error {
Task {
do {
let credential = try await provider.credential(with: uiDelegate)
self.link(with: credential, completion: completion)
} catch {
if let completion {
completion(nil, error)
}
} else {
guard let credential else {
fatalError("Failed to get credential for link withProvider")
}
self.link(with: credential, completion: completion)
}
}
}
Expand Down
Loading

0 comments on commit 8dbf4e4

Please sign in to comment.