Adrian
Adrian

Reputation: 20058

Initialize ViewModel with defaults values

I have the following code for a simple ViewModel with which I want to update 3 labels:

struct State {
    var timeLabelText: String?
    var timeLabelHidden: Bool
    var dayLabelText: String
    var dateLabelText: String
}

class ViewModel {
    var state: State = State(timeLabelText: nil, timeLabelHidden: true, dayLabelText: "Day 0", dateLabelText: "June 19, 2017") {
        didSet {
            callback(state)
        }
    }

    var callback: ((State) -> Void)

    init(callback: @escaping (State) -> Void) {
        self.callback = callback
        callback(state)
    }

    var date: String {
        get {
            let dateFormatter = DateFormatter()
            dateFormatter.dateStyle = .long

            return dateFormatter.string(from: Date())
        }
    }
}

This will initialize my UI with the default values from the State. But for the dateLabelText I want to initialize it with the actual date, before the UI is displayed.

Where is the right place to do this ? Should I just go and do it inside the ViewModel initializer ?

init(callback: @escaping (State) -> Void) {
    self.callback = callback
    state.dateLabelText = date  // add this here 
    callback(state)
}

Upvotes: 0

Views: 603

Answers (1)

GetSwifty
GetSwifty

Reputation: 7746

I would suggest making it a static property:

class ViewModel {
    var state: State = State(timeLabelText: nil, timeLabelHidden: true, dayLabelText: "Day 0", dateLabelText: ViewModel.date) {
        didSet {
            callback(state)
        }
    }

    var callback: ((State) -> Void)

    init(callback: @escaping (State) -> Void) {
        self.callback = callback
        callback(state)
    }

    static private var dateFormatter: DateFormatter = {
        let dateFormatter = DateFormatter()
        dateFormatter.dateStyle = .long
        return dateFormatter
    }()

    static var date: String {
        get {
            return dateFormatter.string(from: Date())
        }
    }
}

Note that I also separated out the dateFormatter so it's only initialized once. Creation of DateFormatters is a relatively expensive operation that shouldn't be repeated unless necessary.

Also be aware that with your approach the date will be different every time it's accessed. This type of functionality may be better described as a function rather than a property.

Upvotes: 1

Related Questions