How is your Thursday going?
iOS 15 GM is right around the corner, people are buzzing about last moment API changes and additions. And I'm here with some good old code improvement tips 😀👇
Waiting on multiple async calls
Have you seen code that's running multiple async calls in a loop, calling completion on the last item in the loop? Or counting the number of callbacks called? I've seen it a lot, and the last time has prompted me to share this tip 🙂
DispatchGroup allows you to wait on multiple async operations, as complex as they may be. The concept is simple: the dispatch group keeps track of how many tasks are outstanding (unfinished).
leave() calls increment and decrement the internal counter. Once the counter reaches zero, your custom closure is called. Here's a small example by @joemasilotti:
Conditional modifiers are bad? 😬
Are you using conditional modifiers in SwiftUI? I am 🙈 Folks at @objcio came out with a detailed explanations on why it's not such a good idea. SwiftUI uses the type system for diffing of state, and conditional modifiers such as
applyIf(...) break that.
The article also dives into why SwiftUI works the way it does, so check it out if you want to learn more: Why Conditional View Modifiers are a Bad Idea
Timers, scrolling, run loops
When you use
Timer.sheduledTimerscheduledTimer(withTimeInterval:...), it will not trigger while the user is interacting with a scroll view, or is performing any other touch-tracking interaction. The timer will continue after the interaction has ended. That's because this convenience method auto-schedules the timer in the
.default runloop mode, and the default mode doesn't check the timer during touch interactions.
If you want the timer to continue as normal during touch events, you'd have to init and schedule the timer with
.common mode manually:
RunLoop.current.add(timer, forMode: .common)
@qdoug shared a handy cheat-sheet for remembering which mode to use, as their names are super confusing:
Review the resources too
A fascinating anecdote shared by @krzyzanowskim. 98% of an app's size is icons, 11 MB each. That's nearly 1600x1600px. Why a png icon need to be this big? I bet this is not intentional, and these folks can reduce their app size at least 5x by including appropriately-sized images.
AKA this is a reminder to review the assets that are being introduced to the app, and not only code 🙃
Quick 2-in-1 tip
1) NSCache exists and is a good alternative to a plain dictionary when you want to cache non-trivially sized items
2) How feedback is delivered is extremely important. Simply being friendly goes a long way ✨
Alright, that’s it for today.
Did you enjoy this issue? Let me know by pressing the buttons below, so I can improve the newsletter.
Got feedback? Want to see more, or less of certain kinds of tips? I’d love to hear from you. Reply to this email or reach out on Twitter via @ios_code_review 🙌