Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Mind map your app (with notes)

Mind map your app (with notes)

My talk – with presenter notes – from NSBudapest meetup held as part of Craft Conf 2018 in Budapest, on May 10th.

If you need version without presenter notes:
https://speakerdeck.com/radianttap/mind-map-your-app

It's a short dive into a proper use of Coordinators and Layers architecture to really separate View Controllers into manageable, isolated units.

More Decks by Aleksandar Vacić (Radiant Tap)

Other Decks in Programming

Transcript

  1. M I N D - M A P Y O

    U R A P P A l e k s a n d a r Va c i ć @radiantav C R A F T 2 0 1 8 · N S B u d a p e s t Mind-mapping an app…”what the heck that even means”. I’d like to think of it as somewhat new approach to architecting an app. Or maybe it’s an old approach, dusted-out from the basement of programming. You decide what it is, at the end.
  2. App starts with an idea. A business plan would help

    too, but let’s not digress too much. App sprouts from an idea. I see a problem that I feel I have a good solution for.
  3. If you’re lucky to have a proper designer in the

    team, this rough phase is followed up wirefrmes, where you flesh-out the user stories.
  4. Then User Experience is detailed out, with layouts for each

    screen and transitions and connections between them.
  5. Finally look & feel is applied on top of the

    wireframes. So, we now need to code this up.
  6. UI / UX is done. The only thing left: code

    It is my firm belief that the best code is the code you don’t have to write nor maintain. Thus before jumping into Xcode, I first spend as many days as needed to plan code: data models, data flows, what each of those user stories and workflows needs to make them a reality. This is crucial high-level step as it helps to identify data types before you get deep into the boilerplate code required for collection views and what not.
  7. Some teams use post-it notes. It’s a..good tool..to figure out

    the details: where each screen fits inside the app, what initiates its display, what data is needed to display the content, is data coming (a)sync etc. After days of brainstorming and moving little colored paper slips here and there – now you know what View Controllers you need. Where you need to implement Delegate pattern so data can flow back. What VC will push which other controllers. What’s being presented as popup and when.
  8. Code is done. Really..? What’s left to do is the

    grunt work of actually writing all that code. It should be easy, peasy, now…right? If only. Heh…
  9. And why: because this is fiction. I don’t know a

    single, even moderately complex app that is this clean. I mean – just look at this lovely UX we have here. You have a home screen, views loads stuff in proper order: promo blocks, some content categories, nice browsing system; then somewhere along the line we will have Add-to-cart, display Cart, check Account status (and login if needed) then UX flow proceeds with Payment etc.
  10. HomeController ProductDetailsController ProductsController If you follow UIKit by the book,

    this means you will HomeController, which will instantiate & display ProductController and give it a list of Products. Where, after some cell tap, a ProductDetailsController will be instantiated and passed a single Product from the received list. Etc. You are happy, there’s a clear path how the app works. So you implement all this, beta 1 is ready and you send it off to all stakeholders for approval and to show off the progress. And then…
  11. They congratulate you and tell you that app needs to

    be able to jump directly to the Details screen all the way down here. You need to deep link a product and needs to be shown instantly after the app start. But, you may say, app needs to load the products list first, then to instantiate the intermediary VCs and fetch data sources and only then it can show the product…And they look at you, like “ok, yeah…?” Weather you manage to charge the client for that feature creep and change – you still need to do it. With the UIKit as it is, you will start to wing it. Most likely add some property called deepLinkProduct and then if it’s not nil DetailController will be pushed automatically onto UINC stack without even showing the Home and Products browse… Oh boy…
  12. Architecture of complex apps is ever evolving, quite often in

    unforseen ways. Then you follow it up with a Boolean flag here. Another property there. Few more ifs in the business logic of the app to accomodate another new user-flow that comes along. Over time you add far too many special cases. Your code is a mess where not even you can figure out all the code paths.
  13. – M A R T I N F O W

    L E R “Architectural refactoring is hard, and we’re still ignorant of its full costs, but it isn’t impossible.” Patterns of Enterprise Application Architecture Hence, quite possibly even before you reach ver 1.0, you may need to re-factor your app’s architecture. Depending on what comes up, this may be a partial or total rewrite. If you think – well, it can’t possibly go really, really bad… – think again.
  14. In order to avoid an insanity like this – that’s

    a real story, not fiction – you need an architecture that will allow re-factoring of any complexity. So: how to prepare yourself for any possible scope change in the project lifetime? In an app of any complexity? (Really infinite).
  15. O N I O N Your app needs to be

    an (Psst - I know this is garlic, but bear with me) Your app needs to be an onion. Lovely, beautiful onion with layers as thin as they can be, so if you add one or remove or replace one it does not break the overal structure. You need as composable architecture as possible, with ability to seamlessly plug-in layers that you need. Each layer should be self-contained, as much as possible.
  16. Data Delivery Data Source Data Storage You need: (1) data

    storage separated from data sourcing (2) data source separated from data delivery Because if you combine any of these domains, you are bound to get into a situation where you will repeat the same code in multiple places or be entirelly unable to implement a feature.
  17. Data Delivery Data Source Data Storage What’s Delivery mechanism? It

    can be network (URLSession) or it can be file(s) loaded from the Bundle. Or app’s sandbox. This layer have no idea what it deals with - it gets binary Data blob and transfer it to the Source layer. Source is usually an API. And another API. Or wrapper for a file hierarchy or chunks of data from socket streaming. It knows what Data blobs actually are converts them from Data into JSON or XML. Something that Data Manager can work with. Data Manager handles Storage which can be Realm or Core Data or in-memory store. This module convert the raw data formats into classes, structs and enums – your Model objects: Product, Cart, Item, Account, Customer, Song, Album etc. Anything that comprises your app’s internal data model.
  18. Data Delivery Data Source Data Storage UI Let’s look at

    UX flows from before. Everything is sort of fine… …until your controllers need to jump hoops. Add Product to Cart. 1-click buy which jumps to Payment. Etc. VC represented by just one independent post-it note is a lie, because it’s not independent, it’s glued, hard-wired with other VCs around it.
  19. Data Delivery Data Source Data Storage UI This pile of

    stuff is (one of) the reason for the so-called MassiveVC problem. The problem does not stop there though. What’s missing here..? Where are all the data paths between UI and Data – if I add them, this will turn into a ball of twine…
  20. N O T M Y FA U LT … H

    O N E S T ! It’s messy as hell.
  21. Data Delivery Data Source Data Storage UI All that wiring

    going in and out – that’s not the job for the UIViewController. Starting and instantiating UIVCs – that’s also not the job for the UIViewController. (This is why I can’t stand UISegue and wish I could burn it out of existence). UIKit is digging its own hole here. Let’s stop digging and first get rid of this mess… Every one of these boxes should be unaware of any other box. Your VCs should be entirely boxed-in. They take some data and use to display a view. They recognize significant actions inside the views and pass them along…to something else. They don’t care who is going to react to those actions – their job is to recognize them and pass them along, up the chain.
  22. Data Delivery Data Source Data Storage UI If VCs deal

    with just one task, they become small and manageable.
  23. Data Delivery Data Source Data Storage UI Content VCs shoud

    not care where they are. In NC, presented as popup, inside PageVC, they literally don’t know nor care. But someone else needs to handle these connections, something else should control the UX/data flow…
  24. Data Delivery Data Source Data Storage UI UI Coordinators …and

    that’s where Coordinators comes in. Their only job is to be the wiring between the global data store for the app and various views those data are shown in. Between the VCs. To move the data flow along. We have one more missing layer here…
  25. Data Delivery Data Source Data Storage UI UI Coordinators Middleware

    …which I call middleware managers. These are things like AccountManager which handles what Customer is currently logged in. CartManager which manages the one specific Order being built. Etc. This is the business logic of your app. Pay attention – this is not Core Data’s job. Data Storage is fairly simplistic, it reads and writes data but does not handle data transactions. For example: it knows to create an instance of some Customer object when requested to do so by AccountManager, which knows that this particular instance is specially important because it’s a logged-in Customer. DataManager could not care less, it creates the objects, passes it on and forgets about it. (Middleware sounds a lot like micro-services which are all the fancy in web backend world right now).
  26. If you manage to separate all this, then you don’t

    need colored post-it notes. You can mind-map in code, no intermediary prototyping tools required. Code Mapping, enabled by… (If you manage…) (You can mind-map…) You just need Xcode and your knowledge of Swift and UIKit. (Code Mapping…)
  27. L AY E R S A R C H I

    T E C T U R E So let me introduce you to my implementation of LAYERS architecture with middleware and a special kind of Coordinator implementation. I promise you it is really this yummy, unlike the onions. Or garlic.
  28. • Coordinator
 Swift implementation of Coordinator pattern, with several advanced

    features • Swift-Network
 Thin URLSession wrapper which allow seamless usage with Operation and OperationQueue • Swift-Essentials
 Various useful extensions, particularly AsyncOperation subclass of Operation github.com/radianttap It’s loose puzzle of several Swift micro libraries, all available on my GitHub repository. … Instead of showing you dry code and explaining those libraries which may take an hour or so, I’m going to show them in action. Which I hope will be enough to pick your interest and then you’ll figure them out on your own.
  29. Let’s demo this approach by code- mapping a bespoke Spotify

    app… in 15-ish minutes ! " #$ Let’s DEMO…
  30. Aleksandar Vacić radianttap.com Follow me as @radiantav on Twitter. Read

    my iOS dev blog at aplus.rs. Use my open source stuff on GitHub.com/radianttap. Photos (from Unsplash) by • delfi de la Rua • Otto Norin • Mike Kenneally