📜 ⬆️ ⬇️

Notes iOS programmer about his hammers, sledgehammers and micrometers

At one fine moment, when at the interviews I was already convinced that I was a senior iOS developer - I had the feeling that I was rested. I am writing similar code, solving problems in similar ways and the feeling that it is not clear where to develop further. I think it’s not just me who faced this problem - the lack of new ideas, concepts, directions. I would like to tell you about those tools and frameworks that helped me overcome this feeling.

I think most of the developers present here have read guys like the gang of four. Everyone, at least during the interviews, heard the word pattern, someone more (or less) lucky heard the more terrible words - imperative, functional, monad, reactivity and other horrors. In general, quite a lot of bright and interesting ideas are in the world of software development and, fortunately, not all of them exist only in the form of verbal abstractions. I would like in this article to tell a little not so much about the applied toolkit (although it is with him that we encounter most of the working time), as about the examples of the toolkit, for the use of which understanding is needed, which significantly helps in the future. I would like to talk about how (and what) tools change the design process itself, writing the code, at least did it for me.



This article, in my opinion, will be quite difficult for junior-level developers, but here are some wonderful tools - reading the code and examples of which can greatly push you toward development. More experienced developers, for sure, a significant part of this information is known, but, I believe that there is something useful for you. If only because I, to my shame and dismay, met most of the things described in the article rather late.
')
In general, as practice shows, the most useful solutions are usually quite simple. The main optimizations are almost always not in the choice of an algorithm with the asymptotics O (n) instead of O (n log n), but in the choice of the way the code base is organized. If you spend less time fighting your own code, you spend more time improving it. Therefore, lately, I try to devote more time to organizing code than I’ve been using the 201st batch that implements PullToRefresh on a UITableView. And I would like to share some of these ways I know.


In advance, I beg your pardon. As Bilbo Baggins said:
A good half of you, I know twice as bad as they should, and I like the thin half half as much as I should.

Here I am also - in this article there will not be a sufficiently detailed analysis of any of the proposed tools (there is not even a single line of code here!) - only subjective sensations and recommendations for use. And there are a lot of tools and each of them deserves a separate analysis.
BUT! there are these analyzes - and for each tool I tried to indicate where you can find examples of its use, documentation and related information - well, it is really more than enough.

So, let's begin.

Chapter 1. Introduction


cocoaPods

Probably there are no people who have not heard about this tool. A tool for managing external dependencies (third-party) for your project.
You can read about it here . I will not particularly write here about him, because everyone knows everything very well. And for those who do not know, you can read here and take note that this tool for iOS developer is a must have. The transition to its use significantly reduces the time of prototyping new applications, and writing your own pods significantly disciplines the process of creating reusable code.

Virtues


disadvantages


MagicalRecord

The framework for working with databases, which is a wrapper over CoreData. Read more about it here .
MagicalRecord helps you start using CoreData, even if you avoided it in every way before. Someone once compared using MagicalRecord without understanding how CoreData works with enjoying a cup of coffee in a burning house - and I can understand it, but in my personal experience - it was much easier for me to understand the subtleties of CoreData just by reading and using MR code in practical tasks.

MR itself is an adaptation of the concept of ActiveRecord for Objective-C. This concept shifts the focus when working with databases from databases and tables to individual records, linking to them the main operations on working with the database. That is, instead of “Table - delete this record”, we say “record - succeed”, or “record - create, change, give me all the instances corresponding to your entity”.

Its use can significantly reduce the amount of code in your wrapper over the database. And besides, it allows you to write much simpler and safer code for working with the database.

Virtues


disadvantages


PromiseKit

A framework for working with such a concept as Promise . You can read more about it here .
In short, this is a way to organize work with asynchronous code in the form of chains of actions. Why do you need it?
1. Asynchronous code becomes simple and linear regardless of the thread in which it is executed. Before his eyes, his strict structure - what and why will be fulfilled. On one screen you can put the following type of logic: Download two configs. When they hit, check them for validity. After that, start some kind of animation, then display the results.
2. Asynchronous code becomes atomic, encapsulated, and reusable. Very often there are many temptations to break the encapsulation of asynchronous operations — use some common variables, for example — which makes asynchronous code more difficult to change.
3. A comfortable opportunity appears to handle the errors of the entire execution chain. Everyone who wrote chains of asynchronous code encountered the fact that the longer the chain is, the more difficult it is to correctly handle errors, the harder and more cumbersome the code becomes.

Virtues


disadvantages


Chapter 2. Architectural frameworks or something.


PureMVC

You can read about it in detail here .
Probably one of the first major architectural frameworks that I had to deal with while working on mobile applications.
In short, this is a formal breakdown of the MVC pattern into smaller entities:
1. VO (value Object) - it is also familiar from CoreData Entity
2. Proxy - with its strange name, it nevertheless is a wrapper over a model - are responsible for data access and nontrivial getters (aggregators) of the model
3. Mediator - what is more accustomed to be considered a controller in MVC, controls the display in View and processes the signals coming from it. Can be subscribed to notifications sent through the facade.
4. View - well, View it is View. Code responsible for the visual presentation of information.
5. Facade - Singleton entity that exists all the time the application is running. All objects of the Proxy, Mediator and Command classes must be registered there.
6. Notification - the message sent through the facade. All mediators subscribed to it will receive it (and only they).
7. Command - that which describes the flow of the application - obeying the Command pattern - is started, executed, completed without being held in memory, in essence representing a notification with the executable code.

Virtues


disadvantages


Ash framework

You can read about it in detail here . You can also find examples of use.
Specifically, this framework is more suited to game development, but if at some point you can say that your application has ceased to be stateless, then getting to know this thing will be at least informative.
In short, this is a framework that implements the Entity-Component-System pattern and operates on the following set of entities:

1. Entity - in fact, some entity (for simplicity of description, I will use examples from the game subject in this case, because they are more suited to this framework). For example - a player, enemy or obstacle. In addition, entities may also be not so obvious actors (active objects) - for example, popup Options, lifeBar, or, for example, the whole level. Operates with the minimum information, associated with a certain set of components.
2. Component - some atomic data container. For example - position, speed, destructible, ...
3. Filter - Some filter in order to be able to get not the entire set of Entity - but only those that pass it. It is a set of keys component. Thus, if the filter contains the keys “position” and “speed” - then entities that do not move, or non-gaming entities - will not pass it.
4. System - description of the nature of changes of entities. Operates with a filtered set of entities and somehow converts it. For example, a gravity system. Takes entities passing through the filter — have a position, speed, acceleration, exposure to gravity — and recalculates their accelerations taking into account the effect of gravity.
Or MovementSystem - takes all entities that have a position, speed and acceleration - and change speed by the amount of acceleration, and position, by the amount of speed
5. World - some object that requests an update of all systems in a certain order.

In essence, this framework offers to the behavior of objects from a somewhat unusual point of view for a classical OOP — not an object reacts to changes, but the world finds objects that can react and change them independently, using systems.

Virtues


disadvantages


Reactive cocoa

Probably one of the most significant third-party frameworks for iOS development of the existing now. You can read about it in detail here and in Habré - and I strongly recommend it. He proposes to use some replacement of the basic iOS pattern (MVC) with its MVVM counterpart and relies on reactive programming in its use.
In short, Reactive Programming is a development paradigm focused on working with data streams. If the usual development (imperative), the developer programs in the style of "the program should make A, then make B, then make C". If A, B, and C are significant logical operations located in various application modules — as the number of such blocks grows, the coherence of programs increases, their complexity and size increase.
The most famous example of such a binding of various modules for long-running operations is the delegation pattern, but it does not solve all the problems.


What does Reactive Cocoa and MVVM offer:

For myself, I consider ReactiveCocoa the development of PromiseKit ideas, extending them to the level of application architecture.

Besides the fact that ReactiveCocoa inherits the advantages and disadvantages of PromiseKit - I would like to add the following:
Virtues


disadvantages


componentKit

A recent gift from the Facebook development team, which you can read more about here . I do not know about you, but more than once I looked at HTML and CSS with sadness - as ways of the task of interfaces. That is, what is called a declarative UI .
In short, according to Wikipedia, this is a way of describing entities that are not focused on “how to create it”, but on “what it will be like when it was created”. ComponentKit is the development of ideas, the emergence of which in iOS development can be seen in Avtoleayaute - the concept by which - by changing one interface element - there is no need to do many operations so that the rest of the UI remains to look correct. If in the old UIKit by changing the size of some UIView, there was a need to recalculate the positions of all the other UIView relative to it, which sometimes resulted in a nontrivial code for working with coordinates, now it suffices to say that this View will be 20 pixels from View, which is higher and 30 - which is lower - and no matter how we change its size - this ratio will remain unchanged.
ComponentKit went further in this regard - it offers a fairly large number of solutions for standard entities, the work with which used to be a lot of hassle:


Virtues


disadvantages


Chapter 3. Testing


About testing says a lot and different. Good and bad. Someone says that testing is a silver bullet, someone, on the contrary, it takes time, but in my opinion - this is one of the key stages in the development of programmers - and before you can judge about it - it is necessary pass the.
I would also recommend reading this recent article - it offers a superficial but pleasant overview of what tools in this regard are available to iOS developers.
If to speak seriously - TDD is probably the most strongly influenced me, as a developer, concept. And the point is not that autotests allow you to avoid regression, allow you to write code faster, less worried because of the changes. The main advantage of autotests is that not every code can be tested. It is through testing that abbreviations such as DRY and SOLID make sense.

Expecta

You can read about it in detail on the page of its repository , as well as its parent repository . There is also a sufficient number of examples of its use - enough to start using it.

If in your code:
1. There are many implicit dependencies (for example, singletons that you jerk with or without) - this code is incredibly difficult to test, because you need to satisfy all these dependencies. And from the point of view of application development, a change in the code of these most implicit dependencies will affect an unknown number of places in the code in an unknown way. Definitely bad.
2. If there are more non-stateless connections in your code, this code is difficult to test, because you need to test entire bundles of modules in all possible combinations of their steates (that is, the number of test cases grows exponentially). And from the point of view of the development of the application - in each of the combinations of states there can be some kind of bug, and the risks that the linked module will not be in the same state that we expect from it are still very high. And all additions to the code have a very, very high price.
3. If your code is not DRY, then you have to write tests for each of the repeated pieces of code, which increases the amount of work. And from the point of view of application development, the difficulty of maintaining the working capacity of a repeating code is proportional to the number of repetitions.

And many many others.
Thus, it turns out that the code being tested is in itself more supported, simpler in itself, simpler when making changes. And in general, in itself, it saves time.
And the best way to check that your code - we test - is to cover it with tests. If I understand correctly, over time, the need for most tests disappears, because you are already writing out the test code out of habit, but you still have to get to that time.

So, a bunch of Specta / Expecta is a framework for writing tests in the style of BDD .

Virtues


disadvantages


OCMock

You can read about it in detail here .
Unfortunately, when testing, it is not always possible to completely eliminate external and implicit dependencies of a module without significantly complicating the code. And here OCMock comes to the rescue - it allows you to emulate the behavior of external objects (including system frameworks), isolating your module from all external influences (network connection speeds, unexpected errors) and allows you to work with a guaranteed pure context (the server will return , , , , NSUserDefaults , , , ).

«» SOLID Enterprise — - . « » « ».




Blood Magic

, — 1101_debian , .
, , .
, . ( , . — ) Dependency injection — .

— , , , — — . , .h , . - ( , , OCMock ). -, « ? ? - ?».




4.


mogenerator

, , . . , , — .
— , , runtime, , , :
. Objective-C — Runtime — . , (DRY , , )
, ?
— ?
— ?
, ( , , ...).

-- , ( ).

, mogenerator , — . , , - .




fastlane

.
, , , continuous delivery .
:



, , , (AppleScript, Bash, Python, Ruby) . , . , DSL . , DSL ( ), , . FastLane — , DSL — .




disadvantages


YACC/LEX

, , , DSL . , , :


, , :


, — .




disadvantages


Instead of conclusion


, , , , ( , , ), — ( !) , . , , - — .
, . Until.

Source: https://habr.com/ru/post/254435/


All Articles