UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

SwiftUI App Tab View Freezes after Network Request

Forums > SwiftUI

There are basically 3 screens in the application, these are splash screen, auth screen and app screen.In Root View, it shows the splash screen first and then directs it to auth or app according to the user status. Here I am making a network request while looking at the user's status. But after I do this, I direct the user to the app screen and the Tab view in the App Screen does not work, it freezes. When i press and hold on tab item tab view works but when i click it doesn't work.

Network Request Code:

func fetchWithURLRequest<T: Decodable>(_ urlRequest: URLRequest) -> AnyPublisher<T, Error> {
        URLSession.shared.dataTaskPublisher(for: urlRequest)
        .mapError({ $0 as Error })
        .flatMap({ result -> AnyPublisher<T, Error> in
            guard let urlResponse = result.response as? HTTPURLResponse, (200...299).contains(urlResponse.statusCode) else {
                return Just(result.response)
                    .tryMap({ response in
                        if let urlResponse = response as? HTTPURLResponse {
                            let apiError = APIError(statusCode: urlResponse.statusCode)
                            throw apiError
                        } else {
                            throw APIError(statusCode: 0)
                        }
                    }).eraseToAnyPublisher()
            }
            return Just(result.data).decode(type: T.self, decoder: JSONDecoder()).eraseToAnyPublisher()
        })
        .receive(on: DispatchQueue.main)
        .eraseToAnyPublisher()
    }

I'm using this network request in this ViewModel Class:

class RootViewModel: ObservableObject {

    @Published var containedView: ContainedView = .splash
    @Published var protectedError = false
    var isError = false

    var cancellables = Set<AnyCancellable>()
    let apiService = APIService()
    let keychain = KeychainSwift()

    func checkIsAuth() {
        if Auth.auth().currentUser == nil {
            DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
                withAnimation {
                    self.containedView = .auth
                }
            }
        } else {
            self.getUserInfo()
        }
    }

    func getUserInfo() {
        let userID = keychain.get("userId") ?? ""
        Route.sharedInstance.urlComponent.path = Route.Path.getUserInfo.rawValue
        Route.sharedInstance.urlComponent.queryItems = [
            URLQueryItem(name: "user_id", value: userID)
        ]

        var urlRequest = URLRequest(url: Route.sharedInstance.urlComponent.url!)
        urlRequest.addValue("Bearer \(BEARER_TOKEN)", forHTTPHeaderField: "authorization")

        let publisher: AnyPublisher<User, Error> = apiService.fetchWithURLRequest(urlRequest)

        publisher.sink(receiveCompletion: { (completion) in
            if case .failure(let error) = completion,
                let _ = error as? APIError {
                self.containedView = .auth
            }
        }) { (user) in
            CurrentUser.addCurrentUser(user: user)
                withAnimation {
                    if !user.protected {
                        if !self.isError {
                                self.containedView = .app
                        } else {
                            self.containedView = .auth
                        }
                    } else {
                        self.protectedError = true
                    }
                }
        }
        .store(in: &cancellables)
    }
}

I'm using View Model in View of this screen:

enum ContainedView {
    case splash, auth, app
}

struct RootView: View {

    @ObservedObject var rootVM = RootViewModel()

    var body: some View {
        ZStack {
            containedView()
                .transition(.slide)
        }
        .onAppear {
           NotificationCenter.default.addObserver(forName: NSNotification.Name("signOut"), object: nil, queue: .main) { (_) in
                self.rootVM.containedView = .auth
           }
            self.rootVM.checkIsAuth()
        }
        .popup(isPresented: $rootVM.protectedError, type: .`default`, closeOnTap: false) {
            PopUpView(title: "Oops!", imageName: "protected_account", description: "To use this app, you must be having public account") {
                self.rootVM.protectedError = false
                self.rootVM.containedView = .auth
            }
        }
    }

    func containedView() -> AnyView {
        switch rootVM.containedView {
        case .splash: return AnyView(SplashView().id("splash"))
        case .auth: return AnyView(AuthView().environmentObject(TwitterService()).id("auth"))
        case .app: return AnyView(AppView().id("app"))
        }
    }

And the app screen:

struct AppView: View {

    init() {
        UITabBar.appearance().barTintColor = UIColor(named: "BackgroundBlue")
    }

    var body: some View {
        TabView {
            InspectedView().tabItem {
                Image(systemName: "eye")
                Text("Inspected")
            }.tag(0)
            ProfileView().tabItem {
                Image(systemName: "house")
                Text("Profile")
            }.tag(1)
            MoreView().tabItem {
                Image(systemName: "ellipsis")
                Text("More")
            }.tag(2)
        }
        .accentColor(.white)
    }
}

2      

TAKE YOUR SKILLS TO THE NEXT LEVEL If you like Hacking with Swift, you'll love Hacking with Swift+ – it's my premium service where you can learn advanced Swift and SwiftUI, functional programming, algorithms, and more. Plus it comes with stacks of benefits, including monthly live streams, downloadable projects, a 20% discount on all books, and free gifts!

Find out more

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.