iOS Code Quality 1/2

When I tell my friend i'm a developer and i'm writing some bunch of code, they don't say it but, I know they see me like this:

Crazy Coding

And when I feel this, I know they see me like someone who write tons and tons of line of codes, unreadable things like, you know, the Matrix. But it's false, because good dev use good code quality tools and rules. And if you follow some good guidelines and have a bit of organization/team-spirit, you can do a xcodeproj as sexy as the final app! Here are some of the major things I personaly use when I develop an iOS app.

Team Working

Excepting some folks, many of iOS devs work in a team and THAT is a big good point !

    Two pairs of eyes for one line of code

This sentence must in your TOP-10 geeky sentence when you are coding. It can be seen unproductive to be reviewed by another co-worker, but in fact, it's very effective, more productive and very formative. This can be done with some rules:

Extreme programming

This can be viewed like a good expression to explain when 2 folks are in front of a screen but ... no programming (9GAG is your best friend for this period) BUT in reality it's a very effective way to produce lighter code, more thoughtful bunch of lines or algorithm. Coding in binom can show you another point of view or another way to do your stuff.

It's an efficient solution but it have to be done sporadically and periodically. Too many extreme programming kill the process: this have to be done only when you stuck on a part of your work or when you have to choose between solutions, when you have to make a big choices. 2 brains for big things, not to choose a color for example (and after go to see some poney on 9gag...).

Community programming

Softer than E.P., community programming is a good (and personnaly adopted) way to review your code. The best example of community programming is GitHub.

GitHub Logo

With 9 millions of users, GitHub is the best example of community programming. And it's done using some programming tools, seen below ;) !
The main objective of this method is to review your code by your co-worker but on your commit (which push you into doing short commit ! another little tips), which are accepted during pull/merge request of your laste change on the main repo (@see below)

Team working - Git tools

When you build an app in a community/team programming spirit, you can use two veru good assets in the git package. Git-Flow and pull/merge request.

Git-Flow

Git-Flow is not a direct way to enhance your code quality, but enhance your code organization, and so the quality of your build. It can be summarized by a famous sentence:

Divide to rule

and in french

Diviser pour mieux régner   

Git-Flow allow you to divide your action and force you to commit your code for each hotfix/feature/release/build/add/improvment/whateveryouwant in a different branch. Let's see this very good graph:

GitFlow graph

As you can see, when you, you code on two branches (develop and master), Git Flow allow/force you to much more:

  • Historical branches

    • These are your master and develop. Every commit on the master is a production release. Every commit on the develop branch is a beta-test release for you and not the client (like for your internal receip. Not more, not less. That's all. To give you a scope, develop is the branch where you will do your main continuous integration.
  • Feature branches

    • They allow you to add... well ... features ! For ex, in your app you want to accept URL Schemes, you will branch from the last develop, named it like "URLScheme" and do all its job on it, and ONLY its job. You wanna fix at the middle of the feature a bug ? let's commit your work on the "URLScheme" and use the Git-Flow "Hotfix"
  • Release branches

    • develop is your main branch, master is the AppStore branch, and release is the client branch. Every commit on it is an AdHoc deployment. Easy, no ? There are some conventions about this branch:
      • branch off: develop
      • merge into: master
      • naming convention: release-* or release/*
  • Hotfix branches, or "Maintenance branches"

    • In web jobs in general, hotfix is seen like a hotfix directly on the master branch, and deploy at the same time on the develop one. For iOS, you can use hotfixes on master directly (for critical issues like security threat) or in the develop branch to fix an issue seen by a client on its last Release commit (but keep an eye on wich develop commit you have to hotfix !)

If you want more informations about Git-Flow workflow, I redirect you on the very good article made by Atlassian: Gitflow Workflow

Forks & Merge/Pull requests

Merge Requests

Forking workflow has a major difference compared to the main workflow. There is not one repos for X devs, there are as many repos as folks. One of this devs is the "dictator" one, the expert (blue guy above) who reviewed all developers' code. This is the strict way to use Forking Workflow. I prefere when there is not dictator, and all others developers reviewed the code: It's cost-efficient and not all mobile team have an expert, it's a fact. So you can be the dictator... yes ...

Diabolic baby meme

Here is how it work:

  1. Instead of working on the main repos, every devs fork it on his own GitHub/GitLab profil (his own remote).
  2. Every devs clone their own new-borned remote locally.
  3. They do stuffs...
  4. ...and commit/push (so always on their remote repo)
  5. After that, and when a developer feels the need to be reviewed and apply their changes for all other devs AND the big main repo (the upstream), he ask a pull/merge request
    • On GitHub it's named a Pull Request...
    • and on Gitlab a Merge Request. But it's the same workflow/meaning.
  6. The dictator (or in a best cases the others devs) review the code and comment it. Note: a Pull/Merge request has to be seen like a post or a thread: you can discuss on it, ask why he did like that, explain why your solution is better etc etc ...
  7. The dev who ask the request saw some "To-Do" changes written during the review, change his code, push again (the PR/MR is automatically refreshed, no need to recreate one)
  8. Another review by the dictator etc etc etc ...
  9. ... the Dictator accept the MR/PR
  10. The changes are automatically merged (80% of the times, maybe some part have to be done manually, thank you .pbxproj) and deploy on the main repo, the upstream one !
  11. all other devs just have to pull on their own forked to get the changes !

    Again, if you want better or deeper explanations, Atlassian is your friend: Forking Workflow

Dependency managers

Every good iOS developer is a lazy developer, that's a fact: you don't want to re-re-re-re-re-re-rewrite the same model, the same HTTP Client or the same Custom 3D popup View Of The Death. And you don't even think to pull an update of these really cool stuffs, afraid to put a time bomb on your project. For this, you can use dependency managers.

Package Logo

Dependency managers allow you to use the KISS spirit: Keep It Simple Stuff.
No need to re-invent known and very well done stuff (who said AFNetwork ?), get errors when you want to add this beautiful CryptographicOfTheDeath.bundle or when you have the best red lines in xCode: "Duplicate Symbols for ARM64" ... yay !

Cocoapods

Cocoapods logo

The TOP 1 tool for all iOS developers is Cocoapods: it allows you to add any correct repo on your xcode project and use it just by adding one line of script. It depends of a file, named Podfile, and created by yourself at the root of your project and is presented like this:

platform :ios, '8.0'
use_frameworks!

target 'MyApp' do
  pod 'AFNetworking', '~> 2.5'
  pod 'ORStackView', '~> 2.0'
  pod 'SwiftyJSON', '~> 2.1'
end

Just with this, you are able to create a .xcworkspace containing your project and all of these awesome frameworks, just by tapping on your Terminal:

pod install

And magic happen. No injection error, no duplicate symbols, everything rocks. You now want to use AFNetworking ? just put it on your file like this:

#import <AFNetworking/AFnetworking.h>

the main drawbacks of Cocoapods is its solution: it's intrusive in your code (you have to open a xcworkspace) and not all libraries can be pulled by Cocoapods, they need to be known in the Cocoapods database. Not like Carthage.

If you want more informations about Cocoapods --> here

Carthage

Instead of Cocoapods, Carthage allow you to inject all (well done) repositories you want, package it into static or dynamic libs and give you beautifuls .framework.
When Cocoapods is easier to use, Carthage need to create some manual stuff, like importation and XocdeProject modifications, but can be done easily, and maybe automatically done in a beautilful high end Carthage script.

The solution is based on a Cartfile, which list all of the framework you want with their repos:

github "Carthage/ReactiveTask" "0.7-beta.2"
github "thoughtbot/Argo" ~> 1.0.1

Not a pod install to do, but a

carthage update

And your framework are done ! You 'just' have to integrate it (but again, I pretty sure this part can be automatically done)

If you want more informations about Carthage --> here