代码之家  ›  专栏  ›  技术社区  ›  alionthego

在SwiftUI中,如何根据异步调用确定要显示的视图

  •  0
  • alionthego  · 技术社区  · 3 年前

    当我的应用程序第一次出现时,我试图通过一个异步调用来控制它的流量,以查看用户是否登录。

    如果这个调用是同步的,我可以做一个简单的切换,或者确定要显示的视图。

    但我不知道如何处理基于异步请求的流。到目前为止,这是我所做的,但更改state变量并不会更改显示的视图。以下内容在app file@main function中:

    enum LoginStatus {
        case undetermined
        case signedIn
        case signedOut
    }
    
    @main
    struct SignUpApp: App {
        
        @State var loginStatus: LoginStatus = .undetermined
        
        public init() {
            getLoginStatus()
        }
        
        var body: some Scene {
            WindowGroup {
                switch loginStatus {
                case .undetermined:
                    Text("SigningIn")
                case .signedIn:
                    EnterAppView()
                case .signedOut:
                    LoginView()
                }
            }
        }
        
        func getLoginStatus() {
            someAsyncFunctionToGetSignInStatus { result in
                DispatchQueue.main.async {
                    switch result {
                    case .success:
                        self.loginStatus = .signedIn
                    case .failure:
                        self.loginStatus = .signedOut
                    }
                }
                
            }
        }
    }
    

    我想这是一项常见的任务,我想知道处理它的最佳方式是什么。

    0 回复  |  直到 3 年前
        1
  •  1
  •   jnpdx    3 年前

    您的想法是正确的,但通常使用异步调用时,您可能会希望将它们移动到ObserveObject中,而不是将它们放在视图代码本身中,因为视图在SwiftUI中是瞬态的(尽管异常可能是顶层的) App 就像你一样)。

    class SignInManager : ObservableObject {
      @Published var loginStatus: LoginStatus = .undetermined
      
      public init() {
            getLoginStatus()
      }
    
      func getLoginStatus() {
            someAsyncFunctionToGetSignInStatus { result in
                //may need to use DispatchQueue.main.async {} to make sure you're on the main thread
                switch result {
                case .success:
                    self.loginStatus = .signedIn
                case .failure:
                    self.loginStatus = .signedOut
                }
            }
        }
    } 
    
    @main
    struct SignUpApp: App {
        
        @StateObject var signInManager = SignInManager()
    
        var body: some Scene {
            WindowGroup {
                switch signInManager.loginStatus {
                case .undetermined:
                    Text("SigningIn")
                case .signedIn:
                    EnterAppView()
                case .signedOut:
                    LoginView()
                }
            }
        }
    }
    
        2
  •  0
  •   Turki Alqarni    3 年前

    枚举登录状态{ 案件未定 案例签名 案例签名输出 }

    @主要的 struct SignUpApp:App{

    @State var loginStatus: LoginStatus = .undetermined
    
    public init() {
        getLoginStatus()
    }
    
    var body: some Scene {
        WindowGroup {
            switch loginStatus {
            case .undetermined:
                Text("SigningIn")
            case .signedIn:
                EnterAppView()
            case .signedOut:
                LoginView()
            }
        }
    }
    
    func getLoginStatus() {
        someAsyncFunctionToGetSignInStatus { result in
            DispatchQueue.main.async {
                switch result {
                case .success:
                    self.loginStatus = .signedIn
                case .failure:
                    self.loginStatus = .signedOut
                }
            }
            
        }
    }
    

    }