ManWithBear

Thinking out loud - Pet project series - 3/x

Just ignore me

Last week we agreed on going with a manual layout. That means our views / controllers are not gonna be instantiated through a NSCoder -> init(coder:) is useless right now. But the compiler doesn't know about our decision and complains about missing implementations.

For such use cases I have a handy code snippet up my sleeve:

@available(*, unavailable, message: "This class can not be used in the Interface Builder")
required init?(coder: NSCoder) { fatalError("This class can not be used in the Interface Builder") }

Putting it together

I started to implement an ingredients list table with a collection view (logic...huh). And man! How I enjoy working with a "new" UICollectionViewCompositionalLayout.

At first glance, it may look java-level-bloated, but nothing that a couple of extensions couldn't fix :D

On second look, creating grid layouts has never been easier.

Oh and just look at this beauty:

NSCollectionLayoutGroup documentation

Hide it under a rug

Probably the only feature I miss in Swift right now are namespaces (scopes for identifiers to prevent name collisions).

One way to achieve namespace-like behaviour is by using nested types, e.g.:

enum Layouts { }
extension Layouts {
   struct MagicLayout { }
}

Layouts.MagicLayout() vs MagicLayout()

For smaller projects it's a question of tidiness and things being in their place.

On bigger projects it's common to have naming issues, when you spend too much time to come up with a name for a thing, cauz you cannot just call it TheThing (well you can, but just once). But if you already have domain specific namespaces, random TheThing becomes domain specific as User.TheThing, Layout.TheThing or whatever you came up with.

Call me anytime

People tend to put every piece of logic, every single function into some class / struct. Maybe it's a way to avoid "a dirty singleton" bad practices. Or maybe it's thinking something like: "OOP will solve all our problems".

I personally find small pure functions super handy. Especially if you combine them with namespaces from above.

For example, new compositional layouts can be just one global function as:

enum CollectionLayouts { }
extension CollectionLayouts {
    enum List {
        static func make() -> UICollectionViewLayout {
            ...
            return UICollectionViewCompositionalLayout(section: ...)
        }
    }
}

let collectionView = UICollectionView(frame: .zero, collectionViewLayout: CollectionLayouts.List.make())

Consuming package

As you remember, SPM is unable to build iOS apps, so we need to create a separate demo project that would add the package as a dependency.

Luckily, Xcode is able to add local dependencies if you use file:// schema:

file:///Users/{username}/broken_dreams/path_to_project/TheProject

If you want to know how it all started, I got you: Starting Pet project series 0/x | ManWithBear

See ya!

Tagged with: