The Domain layer (An iOS architecture part IV)

The aim of this post is just to explain how to organise the domain layer in an architecture. A possible definition of domain layer is where the application business logic is implemented, or the told in the contrary way what is nor view neither data acquisition.

The domain layer is the fuzzy invisible border between View and Data layer. But as app grows in complexity (and in lines of code) is the cornerstone of your development, so this is why is important to have this layer under control.

Components

Sequencer

The sequencer is the component that will handle the start up sequence, this is something thats starts very simple at the beginning of the implementation, but as time (and requirements) goes on could turn into a really nightmare 🎃. You can find the implementation details in the following post.

Managers

Managers is the wrapper class for accessing to a unique device services like bluetooth, maps, gyroscope… Or in case that you wanted  to centralize a behaviour in a single class, for instance, a Session Manager for controlling wether a user was logged properly or not. This class is a singleton implementation.

Up to here this is good about this component. But watch out, to start abusing them! Is quite common that will start appear singletons as mushrooms. I recommend to read the following post.

Use Cases

Use cases functions are the entry point for any functionality requested by views.  The reason for living of this component lies in:

  • Unload task from views. Helps to reduce Massive View Controllers problem.
  • Reusability. Is likely that you use the same functionality from different views.
  • TDD. You can apply unit test to this function class.

Coordinators

Coordinators controls the flow of screens presented, is the coordinator who decides which is the next screen to present, not the view any longer…

This will help to reduce the amount of code to put in the view, and also its reusability, the same view can be placed in a totally different screen flow.

Use cases and coordinators working together but not mixed

Presenters interacts with use cases when some functionality has to be performed (e.g request data from a service, try to connect to a bluetooth device, get a map pinpoints,…). But in case that presenter considers that is no more longer usable (e.g. user select dismiss button to remove the view, or selected an item for pushing another view with the item details) it has to interact with the coordinator and will be the coordinator who will decide  which is the next view to present.

Conclusion

In this post we have reviewed which is the role of Domain layer and its components.

What’s next

In the next post will be presented the Data Layer and how to retrieve data independently where is phicially stored (ddbb, service, keychain, user defaults… ).

     

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).

     

An iOS app architecture (Part I)

An iOS app architecture

The aim of this post (and the followed ones) is to expose an iOS app architecture that I have been using for developing iOS apps during last two years. In the end is not strictly one of the known ones: VIPER, MVVM, MVP…, but obviously with many commons concepts.

What is an architecture?

From wikipedia: Software architecture refers to the high level structures of a software system, the discipline of creating such structures, and the documentation of these structures. These structures are needed to reason about the software system. Each structure comprises software elements, relations among them, and properties of both elements and relations.[1] The architecture of a software system is a metaphor, analogous to the architecture of a building.[2]

In practice a software architecture allow to absorb the product owner requirements without increasing your app source code complexity. If does not, start to refactor before is too late.

Outlining the architecture

As a professional painter we have to outline the available canvas and decide which functionaly will be implemented in each part.

Once done, now is crystal-clear which part will be occupied by fingers, palm and wrist.

Moving to software engineering, I am talking about 3-tier architecture model, this model has been used for in other technologies (e.g web, client-server). It splits the app in 3 layers (View, Domain, Data), its philosophy is very clear:

  • Each layer has a very concrete purpose
  • Each layer has a defined interface for requesting its implemented services.
  • A layer can only interact with its adjacent one.

Rule number I. Visualize mentally that each component (and its subcomponents) from your architecture as an apartment in a building. A component can only interact with its immediate upper and lower components floor. If you want to go from 4th floor to 2nd one, you have go through 3rd.

For instance if we want to present ddbb query result in a view:

🚫 🙅 Forbidden. Access directly from a view to a database handler to make a request. Comming in to iOS context, figure out that you get the realm ddbb handler and implements the query from the ViewController that will present the results.

✅The approach. Define one interface method in the Data and Domains layer that returns the requested data (e.g. in form of array) to the view, so View layer unique responsibility is draw the data returned by domain layer.

With this simplistic example, Domain layer does nothing apart from calling Data layer, you would think that this layer is redundant, but truly believe me it is not. If some data processing has to be done, Domain layer is the place.

From this rule you will get the following benefits:

  • Use TDD for validating Domain and Data layers with unit tests
  • Reduce the number of code-lines in the view (Massive ViewControllers problem).

Rule II. No-shared responsibility. Every component has a concrete responsibility and no other component can perform it, but the designated one.

For instance in our app we have different screens and each one is presented information retrieved from a rest service.

🚫 🙅 Forbidden. Implement in every view the service call for retrieve the data to present.

✅The approach. Place all the service calls in a component, as this component is retrieving data, it will be placed in the Data layer. So the view will request to domain the rest data, and domain will request to data layer, finally the data will be returned to view via domain.

From this rule you will get the following benefits:

  • Use TDD for validating a component with a concrete responsibility.
  • In case that some component fails (e.g rest api’s), we have to review a file, not bunch of scattered code in all project.
  • Reduce the number of code-lines in the view (Massive ViewControllers problem).

The architecture

As you can see in the architecture block schema, there are from 5 up 7 seven levels, so is essential that each component only interacts with its upper and lower components.

iOS app architecture

The exception that confirms the rule

There is one case that Rule II will be overridden, and is the case when two (or more view are presenting some information) and this information is updated/deleted from Data Layer. In this case the presenters get subscribed to data events broadcasted by Data Manager, and when presenter gets the notification then fetchs for the latest data to present.

iOS app architecture

Implementation

iOS app architecture

Basically the implementation is an almost empty project, with the basic folder organisation for holding different layers ant its components that matches with architecture presented:

We have added a very basic app start up sequence, is very important to keep this part of code under a tight control, leave only necessary code in AppDelegate.swift:

InitAppSequencer is the responsible for the start up sequence, this class dispatches the different operations needed during start up app sequence.

Up to this moment the unique task (operation) that app must do is just present the main screen.

If you want to know more about sequencers you can find in my pot post Design iOS app start up sequence (with Operations)

Pods

The pods that highly recommend and will improve dramatically the quality of your code are:

  • R.Swfit. Get strong typed, autocompleted resources like images, fonts and segues in Swift projects
  • Swiftlint. A tool to enforce Swift style and conventions

You can download the code used in this post from here.

Conclusion

In this post has been presented the layered structured of this architecture and the rules that governs the communication between each component.

What’s Next

In the next posts will be presented in detail: View, Domain and Data layer.

References

 

     

Design iOS app start up sequence (with Operations)

The aim of this post is just to propose a design pattern for implementing the start up sequence for an iOS App. When Coordinator pattern is not enough for your app needs, then  is time to move to a upper level of abstraction.

The reality

Lets pretend that we want to develop an iOS that allows us to compose music and  connect to a bluetooth speaker to play our creations. At the beginning the start up sequence coordinator just presents the main screen. But as the sprints are passing by, the product owner ask to implement the following requirements during the start up sequence:

  • Autoconnect to default speaker. During start up process, the app  tries to autoconnect to last connected speaker. When the app has never been connected to one, is presented a coordinator with an assistant for scanning and connect to any surrounding bluetooth speaker.
  • Force update. The app checks from a service whether can continue or require a user to update the app.
  • Tutorial. When the app has a new release or is the first time app execution is presented the tutorial slider.
  • Country/Language detection. In the first time app execution is set the language according device automatically, if language is not available then is presented to user a list with the languages supported by the app.
  • Push notifications. When the user presses on the push notification alert message, the app is started up presenting a view showing more details about the notification. On dismissing the view, appears the main app view.
  • Present a customized splash screen with an animation.
  • AutoLogin/Login/Create account. When user was previously logged in, the app request a rest service for a token_id that will be used in further rest api’s calls. Otherwise is presented an assistant for entering credentials or create a new account.
  • …Last but not least, start up sequence can not take much longer (no more than 3  secs.), when no user interaction is required.

If an sprint takes 2 weeks, Could you figure out how messy was the start up coordinator passed four months? … yes it was 😨

Why a coordinator is not enough (for this case)

A Coordinator, as well known as Router in VIPER,  is a great pattern for removing presenter the knowledge about which is the next presenter to show (Great… less lines in the ViewController 🎉). The presenters logic flow now is concentrated in a single class and second presenters can be reused by other flows. There are two articles that talks about coordinators, I highly recommend them (Coordinators Redux and An iOS Coordinator pattern)

But times goes by and oncoming features are integrated in the app start up sequence, the number of lines will start to grow and code become harder to understand. Not using coordinator pattern would have been hundred times worst 🤡.

This pattern does not fit in our start up sequence, basically because we were forcing to put in the same flow tasks that could be splited in different flows and in some cases can be launched in parallel. Is clear that I need a another point of view.

Design iOS app start up sequence

From now on, for avoiding naming mistakes we will call Sequencer to our brand new supercoordinator.

REQUIREMENTS

First of all,  we have to split the start up sequence in independendent isolated operations. The start up sequence does not have to be unique, depending on the context we have several dependency graphs.

TASKS DEPENDENCY SCHEMA

First time execution

s1

This is the worst case scenario because all operations must be serialised, the unique operations that can be parallelised are Present Splash (PS) and Force Update (FU). Fetch Configuration depends on PS because in case that did not exist country configuration for country device is presented a UI menu, so it is mandatory to wait until PS finishes for using the UI.

The rest of operations, login (LOG), tutorial (TUT), connect first speaker (CFS) must be serialised because requires user input.

Forze update (FU) has no dependency, because when update is required it will abort all the operation sequence.

Regular start up sequence

In this scenario: the country, the auto login information and also there is a known speaker to connect is known by the app, so all those operations can be parallelised.

s2

This is the best case scenario up to 5 operations can be launched in parallel.

Push notification start up sequence

s0
The unique difference between this an previous scenario is that with that using that pattern you can replace easily replace Tutorial (TUT) operation by Present push information (PPI) operation.

OPERATIONS LAUNCHER

Operations (NSOperations previously also known) is a mechanism for parallelizing tasks on iOS. Is very useful when the app has to do a lot of massive and repetitive taks, like for example fetch images from a server and present them on a collection view. This really removes the dust from device cpu cores 🚀.

Another great advantage that provide us Operations is that is direct to define depenendencies between tasks, so tasks will be executed in the order defined by the dependency graph.

An operation can be cancelled so in case that Force update requires to update the app, it can cancel the rest of operations and take control of UI.

🖐️ I highly recommend to view Advanced NSOpetations (WWDC 2015)

IMPLEMENTATION

This is the implementation of first time execution:

This is incomplete, because the point is to dynamically build the task dependency depending on the scenario that app starts up.

An operation would be something like this:

For understanding concurrent operation, please take a look at Ray Wenderlich video AsyncOperations

TESTING

For validating the sequencer is as easy as creating a unit test that validates the dependencies between operations in the deferents scenarios that app can start up.

And for validating an operation, just add completion block to the operation. The test will launch the operation, and the unit test will be executed in the completion block. In case of tutorial the unit test will validate is (or not) the topViewController, and DataManager has knowledge that has been presented and does not have to be presented next time (unless the app will be updated to upper version)

Conclusion

We have tried to demonstrate the approach presented is more accurate than Coordinator pattern when we want to sequence (and paralelize) something as heterogenous as a start up sequence.

References

     

Swifting a Mock Server (with Vapor)

The aim of this post is put up the level of previous post (Testing at the edge of your App with a Mock Server), just by using Vapor (a swift backend framework) and deploying server with Heroku (a cloud platform that lets companies build, deliver, monitor and scale apps).

Setup the environment

Vapor

For installing vapor backend framework just:

For creating a new vapor project, afterwards create a new git repository with the stuff generated and finally open the project:

Up to this point you will have XCode with new project:

stp

Run the project, open your favourite browser and type the url http://localhost:8080

browser

Mock server is working on local ?. Ready for getting to next level? ?

Heroku

If you do not have an account just sign up here. Later on, download Heroku command line tools, for validating installation just type (restart computer if necessary).

….finally after several minutes the mock server is deployed on a remote site, just type https://mock-vapor.herokuapp.com/ in your browser.

browser2

Implementing a dummy service

Our mock server will return .json, first thing to do is setting  content-type.  Just update View.swift extension:

Validate with any rest analyzer:

post

Adding basic fixer answer. This is what our mock servier will answer:

latest_FORCE_BUSINESS_ERROR is just a json template file.

The client App

The client app will be exactly the same presented in previous post, but obviously replacing urls.n In this case we will use three schemas:

  • Local mock server. For debugging with local mock server.
  • Remote mock server. For working with common development mock server.
  • Fixer real server. For working with final service.

Select Local mock server schema and launch the test:

tr

Deploy the mock server

At the moment there is nothing by typing https://mock-vapor.herokuapp.com/latest in the remote server:before

For deploying just push changes:push

This process can take several minutes… ?

push2

But finally we have the remote with latest, at this moment, just type: https://mock-vapor.herokuapp.com/latest. The remote server is ready!

after

Switch mock remote server

Switch oclient Mock Server Schema to lauch the tests on the client, but this time bouncing to a remote mock server.

rs

Conclusion

With this post you have seen how to deploy a remote mock server. You can use this server as a test platform or you could develop your app backend. If you were interested in investigating more you can fetch source code from here.

Useful links

     

Testing at the edge of your App with a Mock Server

The aim of this post is to just present how to build a simple mock server for validating the service calls on your iOS app with unit tests. The components that contains the service calls are at the edge our app and usually are not validated mostly because it is assumed that api is working fine, but this is not always true…

 

The mock server will respond with a controlled response and will also help you to simulate several error status responses or even delays on answers. Android and Windows phone platforms can also take profit on it.  The server will be implemented in node.js, but do not get scared, there is no need a lot of knowledge on this technology.

The server is mocking fixer public API service, and in concrete the following rest API http://api.fixer.io/latest?base=USD

What’s node.js?

Node.js is an open-source, cross-platform Javascript runtime environment for developing a diverse variety of tools and applications. For installing on your mac just type the following commands in your terminal:

Express  is a web application framework for Node, this will facilitate our task for developing our http server. For writing code, there are many text editors (sublime2atom,…) , but I recommend Visual Studio Code (VSC) because it allows you to debug the code.

The mock server

With VSC just open localMockServer folder, go to debug and press the play button.

vsc

Open your internet browser and type http://localhost:3080/latest in the url, if mock server was started well you should have to see something like this:

resp

Developing iOS service component

Once we have an answer from the server let start to develop the iOS service component. For doing that we will create a simple single view app, please do not forget include support for unit testing.

sva

For network service support I will use Alamofire pod, this is what it was AFNetworking in Objective-C.

For switching between real Fixer server and our mock server I will create a new schema and inside it I will define an environment variable for controlling which baseURL hast to be returned.

sch

baseURL attribute will be calculated in the following way:

Remember, from now on we will work with mock server so switch to FixerClient-MockServer schema.

sch2

The service implementation is the following:

The second function parameter is optional and only will be used for notifying server which test scenario we want to run. At the moment there are two error test cases, one for reproduce a server error and another for reproducing a business error (json with unexpected structure basically).

Unit testing our iOS app service component

The unit test implementation for forcing business error is the following:

After the rest of unit tests implementation just launch the test:

te

 

Conclusion

With the mock server all your business layer can be validated using unit testing and will isolate your development from backend. For doing this sample project I have used cocoapods 1.1.1 and XCode 8.1. You can download the code here.

Links

     

Scratching image table view controllers

The aim of this post is showing how to fix choppy tableviews when they are showing huge images fetched from the cloud.

 

The App

The app is very simple, just a table view that shows a collection of pictures.

Simulator Screen Shot 28 Aug 2016 17.03.55

The app presents the following problems:

  • The picture size is huge so the scroll must be smooth.
  • There is a high memory consumption, so iOS quick the app out.
  • The pictures are fetched every time that a cell is being presented (not cached).
  • Fetch is not cancelled once the cell is not shown in the tableview due to scroll.

filesizes

The picture resolution is 6144 x 4096.

 

The classical approach

Tableviews (and scrollviews) scroll must be smooth. User would not detect app bandwidth consumption easily, but a bumpy scroll is detected from the very beginning. Here what we have to do is to be sure that image is fetched in background and, once is retrieved, update image view in the main thread.

This is how a regular cell should have to be configured:

 

Memory consumption

But memory consumption increases in a dramatic (deadly) way:

MemoryConsumption

When you access the NSData, it is often compressed (with either PNG or JPEG). When you use the UIImage, there is an uncompressed pixel buffer which is often 4 bytes per pixel (one byte for red, green, blue, and alpha, respectively). There are other formats, but it illustrates the basic idea, that the JPEG or PNG representations can be compressed, when you start using an image is uncompressed.

This model does not work at all with huge pictures, it is  necessary to work with a different architecture.

The image provider

We will delegate the  work of fetching and processing the image to a image provider class. Every cell will has its own image provider.

imageprovider

We will create the image provider in tableview willDisplayCell method:

It could be the case that cell will dissapear before image provider ends its tasks. You can cancel the operation done by image provider.

In my case I was not interested in doing that because it was highly likely to get back to the dissapeared cell.

Cache the downloaded stuff.

At the end is only necessary to download the image once, not every time that cell is going to be shown. We have implemented this by using NSCache object, this differs from other mutable collections in a few ways:

  • It incorporates various auto-removal policies, which ensures that it does not use too much system memory.
  • You can access from different threads without having to lock the cache yourselve.
  • Retrieving something from an NSCache object returns an autoreleased result.
  • Unlike an NSMutableDictionary object, a cache does not copy the key objects that are put into it.

Profile new architecture

With new architecture the memory consumption lasts in that way:

newmetrics

Awesome, It has been reduced memory consumption by 60!!!

 

Conclusion

There are times that is not under app developer the image size of images that has to fetch. If you use the classical approach then you will find that tableview scroll is choppy and most probaly OS will kick the app out. For avoiding such disgusting issue this architecture fits properly well. You can find the source code here.

     

Validating View Controllers with Quick and Nimble

On arriving  UI automated testing in XCode 7 developers had a great tool for automatically validate our apps.  But as our test suite starts growing we start facing some inconveniences.

By using accessibility interface you cannot validate view controller attributes, for instance validate if you got the right number of cells in a collection. Another problem that I faced was at time of refactoring test cycles took to long.

I strongly believe in testing, but dealing with such inconveniences  pushed me to search for another iOS test frameworks. After watching some videos and hearing about them in some conferences I decided to investigate about validating view Controllers with Quick and Nimble.

The aim of this post is just show how to setup Quick and Nimble test frameworks and play a little bit with them.

Quick and Nimble

Quick is a BDD testing frakework that is almost the same as XCTest, but with the additional focus on describing your intent and why you are testing parts of your code.

Nimble allows you to express expectations using a natural, easily understood language.

Environment

I have found some difficulties downloading sample projects with the framework integrated. So at the time of writing this posts the XCode that I am using is 7.3.1 and the Podfile content is the following:

View controller undertest

The view controller under test shows a collection of Gremlins with a search bar that will allow to filter them by name.

Simulator Screen Shot 31 Jul 2016 00.33.15

 

Test are implemented as a regular UN test, so adding a new test is just adding a new UN test file:

projfiles

untest

As was mentioned before test are implemented as BDD test structure changes a little bit but do not get scared. Lets start  testing the view controller title:

First thing to do is import Quick and Nimble and extend our test class from QuickSpec. beforeEach is the chunk of code that will be execute before each test. Tests itself are implemented by specifying with it.

Another important issue is the call controller.beginAppearanceTransition before each test, this execute viewcontroller lifecycle calls before executing test.

Now lets launch test:

redtogreen

But remember we have to move from red to green. Now, just set the expected title string name and re-run the tests.

The first impression that you experiment with this framework is how easy and fast is execute a battery of test. An how easy is get into view controller internal attributes and methods for validating what is going on.

Let’s test that collection view can show all the expected gremlins

The view controller by default will show a hardcoded set of gremlins for better understanding, but that is not the real case scenario. For validating that the first that we do is just validate that the number of items that can see the collection view are 13, and afterwards we inject an array of 3 items for validating that the new number of items that can see the collection view now is different:

Lets look for more gremlins

But the view controller also allows us search gremlins by name, now lets validate that this functionallity is really working:

An important issue that I want to mention at that point is that or view controller hides the search bar when there are no items. This is very easy to do with this framework, just check .hidden attribute from search bar and that’s all!.

You can download the sample project used in this post here.

Conclusions

With Quick and Nimble you can run a test suit very quickly and this is great for refactoring. On the other hand is direct to have access to view controller internal stuff, this will save you lines of code and execution time on UI testing. So Quick and Nimble is a great alternative to unload test stuff from UI testsuite.

gizmo

Useful links

Model your classes with Argo JSON parser

The aim of this post is just basic introduction about how to use Argo framework for feeding your model classes from JSON data.

What is Argo.

[From https://github.com/thoughtbot/Argo]

Argo is a library that lets you extract models from JSON or similar structures in a way that’s concise, type-safe, and easy to extend. Using Argo, you won’t need to write validation code to ensure that incoming data is of the right type, or to make sure required data fields aren’t turning up empty. Argo uses Swift’s expressive type system to do that for you, and reports back explicit failure states in case it doesn’t find what you’ve told it to expect.

Argo

Argo is the Greek word for swift and the name of the ship used by Jason, son of Aeson, of the Argonauts. Aeson is the JSON parsing library in Haskell that inspired Argo, much like Aeson inspired his son Jason.

Codoapods. First things first.

In the Podfile you will have to add two frameworks, Argo itself and Curry that is being used for saving effort on initializing structs and classes.

 

Parsing structs

In this section through different examples I will explain how to parse the most common JSON structures.

Example 1. Most Basic JSON structure.

The content of the json file is the following:

The modeling struct is the following:

Just a few comments

  • As you can see with curry you save up call the initializer passing all class attributes.
  • <^> is for marking the first attribute, the rest are marked with a <*>
  • <| is for parsing a regular attribute and <|? for the optional ones.

For parsing just:

  • “person” is just the filename that contains the json.
  • JSONFromFile is a helper method that retrieves the json from the file. At the end of the post you will find a like for downloading whole sample project.

Example 2. 1-n attributes.

The content of the json file is the following:

The modeling struct is the following:

And this one:

Just a comment:

  • <|| is for parsing a collection of items

For parsing just:

Example 4. Another way of parsing JSON file.

The content of json file is the following:

The modeling struct:

For parsing the struct just:

As you can see the way of calling parser in that case is different but the result is exactly the same.

Parsing classes

For parsing classes I am based on the last struct example, but for clear understanding I will show an example.

This is the json content:

The modeling class:

In deep the idea is quite close than with structures, but in case of classes is carried out in a different way.

Finally for calling the parser:

Conclusion

I hope that throught all those examples you will not find any difficulty for understanting how to do a basic parsing. Please take a look at the library documentation for deeper understanding. You can download the sample project from here.

Usefull links