mazyod
Passionate Developer! Loves games, Elixir, and cats.
... and how to define them
🤔
🧐
🛠
@objc public let error: NSError?
@objc public let serverErrorCode: String?
@objc public let serverErrorDesc: String?
@objc public let serverErrorFields: [String: Any]?
public enum Domain: Equatable {
case unknown
case connection
case url(String)
case backoff
case server(ErrorDTO)
}
Problem
final class XYZ {
private var dispatchGroup: DispatchGroup? = nil
func doStuffThenProceed() {
dispatchGroup = DispatchGroup()
functionA()
if condition {
functionB()
}
...
dispatchGroup.notify {
self.proceed()
}
}
}
Solution
final class XYZ {
private let operationQueue = OperationQueue()
func doStuffThenProceed() {
var operations: [Operation] = []
operations.append(functionA())
if condition {
operations.append(functionB())
}
...
let completion = {
self.proceed()
}
operations.forEach {
completion.addDependency($0)
operationQueue.add($0)
}
OperationQueue.main.add(completion)
}
}
// before
private func loadMixpanelToggles() {
toggleDispatchGroup.enter()
togglesLoadedOrTimedOut = false
Mixpanel.mainInstance().joinExperiments {
if self.togglesLoadedOrTimedOut == false {
self.togglesLoadedOrTimedOut = true
self.toggleDispatchGroup.leave()
}
}
DispatchQueue.main.asyncAfter(deadline: .now() + ...) {
if self.togglesLoadedOrTimedOut == false {
self.togglesLoadedOrTimedOut = true
self.toggleDispatchGroup.leave()
}
}
}
// after
private func loadMixpanelToggles() -> Operation {
return BlockOperation {
let semaphore = DispatchSemaphore(value: 0)
Mixpanel.mainInstance().joinExperiments {
semaphore.signal()
}
semaphore.wait(timeout: .now() + ...)
}
}
By mazyod
What are boundaries in software development? How should we work with them?