Question

I need to use DispatchQueue within controller and pass it as dependency. This is what I have tried so far and worked out two solutions. Need to ask what is better and in common use by other developers:

protocol DispatchQueuerable: class {
    func perform(withDelay delay: Double, block: @escaping () -> Void)
    func performAsync(block: @escaping () -> Void)
}

First solution:

class DispatchQueuer: DispatchQueuerable {
    private let queue: DispatchQueue
    init(queue: DispatchQueue) {
        self.queue = queue
    }
    func perform(withDelay delay: Double, block: @escaping () -> Void) {
        queue.asyncAfter(deadline: .now() + delay as DispatchTime, execute: block)
    }
    func performAsync(block: @escaping () -> Void) {
        queue.async {
            block()
        }
    }
}

Second solution:

extension DispatchQueue: DispatchQueuerable {
    func perform(withDelay delay: Double, block: @escaping () -> Void) {
        asyncAfter(deadline: .now() + delay as DispatchTime, execute: block)
    }
    func performAsync(block: @escaping () -> Void) {
        async {
            block()
        }
    }
}

My question is what is better approach to avoid tight coupling in code and use MVVM Archtecture properly:

How do I use them?

First solution:

let queuer = DispatchQueuer(queue: DispatchQueue.main)
MyViewController(queuer: queuer)

class MyViewController: UIViewController {
    private let queuer: DispatchQueuer
    init(queuer: DispatchQueuer) {
        self.queuer = queuer
    }
}

Second solution:

let queue = DispatchQueue.main
MyViewController(queue: queue)

class MyViewController: UIViewController {
    private let queue: DispatchQueue
    init(queue: DispatchQueue) {
        self.queue = queue
    }
}

I really like the FIRST solution and know it, but what do you think about that?

Was it helpful?

Solution

Before I come to your actual question I'd like to mention that the difference of your two solutions wasn't easy to find out for me by starting to look at how to use your MyViewController class. Then I figured out that you are using two classes with very similar names. From my point of view the name of your class DispatchQueueris much to close to DispatchQueue. You should definitely find another name for it.

Concerning your question about the coupling of your solutions I would say it depends. The compile time dependencies are equal. Still the functional dependency to the DispatchQueuerable protocol is more obvious to the user of your MyViewControllerclass in your first solution. Opposed to this the to second solution using the extension somehow introduces a hidden dependency to the protocol (depending on where you put the source code of the extension). Still this solution is the more swifty way of doing it and an experienced Swift developer will probably prefer this solution while any OO developer will easily be able to follow your first solution.

OTHER TIPS

Most certainly opt for the latter. One of Swift's greatest strengths is its support for retroactive modelling. Take advantage of it.

In Swift, you basically never have to use the wrapper design pattern, because you can just make existing types conform to new protocols.

Licensed under: CC-BY-SA with attribution
scroll top