PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Monday, October 17, 2022

[FIXED] How to return to "View Parent" from ASWebAutheticationSession

 October 17, 2022     aswebauthenticationsession, macos, oauth, swift, swiftui     No comments   

Issue

How to return from the ASWebAutheticationSession completion handler back to the View?

Edit: Just for clearance this is not the original code in my project this is extremely shortened and is just for showcasing what I mean.

Here's an example of a code

struct SignInView: View {
    
    @EnvironmentObject var signedIn: UIState
    
    var body: some View {
        let AuthenticationSession = AuthSession()
        AuthenticationSession.webAuthSession.presentationContextProvider = AuthenticationSession
        AuthenticationSession.webAuthSession.prefersEphemeralWebBrowserSession = true
        AuthenticationSession.webAuthSession.start()
    }
}

class AuthSession: NSObject, ObservableObject, ASWebAuthenticationPresentationContextProviding {
    var webAuthSession = ASWebAuthenticationSession.init(
        url: AuthHandler.shared.signInURL()!,
        callbackURLScheme: "",
        completionHandler: { (callbackURL: URL?, error: Error?) in
            
            // check if any errors appeared
            
            // get code from authentication

            // Return to view to move on with code? (return code)
        })

    func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor {

        return ASPresentationAnchor()
    }

}

So what I'm trying to do is call the sign In process and then get back to the view with the code from the authentication to move on with it.

Could somebody tell me how this may be possible? Thanks.


Solution

Not sure if I'm correctly understanding your question but it is normally done with publishers, commonly with the @Published wrapper, an example:

import SwiftUI
import Combine

struct ContentView: View {
    @ObservedObject var viewModel = ViewModel()
    
    var body: some View {
        VStack {
            Button {
                self.viewModel.signIn(user: "example", password: "example")
            }
            label: {
                Text("Sign in")
            }
            
            if self.viewModel.signedIn {
                Text("Successfully logged in")
            }
            else if let error = self.viewModel.signingError {
                Text("Error while logging in: \(error.localizedDescription)")
            }
        }
        .padding()
    }
}

class ViewModel: ObservableObject {
    @Published var signingStatus = SigningStatus.idle
    
    var signedIn: Bool {
        if case .success = self.signingStatus { return true }
        
        return false
    }
    
    var signingError: Error? {
        if case .failure(let error) = self.signingStatus { return error }
        
        return nil
    }
    
    func signIn(user: String, password: String) {
        self.dummyAsyncProcessWithCompletionHandler { [weak self] success in
            guard let self = self else { return }
            
            guard success else {
                self.updateSigning(.failure(CustomError(errorDescription: "Login failed")))
                return
            }
            
            self.updateSigning(.success)
        }
    }
    
    private func updateSigning(_ status: SigningStatus) {
        DispatchQueue.main.async {
            self.signingStatus = status
        }
    }
    
    private func dummyAsyncProcessWithCompletionHandler(completion: @escaping (Bool) -> ()) {
        Task {
            print("Signing in")

            try await Task.sleep(nanoseconds: 500_000_000)
            
            guard Int.random(in: 0..<9) % 2 == 0 else {
                print("Error")
                completion(false)
                return
            }
            
            print("Success")
            completion(true)
        }
    }
    
    enum SigningStatus {
        case idle
        case success
        case failure(Error)
    }
    
    struct CustomError: Error, LocalizedError {
        var errorDescription: String?
    }
}


Answered By - Marc Biosca
Answer Checked By - Pedro (PHPFixing Volunteer)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing