Essential snippets for Swift-based iOS apps
Let the language work for you
Swift is wonderfully expressive, succinct yet readable. The ease with which you can extract commonly repeated behavior and functionality, brought a whole new level of enjoyment to my day to day work.
Swift-Essentials is small set of micro-libraries that illustrate this.
Here are some highlights…
Foundation
In just about any app, I need to access application’s name, version and build. Either I’m using them as part of the User-Agent HTTP header or simply to show them in some About view, I need easy access to these values:
static var userAgent: String = {
let osName = UIDevice.current.systemName
let osVersion = UIDevice.current.systemVersion
let deviceVersion = UIDevice.current.model
let locale = Locale.current.identifier
return "\( Bundle.appName ) \( Bundle.appVersion ) (\( Bundle.appBuild )); \( deviceVersion ); \( osName ) \( osVersion ); \( locale )"
}()
Are you scared of making a mistake doing Date calculations? You should be. Stand on the shoulder of people who already dealt with all that craziness and enjoy the fruits of their work:
let now = Date()
let startOfYesterday = now.subtract(days: 1).beginningOfDay()
Controllers
I use Storyboards as glorified .xib
s:
- one (or two) UIViewControllers per storyboard.
- I copy the name of UIVC subclass as
Storyboard ID
I then easily instantiate any such UIVC from code:
let vc = LoginController.initial()
let other = ForgotPassController.instantiate()
I tend to simplify maintenance of complex UIs by making custom container controllers, which means I’m doing the embed dance fairly often:
let vc = AdsController()
embed(controller: vc, into: adsContainerView)
self.adsVC = vc
...
unembed(adsVC)
adsVC = nil
Views
I build UI for my Table/Collection cells in separate .xib files and then register them where needed. This means I need easy way to make nib instance and make subclasses reusable regardless of them being xib-based or not.
final class SearchCell: UICollectionViewCell, ReusableView {...}
final class PersonCell: UICollectionViewCell, NibReusableView {...}
Finally, I need the simplest way to register the subclass with UITV or UICV:
func viewDidLoad() {
collectionView.register(SearchCell.self)
collectionView.register(PersonCell.self)
}
and dequeue it:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell: SearchCell = collectionView.dequeueReusableCell(forIndexPath: indexPath)
}
· · ·
These files are meant to be copied directly into your project and updated often, built upon by you.
Hence no Carthage, CocoaPods & friends. There are few more of these in the GitHub repo, I’ll write about them soon.