Home > AI > IOS > SwiftUI >

the difference between init and onAppear

The order is
– View’s init()
– EnvironmentObject init (that’s why you cannot access home in View’s init()
_ onAppear() ( called after view rendering)

The example code is:

HomeGlobal.swift

import Foundation
import SwiftUI


class HomeGlobal: ObservableObject{
    // this -> UserDefaults
    // UserDefaults -> this
    @Published var userIsLogged: Bool = UserDefaults.standard.bool(forKey: UserDefaultsKeyEnum.userIsLogged.rawValue) {
        didSet {
            UserDefaults.standard.setValue(self.userIsLogged, forKey: UserDefaultsKeyEnum.userIsLogged.rawValue)
        }
    }
    
    func updateValues() {
        userIsLogged = UserDefaults.standard.bool(forKey: UserDefaultsKeyEnum.userIsLogged.rawValue)
    }
    
}


enum UserDefaultsKeyEnum: String {
    case userIsLogged
}

ContentView.swift

import SwiftUI

struct ContentView: View {
    @EnvironmentObject var home: HomeGlobal
        
    init() {
        
    }
    
    var body: some View {
        Group {
            if home.userIsLogged {
                Text("Content View")
            } else {
                Text("Login in View")
            }
        }
        .padding()
        .background(home.userIsLogged ? Color.orange : Color.blue)
        .onAppear {
            UserDefaults.standard.setValue(true, forKey: UserDefaultsKeyEnum.userIsLogged.rawValue)
        }
    }
}

For this example, you can see the home.userIsLogged is not updated immediately. But if you remove the code in onAppear to init, the bug would be fixed.

Leave a Reply