Reusability in view layer (An iOS architecture part III)

The aim of this post is to reinforce the reusability in view layer, it will be presented a way to handle the fonts (and its sizes), colours, texts translations and accessibility labels (for automated UI tests).

This post is the continuation of  the view layer (an iOS architecture part ii) and part of it is based on the following presentation but supported with a sample project in case you want further investigation or adopt the technics explained in your projects.

The view layer (An iOS architecture part II)

Fonts (and its sizes)

For better folder organization we have placed the font files into ViewLayer/Resources/Fonts:
☝️Do not forget add the resource to project target:

Also do not forget to add the fonts also in the Info.plist:

Edit the Info.plist and add the following chunk of xml:

The helper for the font sizes is placed at ViewLayer/Resources/Styles:

For each presenter we have defined an structure that gathers the fonts that is using, this approach lets you have centralised in a unique file the font definitions for WHOLE app:

I let the reader to download the sample project and review the rest of structures contained in the file for further understanding.

Finally for setting the file in the outlet is as simple as:

And the result is the following:

Colors

For colors we will use the same approach as in fonts, define a helper in Styles folder:

As well as in fonts  we will define the palette of colours used as well as the palette-dolors used by each presenter:

Finally for setting the color in the @IBOutlet:

And the result is the following:

Texts

We have just created a string extension for automatically handle the translation depending on the project language bundle:

For avoiding the problem of text identifiers during execution time, we use R.Swift so during compilation time we will know if resource really exists or not. This is also very useful for images, cell reusability, segue identifiers… In that way you will avoid bugs related with identifiers that do not match with the resource. 🚑 Really, do not hesitate in incorporate this pod in your projects!!!!

Finally for set the texts is as easy as:

Even that constants has 6 elements in the keypath, 5 of them are always constant: R.string.localizable.<textId>.key.localized

Accessibility labels

iOS developer will not get direct benefit in setting accessibility labels to @IBOutlets, but when there  is a test team for handling UI tests we have to facilitate their job. In return we will have quick and precise bug reporting. All in all this will save you time in middle-long term.

As well as in fonts and colors, we will create a new module that will concentrate all accessibility constants:

With the following structure:

Finally for applying accessibility to @IBOutlet:

Conclusion

With this and previous post we consider the view layer of the architecture already presented. If you have any doubt, and you can download the source sample project from here.

What’s next

In the next post will be presented the Domain Layer and how View Layer interacts with it using UseCases (Interactors in Viper) and Coordinators.

References:

 

     

The view layer (An iOS architecture part II)

This is the continuation of the following post, the aim of the view layer (an iOs Architecture part II), is just to explain in detail how view layer will be built.

The view layer

When you were working on development tasks related purely related with view just shift your mind to the following schema:

The schema is almost MVP, almost because in some concrete cases does not fit (we will see later on). But the main components are views and presenters, and its role is practically the same

Views

Views are the classes responsible of drawing the information in the screen of device. The input of this class is the model to printout and the output the events that view can not handle.

The events can be handled via:

  • Delegate protocol.
  • Callbacks.

In the implementation project I have used callbacks.

For instance if a view hast to print out a list of persons, as soon as view receives an array of persons will print out the list. When user taps on one of the persons, view catches the event, but does not know what to do with it, so bypasses the event to its parent presenter.

Composite views 🙄. Is quite common that a view will be complex enough to be splited in subviews. In the previous example, figure it out that now we want to print out also a header and a footer on the persons lists. The view will have access to its subviews, and as soon as receives the model from the presenter it will bypass also the models to its subviews. When one of its subviews will receives a user action, depending on the situation, will handle it or will bypass it to its parent presenter.

Heterogeneous Composite Views😣. I will start directly with the example, figure it out the home view of a very famous application like Spotify, LinkedIn, Facebook… In the same screen is presented several sections each one presenting information not related with the other sections.

Could your tell the number of lines for this presenter? Who would be the super-hero in case that some change would be required in the home screen? This is a clear smelt that MVP is not enough for such implementation🤔.

In case of such kind of complex views or in case that we want to reuse the same section views in two (or more) different screens the pattern that we use is MVPP (or MVP+). The idea is as simple as a view will be the container of another presenter (with its own views).

Every (sub)presenter will fetch data from business and will pass it to its views, this will help a lot in reducing the size of the main (super)presenter. Another great advantage of this pattern is that allows to reuse the presenter-view in some other screen.

 

Presenters

Presenter is the abstract representation of a screen app, it has direct access to its views. Its role is quite clear fetch/pass data from/to Business (Domain and Data) layer on one hand and in the other transfer information between views and handle the events reported by views.

For a presenter its views are black boxes, at no moment the presenter knows if what is being drawn is a tableview, a collection view, a pageviewcontroller…. It transfer Models  to view, and wait for the events that view can not handle.

As well as in views, there are some events that even a presenter can not handle, for instance if user presses a button for dismissing the app screen view. In such case the presenter will bypass the event to its coordinator, … but this will be explained in Domain layer (part III).

Implementation

The Presenter will be implemented as a subclass of a UIViewController, whilst for View we have two alternatives UIView or UIViewController. I prefer to use UIViewController, mostly because is easier to control the lifecycle of the view. But If you do not have to, there’s no problem in using UIView.

The project app just present two screens, and heterogeneous composite view and a simple view.

Home screen is a presenter of presenters and the second one is just a presenter. As you can see popular presenter has been reused in the home, this is why is so powerful this model presenter plus protocol.

Simple presenter (Popular).

The presenter is subclassed from UIViewController this allows us to represent it in the storyboard. The view could be subclassed from:

  • UIView. UIViews is the class implementation for handling views, so why not…
  • UIViewController. With UIViewController we have the extra that we can handle the view lifecycle much better than with a UIView.

In the story board the view is embedded in the presenter with a container view:

This is the implementation for the presenter:

In the prepare segue is where is handled the event that is coming from the view, and is bypassed to UseCase (… but this is domain part II).

🚫View could also call the UseCase and the compiler did not complain, but this is totally forbidden in this architecture🚫. Remember 3-tier layer philosophy.

And the view simply:

Print out the model and send back the button event.

Composite presenter (Home).

The Home presenter is a presenter of presenters, the unique case that has to do the superpersenter is just show/hide the sub presenters. But in the case of the implementation both are presented. The storyboard shows pretty clear the super-presenter (at the top), its container view that will hold the subcontainers for placing the presenter for the latest popular place and the most popular place.

The home presenter implementation:

And its view container:

Conclusion

In this post I have presented how to structure view layer using presenters and views. Finally the idea has been supported using a example project, the source code can be found here.

What’s next…

View layer is not finished yet, in the next post I will present how to handle font types (and its sizes), colours, accessibility labels (for automated testing) and localised texts (for translations).