I recently released version 2.12 of Sofa. That release brought new features, but more importantly, included a major refactoring of the app. This was triggered by two announcements at this year’s WWDC:
UITableViewwill eventually (soon?) be deprecated
99% of the views in Sofa were table views. Seeing the writing on the wall, I wanted to start tackling this right away. My path, though, wasn’t clear. Should I stick with UIKit and replace my table views with collection views or go in the SwiftUI direction? Either way I had to learn new APIs so I decided to take time to experiment.
Since SwiftUI is the future of Apple development, I initially chose this path. I wanted to time-box my efforts to a few weeks in case things didn’t work out.
I started building out the main parts of the app like Home and Lists. It was slow at first, but quickly sped up once I got more comfortable. I hit snags with theming and search, but was able to hack around those by diving into UIKit when necessary.
After a few weeks I was making, and seeing, good progress. This was so encouraging that I decided to go all in and rewrite the entire app in SwiftUI. For those of you with sense, you’ll see where this is headed 🙃.
After a few more weeks things started to get dicey. I was running into bugs and having major performance issues. I tried a lot of different things with the layout, data model, and more to improve performance, but it was clear that I couldn’t in good conscience ship this to people. The product would be noticeably worse.
Around late-August I decided I needed to abandon SwiftUI for now and jump back into UIKit. Instantly, my performance issues were gone and things were feeling smooth and snappy. Phew!
The downside was I had a steep learning curve ahead of me. Having to learn
UICollectionView with Compositional Layout was not trivial.
Again, up to this point, Sofa was driven by
NSFetchedResultsController to work with
UIDiffableDataSource was insanely confusing. There is so little documentation on this setup that at times I wasn’t sure it was possible or recommended.
Luckily the internet is amazing and I was able to piece together a solution by learning how to create a view model driven by
NSFetchedResultsController and then sync those changes with to my
UIViewController via Combine.
If there’s interest, I’m happy to write in more detail about the solution I went with. All I’ll say for now is that this setup works great.
UIDiffableDataSource is much more reliable to work with than messing directly with the
NSFetchedResultsController. Oh yea, Compositional Layouts are 🤯. Totally worth the pain of learning.
No way! I had to learn it to make widgets anyway and it had a couple of other benefits.
Since Combine is baked into SwiftUI with things like
@ObservableObject I was able to understand the basics fairly quickly. This made using Combine in UIKit much easier to understand and get working.
I experimented a lot with the new design and features in Sofa 2.12. Once I had my footing with SwiftUI, creating views was not only fast, but super fun. I was able to explore a bunch of ideas, with real data, and play with it on my devices. This blows every single design and prototyping tool out of the water.
I have so much gratitude for people who take the time to share their hard-won knowledge. Not only do they fill important gaps in Apple’s documentation, but they explain in ways that newbies like me can understand. Thank you!
These links helped me ship:
The detour was worth it, even if I had to double back more than I originally anticipated. The app is in a much more reliable and modern place than it was six months ago. Bonus, I got to learn more stuff!
My plan going forward is to stick with UIKit for the core parts of the app and sprinkle in SwiftUI where it makes sense.
If you want to see the fruits of my labor, you can download Sofa for free from the App Store.