Swift main thread style I run into issues where I forget to run UI changes on the main thread. 

I've just fixed an issue for loading and unloading an activity indicator and fixed it with the following code:

if active {
    DispatchQueue.main.async {
        UIApplication.shared.keyWindow?.startIndicatingActivity()
    }
} else {
    DispatchQueue.main.async {
        UIApplication.shared.keyWindow?.stopIndicatingActivity()
    }
}


Now an alternative is this code:

DispatchQueue.main.async {
    if active { UIApplication.shared.keyWindow?.startIndicatingActivity()
    } else { UIApplication.shared.keyWindow?.stopIndicatingActivity() 
    }
}


Now which one is right / more maintainable for the future?
From a processing efficiency perspective, they are largely indistinguishable. But if I were forced to choose between these two approaches, I might lean towards the latter, wrapping the whole if-else test in a single dispatch to the main queue, for two reasons:


There is a timing issue: 

Let’s assume you ran this from a background thread and active was false, so you asynchronously dispatch the activity indicator update back to the main queue. What if, by the time the main queue gets to the dispatched block, that active is now true? Do you still really want to turn off the activity indicator? No, you almost certainly want to treat the combined test of active and the corresponding updating of the activity indicator as a single operation.
There is a thread safety issue:

When dealing with this boolean (and I’m assuming it’s a simple boolean, not wrapped in some synchronization mechanism), you should think about how you ensure thread-safe access to it. One really should synchronize access to one’s properties when writing multi-threaded code, and the first approach makes it unclear from which thread are you retrieving active (much less from which thread(s) is it being updated). One very simple synchronization technique to ensure that all reads and writes to active are done on the main queue, which, by virtue of being a serial queue, ensures thread-safety.




A few observations regarding other possible patterns/considerations: 


You might want to consider whether, rather than writing a routine that you manually call to check active and update the activity indicator accordingly (meaning that every time you update active, you have to remember to call this routine), whether you might prefer to just supply the active property an observer that does the updating of the activity indicator for you. If you can have your property automatically trigger the UI update, then it eliminates the possibility of them getting out of sync.
There are special concerns if the changes to active are happening very quickly:


First, if active changes are happening extremely quickly (e.g. thousands of times per second), you risk flooding the main queue. You can address these sorts of issues with things like dispatch sources.
Second, even if it’s only a couple of times per second, you might want to avoid starting and stopping the activity indicator too quickly (because it yields a spinner that is constantly restarting, yielding a “Max Headroom” style of stuttering effect). For example, if active changes every ¼ second, and keeps doing that for 10 seconds, you may want to just want to keep the spinner going for that full 10 seconds, not starting and stopping it repeatedly. You can accomplish this by programming some latency in the “stop activity indicator” routine. E.g. when active is set to false, add non-repeating timer to stop the activity indicator in ½ second, but only after canceling any prior timer, if any. Likewise, when active is set to true, only “start” the activity indicator if you know it’s not already started.&nbsp;


Bottom line, be aware that the right implementation might depend upon the frequency of changes.