Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Auth] Use result type to wrap completion handlers internally #13563

Open
wants to merge 10 commits into
base: main
Choose a base branch
from

Conversation

ncooke3
Copy link
Member

@ncooke3 ncooke3 commented Aug 31, 2024

Follow-up to #13561

Use Swift's Result type enum to prevent cases where a completion handler is called with both non-nil or both nil.

#no-changelog

@@ -236,7 +236,7 @@ import Foundation
retryOnInvalidAppCredential: Bool,
multiFactorSession session: MultiFactorSession?,
uiDelegate: AuthUIDelegate?) async throws
-> String? {
-> String {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This return type bubbles up to the public API, which we need to make non-optional if possible, so this is why this is being changed to non-optional String.

@@ -16,7 +16,7 @@ import Foundation

@available(iOS 13, tvOS 13, macOS 10.15, macCatalyst 13, watchOS 7, *)
struct StartMFASignInResponse: AuthRPCResponse {
var responseInfo: AuthProtoStartMFAPhoneResponseInfo?
let responseInfo: AuthProtoStartMFAPhoneResponseInfo
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This diff should be a no-op in practice because the initializer will throw if it could not unwrap the value being assigned to responseInfo.

Comment on lines +18 to +22
let verificationID: String

init(dictionary: [String: AnyHashable]) throws {
verificationID = dictionary["sessionInfo"] as? String
guard let verificationID = dictionary["sessionInfo"] as? String else {
throw AuthErrorUtils.unexpectedResponse(deserializedResponse: dictionary)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally, this should be non-optional. I'm adding the error for cases where it's not. Are there success cases where verificationID should be nil?

Comment on lines +267 to +270
guard let sessionInfo = response.phoneSessionInfo?.sessionInfo else {
throw AuthErrorUtils.error(code: .missingMultiFactorInfo)
}
return sessionInfo
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here and below, we need to unwrap the underlying session info which is current an optional:

struct AuthProtoStartMFAPhoneResponseInfo: AuthProto {
var sessionInfo: String?
init(dictionary: [String: AnyHashable]) {
sessionInfo = dictionary["sessionInfo"] as? String
}
}

Throwing an error is new behavior here. I think this may be ok as long there aren't success cases where the sessionInfo should be nil?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The behavior changes made here map to this public API:

/// Verify ownership of the second factor phone number by the current user.
/// - Parameter phoneNumber: The phone number to be verified.
/// - Parameter uiDelegate: An object used to present the SFSafariViewController. The object is
/// retained by this method until the completion block is executed.
/// - Parameter 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, *)
open func verifyPhoneNumber(_ phoneNumber: String,
uiDelegate: AuthUIDelegate? = nil,
multiFactorSession: MultiFactorSession? = nil) async throws
-> String {

Is there a valid success case where the returned String should be nil (or an empty string) and the error is also non-nil? This PR enforces that it is either one or the other (non-optional String OR error).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants