Michael
Michael

Reputation: 2089

SwiftUI and MVVM design pattern

I am trying to get my head round how i can achive the following using the MVVM design pattern with SwiftUI.

I want to have only 1 instance of a networking operation queue (using OperationQueue) where any view model that needs to send any networking requests but i have heard that creating a Singleton is not preferred and i should be passing the networking queue object around where it is needed.

So if i create the instance of the network operation queue in the Scene Delegate and pass them into the ContentView initialiser and store it in an object there to then pass into the views then created.

This doesnt seem like good MVVM design practice as from what i understand the View should Own the ViewModel only?

What is the best way of achieving this?

Edit: thought a bit more about this and I can pass it into the view via its constructor and then within the constructor I can create the view model and pass it straight through so the view doesn’t own anything.

But I still will require a singleton so how can I pass the singleton as a dependency injection rather than using it globally?

Upvotes: 3

Views: 2031

Answers (1)

rfarias
rfarias

Reputation: 1406

We shouldn’t create singletons for the single reason of being an easy way to get global variables, but it doesn’t mean we should never use them.

In your case, if I understood correctly, you are basically creating a service that can be used by the entire application. You could either A) create a reusable class with the networking functions you need (and instantiate anywhere you need it) or B) create a class with a singleton instance in it, that can be easily accessed anywhere.

A singleton would be a better choice if you need to keep some state common to all callers, or if you need to maintain a waiting queue, for example.

Option A

class NetworkService {

    init() {
        // init
    }

    // Your properties and methods
    func someFunction() {}
}

Usage in a ViewModel:

let networkService = NetworkService()
networkService.someFunction()

Option B

class NetworkService {
    static let shared = NetworkService()
    private let queue : Any?

    // Your properties and methods
    func someFunction() {}
}

Usage:

NetworkService.shared.someFunction()

Either way, this is still MVVM. The data is not related to any specific view, nor to a specific model; it's simply a service you would call in any ViewModel that needs it.

Upvotes: 5

Related Questions