All Posts

The Recipe for Singletons Removal

Singleton Banner

We all went through it, am I right? You join a new company, you jump on the new codebase, you find lots of singletons, get used to them, become friend with them, but after some time you realize it’s time to terminate the friendship.

For a greater good.

And for better testing, of course. And for proper dependency injection, of course. And for your own sanity, of course.

After years in this field you should well know that singletons are bad, if you don’t… well… argh, I have bad news for you 🙃, but also a few articles, yes.

So here is a simple recipe to follow in order to have your app/code free from singletons. To some of you, this could all seem very obvious, and you might also know that I don’t write about obvious stuff, but tonight I’m tipsy and I had confirmation that most people are still unsure on how to get around such situations.

The recipe

1) Make a list of the singletons in the app and the dependencies between them.

2) Starting from the most high-level singleton (the one using the others more), apply the following for each one of them:

⦿ create a property in every class that reference the singleton at least once

⦿ substitute all the references to the singleton with the reference to the property

⦿ create a lazy getter returning the singleton or assign the singleton to the property where more appropriate (in the viewDidLoad for ViewControllers or generally speaking the init methods)

⦿ about the usages of singletons in static methods: refactor the code and turn those methods into instance methods as it surely is crap (this will allow dependency injection)

⦿ about the usages of singletons in categories:

→ if you own the class, publicly expose the property in the class

→ if we class comes from a framework (e.g. UIViewController) refactor the code by removing the category (it was probably bad code since the beginning)

⦿ build the app and make sure it still behaves as expected

⦿ make sure the (unit|automation) tests are still green

⦿ for every class using the singleton, modify it so that:

→ if the class is a ViewController, we prefer going for dependency setting rather that dependency injection as the view controller might be accessed via a segue (segue.destinationViewController). In this case, assert that the dependency is set in the viewDidLoad

→ otherwise, modify the designated initializer having it accepting a dependency via injection as per standard dependency injection. Keep the init chain correct (Obj-C & Swift)

⦿ modify the caller chain back up until the root object (most likely the AppDelegate) instantiates an instance of the original singleton and pass it down the chain

⦿ build the app and make sure it still behaves as expected

⦿ make sure the unit tests are still green

Show me the way

Really? Do I have to? Ok, let’s do something quick. Code is in Objective-C because singletons can be more easily found in legacy codebases… it is well-known that nobody writes singletons in Swift these days! Shots fired. 🎭

written in ios, legacy code, singleton Read on →

How to Abstract Your Persistence Layer and Migrate to Another One on iOS With JustPersist

The original post is published on the JUST EAT tech blog at the following URL http://tech.just-eat.com/2017/03/02/how-to-abstract-your-persistence-layer-and-migrate-to-another-one-on-ios-with-justpersist/

JustPersist Banner

In this blog post we introduce a solution to deal with data persistence. We developed it for the Just Eat iOS app and we call it JustPersist. It’s available open source on Github at github.com/justeat/JustPersist.

JustPersist aims to be the easiest and safest way to do persistence on iOS with Core Data support out of the box. It also allows you to migrate to any new persistence framework with minimal effort.

I highly suggest to read my previous article The Easiest Core Data as the underlying concepts are explained there.

The main author behind JustPersist and its design is Keith Moon. Major kudos to Keith for the excellent execution in Swift!

Overview

At Just Eat, we persist a variety of data in the iOS app. In 2014 we decided to use MagicalRecord as a wrapper on top of Core Data but over time the numerous problems and fundamental thread-safety issues, arose. In 2017, MagicalRecord is not supported anymore and new solutions look more appealing. We decided to adopt Skopelos: a much younger and lightweight Core Data stack, with a simpler design, developed by Alberto De Bortoli, one of our engineers. The design of the persistence layer interface gets inspiration from Skopelos as well, and we invite the reader to take a look at its documentation.

The main problem in adopting a new persistence solution is migrating to it. It is rarely easy, especially if the legacy codebase doesn’t hide the adopted framework (in our case MagicalRecord) but rather spread it around in view controllers, managers, helper classes, categories and sometimes views. Ultimately, in the case of Core Data, there is a single persistent store and this is enough to make impossible to move access across “one at a time”. There can only be one active persistence solution at a time.

We believe this is a very common problem, especially in the mobile world. We created JustPersist for this precise reason and to ease the migration process.

At the end of the day, JustPersist is two things:

  • A persistence layer with a clear and simple interface to do transactional readings and writings (Skopelos-style)
  • A solution to migrate from one persistence layer to another with (we believe) the minimum possible effort

JustPersist aims to be the easiest and safest way for persistence on iOS. It supports Core Data out of the box and can be extended to transparently support other frameworks. Since moving from MagicalRecord to Skopelos, we provide available wrappers for these two frameworks.

The tone of JustPersist is very much Core Data-oriented but it enables you to migrate to any other persistence framework if a custom data store (wrapper) is implemented (in-memory, key-value store, even Realm if you are brave enough).

JustPersist is available through CocoaPods. To install it, simply add the following line to your Podfile:

1
2
3
pod "JustPersist/Skopelos"
# or
pod "JustPersist/MagicalRecord"

Using only pod JustPersist will add the core pod with no subspecs and you’ll have to implement your own wrapper to use the it. If you intend to extend JustPersist to support other frameworks, we suggest creating a subspec.

Usage of the persistence layer

To perform operation you need a data store, which you can setup like this (or see related paragraph paragraph):

1
2
3
let dataStore = SkopelosDataStore(sqliteStack: <modelURL>)
// or
let dataStore = MagicalRecordDataStore()

Before using the data store for the first time, you must call setup() on it, and possibly tearDown() when you are completely done with it.

We suggest setting up the stack at app startup time, in the applicationDidFinishLaunchingWithOptions method in the AppDelegate and to tear it down at the end of the life cycle of your entire app, when resetting the state of the app (if you provide support to do so) or in the tearDown method of your unit tests suite.

To hide the underlying persistence framework used, JustPersist provides things that conform to DataStoreItem and MutableDataStoreItem, rather than the CoreData specific NSManagedObject. These protocols provide access to properties using objectForKey and setObject:forKey: methods.

In the case of Core Data, JustPersist provides an extension to NSManagedObject to make it conforming to MutableDataStoreItem.

Readings and writings

The separation between readings and writings is the foundation of JustPersist. Reading are always synchronous by design:

1
2
3
dataStore.read { (accessor) in
  ...
}

While writings can be both synchronous or asynchronous:

1
2
3
4
5
6
7
dataStore.writeSync { (accessor) in
  ...
}

dataStore.writeAsync { (accessor) in
  ...
}

The accessor provided by the blocks can be a read one (DataStoreReadAccessor) or a read/write one (DataStoreReadWriteAccessor). Read accessors allow you to do read operations such as:

1
2
3
func items(forRequest request: DataStoreRequest) -> [DataStoreItem]
func firstItem(forRequest request: DataStoreRequest) -> DataStoreItem?
func countItems(forRequest request: DataStoreRequest) -> Int

While the read/write ones allow you to perform a complete set of CRUD operations:

1
2
3
4
5
6
7
func mutableItems(forRequest request: DataStoreRequest) -> [MutableDataStoreItem]
func firstMutableItem(forRequest request: DataStoreRequest) -> MutableDataStoreItem?
func createItem(ofMutableType itemType: MutableDataStoreItem.Type) -> MutableDataStoreItem?
func insert(_ item: MutableDataStoreItem) -> Bool
func delete(item: MutableDataStoreItem) -> Bool
func deleteAllItems(ofMutableType itemType: MutableDataStoreItem.Type) -> Bool
func mutableVersion(ofItem item: DataStoreItem) -> MutableDataStoreItem?

To perform an operation you might need a DataStoreRequest which can be customized with itemType, an NSPredicate, an array of NSSortDescriptor, offset and limit. Think of it as the corresponding Core Data’s NSFetchRequest.

Here are some complete examples:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
dataStore.read { (accessor) in
  let request = DataStoreRequest(itemType: Restaurant.self)
  let count = accessor.countItems(forRequest: request)
}

dataStore.read { (accessor) in
  let request = DataStoreRequest(itemType: Restaurant.self)
  request.setFilter(whereAttribute: "name", equalsValue: <some_name>)
  guard let restaurant = accessor.firstItem(forRequest: request) as? Restaurant else { return }
  ...
}

dataStore.writeSync { (accessor) in
  let restaurant = accessor.createItem(ofMutableType: Restaurant.self) as! Restaurant
  restaurant.name = <some_name>
  ...
  let wasDeleted = accessor.delete(item: restaurant)
}

written in core data, database, ios, magicalrecord, open source, persistence, skopelos Read on →

A Better Local and Remote Logging on iOS With JustLog

The original post is published on the JUST EAT tech blog at the following URL http://tech.just-eat.com/2017/01/18/a-better-local-and-remote-logging-on-ios-with-justlog/

JustLog Banner

In this blog post we introduce the solution for local and remote logging we developed for the Just Eat iOS app. It’s named JustLog and it’s available open source on Github at https://github.com/justeat/JustLog.

Overview

At Just Eat, logging and monitoring are fundamental parts of our job as engineers. Whether you are a back-end engineer or a front-end one, you’ll often find yourself in the situation where understanding how your software behaves in production is important, if not critical. The ELK stack for real-time logging has gained great adoption over recent years, mainly in the back-end world where multiple microservices often interact with each other.

In the mobile world, the common approach to investigating issues is gathering logs from devices or trying to reproduce the issue by following a sequence of reported steps. Mobile developers are mostly familiar with tools such as Google Analytics or Fabric.io but they are tracking systems, not fully fledged logging solutions.

We believe tracking is different in nature from logging and that mobile apps should take advantage of ELK too in order to take their monitoring and analysis to another level. Remote logging the right set of information could provide valuable information that would be difficult to gather otherwise, unveil unexpected behaviours and bugs, and even if the data was properly anonymized, identify the sequences of actions of singular users.

JustLog takes logging on iOS to the next level. It supports console, file and remote Logstash logging via TCP socket out of the box. You can also setup JustLog to use logz.io with no effort. JustLog relies on CocoaAsyncSocket and SwiftyBeaver, exposes a simple swifty API but it also plays just fine with Objective-C.

JustLog sets the focus on remote logging, but fully covers the basic needs of local console and file logging.

Usage

JustLog, is available through CocoaPods. To install it, simply add the following line to your Podfile:

1
pod "JustLog"

Import it into your files like so:

1
2
3
4
5
// swift
import JustLog

// Objective-C
@import JustLog;

This logging system strongly relies on SwiftyBeaver. We decided to adopt SwiftyBeaver due to the following reasons:

  • good and extensible design
  • ability to upload logs to the cloud
  • macOS app to analyze logs

A log can be of one of 5 different types, to be used according to the specific need. A reasonable adopted convention on mobile could be the following:

  • 📣 verbose: Use to trace the code, trying to find one part of a function specifically, sort of debugging with extensive information.
  • 📝 debug: Information that is helpful to developers to diagnose an issue.
  • ℹ️ info: Generally useful information to log (service start/stop, configuration assumptions, etc). Info to always have available but usually don’t care about under normal circumstances. Out-of-the-box config level.
  • ⚠️ warning: Anything that can potentially cause application oddities but an automatic recovery is possible (such as retrying an operation, missing data, etc.)
  • ☠️ error: Any error which is fatal to the operation, but not the service or application (can’t open a required file, missing data, etc.). These errors will force user intervention. These are usually reserved for failed API calls, missing services, etc.

When using JustLog, the only object to interact with is the shared instance of the Logger class, which supports 3 destinations:

  • sync writing to Console (custom destination)
  • sync writing to File (custom destination)
  • async sending logs to Logstash (usually part of an ELK stack)

Following is a code sample to configure and setup the Logger. It should be done at app startup time, in the applicationDidFinishLaunchingWithOptions method in the AppDelegate.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
let logger = Logger.shared

// file destination
logger.logFilename = "justeat-demo.log"

// logstash destination
logger.logstashHost = "my.logstash.endpoint.com"
logger.logstashPort = 3515
logger.logstashTimeout = 5
logger.logLogstashSocketActivity = true

// default info
logger.defaultUserInfo = ["app": "my iOS App",
                          "environment": "production",
                          "tenant": "UK",
                          "sessionID": someSessionID]
logger.setup()

The defaultUserInfo dictionary contains a set of basic information to add to every log.

The Logger class exposes 5 functions for the different types of logs. The only required parameter is the message, optional error and userInfo can be provided. Here are some examples of sending logs to JustLog:

1
2
3
4
5
Logger.shared.verbose("not so important")
Logger.shared.debug("something to debug")
Logger.shared.info("a nice information", userInfo: ["some key": "some extra info"])
Logger.shared.warning("oh no, that won’t be good", userInfo: ["some key": "some extra info"])
Logger.shared.error("ouch, an error did occur!", error: someError, userInfo: ["some key": "some extra info"])

It plays nicely with Objective-C too:

1
2
3
4
[Logger.shared debug_objc:@"some message"];
[Logger.shared info_objc:@"some message" userInfo:someUserInfo];
[Logger.shared error_objc:@"some message" error:someError];
[Logger.shared error_objc:@"some message" error:someError userInfo:someUserInfo];

written in elk, ios, logging, logstash, open source Read on →

The Easiest Core Data

Over the past months I spent a lot of time on Core Data, I had to deal with a project with a lot of legacy code, Core Data horros and multithreading violations. Core Data is hard, at times it can be frustrating and confusing. For this reasons, I decided to come up with a refined solution for a super simple design. The aim was to write a minimalistic, thread-safe, non-boilerplate and super easy to use version of Active Record on Core Data, that is actually all you need for doing Core Data in the 95% of the cases. The iterations were a few and I reconsidered my solution multiple times until I finally got where I wanted.

So… here it is. Let me introduce Skiathos and Skopelos. Skiathos is the Objective-C version, while Skopelos is the Swifty one. They are available as CocoaPods. The names come from 2 islands in Greece where I spent my 2016 summer holidays and found the inspiration to refine the final versions.

General notes

This component aims to have an extremely easy interface to introduce Core Data into your app with almost zero effort.

The design introduced here involves a few main components:

  • CoreDataStack
  • AppStateReactor
  • DALService (Data Access Layer)

CoreDataStack

If you have experience with Core Data, you might know that creating a stack is an annoying process full of pitfalls. This component is responsible for the creation of the stack (in terms of chain of managed object contexts) using the design described here by Marcus Zarra.

core-data-stack

An important difference from Magical Record, or other third-party libraries, is that the savings always go in one direction, from slaves down (or up?) to the persistent store. Other components allow you to create slaves that have the private context as parent and this causes the main context not to be updated or to be updated via notifications to merge the context. The main context should be the source of truth and it is tied the UI: having a much simpler approach helps to create a system easier to reason about.

written in active record, core data, ios, persistence Read on →

Offline UI Testing on iOS With Stubs

The original post is published on the JUST EAT tech blog at the following URL http://tech.just-eat.com/2015/11/23/offline-ui-testing-on-ios-with-stubs/

Here at JUST EAT, while we have always used stubs in Unit Tests, we tested against production public APIs for our functional and UI Testing. This always caused us problems with APIs returning different data depending on external factors, such as time of day. We have recently adopted the UI testing framework that Apple introduced at the WWDC 2015 to run functional/automation tests on the iOS UK app and stubs for our APIs along with it. This has enabled us to solve the test failures caused by network requests gone wrong or returning unexpected results.

Problem

For out UI Testing we used to rely on KIF but we have never been completely satisfied, for reasons such as:

  • The difficulty of reading KIF output because it was mixed in the app logs
  • The cumbersome process of taking screenshots of the app upon a test failure
  • General issues also reported by the community on the GitHub page

We believe that Apple is providing developers with a full set of development tools and even though some of them are far from being reliable in their initial releases, we trust they will become more and more stable over time.

Another pitfall for us is that our APIs return different values, based on the time of the day, because restaurants might be closed and/or their menu might change. As a consequence, the execution of automation tests against our public APIs was causing some tests not to pass.

Proposed Solution

Rethinking our functional tests from scratch allowed us to raise the bar and solve outstanding issues with a fresh mind.

We realised we could use the same technology used in our Unit test to add support for offline testing in the automation tests, and therefore we designed around OHHTTPStubs to stub the API calls from the app. Doing this was not as trivial as it might seem at first. OHHTTPStubs works nicely when writing unit tests as stubs can be created and removed during the test, but when it comes to automation tests it simply doesn’t work.

The tests and application run as different instances, meaning that there is no way to inject data directly from the test code. The solution here is to launch the application instance with some launch arguments for enabling a “testing mode” and therefore generating a different data flow.

We pass parameters to the app either in the setup method (per test suite):

1
2
3
4
5
6
7
8
override func setUp() {
    super.setUp()
    continueAfterFailure = false
    let app = XCUIApplication()
    app.launchArguments = ["STUB_API_CALLS_stubsTemplate_addresses",
                           "RUNNING_AUTOMATION_TESTS"]
    app.launch()
}

or per single test:

1
2
3
4
5
6
7
func test_ApplePayAvailable_UserLoggedIn_ServiceTypeDelivery() {
    let app = XCUIApplication()
    app.launchArguments = ["STUB_API_CALLS_stubsTemplate_addresses",
                           "RUNNING_AUTOMATION_TESTS"]
    app.launch()
    // test code
}

In our example we pass two parameters to signal to the app that the automation tests are running. The first parameter is used to stub a particular set of API calls (we’ll come back to the naming later) while the second one is particularly useful to fake the reachability check or the network layer to avoid any kind of outgoing connections. This helps to make sure that the app is fully stubbed, because if not, tests could break in the future due to missing connectivity on the CI machine, API issues or time sensitive events (restaurants are closed etc).

We enable the global stubbing at the end of the application:didFinishLaunchingWithOptions: method:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#ifndef APP_STORE_BUILD
    [self _stubAPICallsIfNeeded];
#endif

//...

- (void)_stubAPICallsIfNeeded
{
    // e.g. if 'STUB_API_CALLS_stubsTemplate_addresses' is received as argument
    // we globally stub the app using the 'stubsTemplate_addresses.bundle'
    NSString *stubPrefix = @"STUB_API_CALLS_";
    NSString *bundleName = [[[[NSProcessInfo processInfo].arguments filterUsingBlock:^BOOL(NSString *arg) {
        return [arg hasPrefix:stubPrefix];
    }] firstObject] stringByReplacingOccurrencesOfString:stubPrefix withString:@""];

    if (bundleName)
    {
        [JEHTTPStubManager applyStubsInBundleWithName:bundleName];
    }
}

The launch arguments are retrieved from the application thanks to the NSProcessInfo class. It should now be clearer why we used the STUB_API_CALLS_stubsTemplate_addresses argument: the suffix stubsTemplate_addresses is used to identify a special bundle folder in the app containing the necessary information to stub the API calls involved in the test.

This way the Test Automation Engineers can prepare the bundle and drop it into the project without the hassle of writing code to stub the calls. In our design, each bundle folder contains a stubsRules.plist file with the relevant information to stub an API call with a given status code, HTTP method and, of course, the response body (provided in a file in the bundle).

Xcode group folder

This is how the stubs rules are structured:

stubsMapping.plist

At this point, there’s nothing more left than showing some code responsible for doing the hard work of stubbing. Here is the JEHTTPStubManager class previously mentioned in the AppDelegate.

written in automation, ios, stubs, testing Read on →

A Mind-blowing Impression Tracking Proposal on iOS

In one of my previous companies, it happened from time to time I had the opportunity to do some R&D of experimental ideas. What came out once, was, in my opinion, pretty neat. It never saw the light in production and I don’t want this amount of work to be forgotten, so here is, after years, a still valid outline of a powerful impression tracking engine on iOS.

Before further reading, you should be familiar with AOP and you should read my previous article on Analytics on iOS.

Problem

  • You have an app with a feed
  • You want to track the impressions of the items
  • You don’t want to track items displayed on screen during a fast scroll
  • You only want to track impressions that stay on screen for more than n seconds

Reasons for this are, for example, you want to collect data for the impressions to better sell ads. Prepare to read a lot of code to understand the overall design, not the implementation (for that you need quite some time).

written in analytics, event tracking, google analytics, impression tracking, ios Read on →

The Journey of Apple Pay at JUST EAT

The original post is published on the JUST EAT tech blog at the following URL http://tech.just-eat.com/2015/07/14/the-journey-of-apple-pay-at-just-eat/

Introduction

Apple Pay has recently been released in UK and at JUST EAT we worked on the integration in the iOS app to better support all of our customers and to ease the experience to both existing and new users. Until version 10 of our iOS UK app, the checkout for completing an order was wrapped into a webview and the flow was as follows:

biscuit

Since Apple pushes developers to implement Apple Pay in a way that the checkout doesn’t force the user to log in, the checkout flow had to be reworked, and we took the opportunity to make the majority of the checkout flow native. This enabled us to support both checkout flows:

  • standard checkout (now with a more native flavour)

biscuit

  • Apple Pay checkout

biscuit

The latter is clearly a fantastic solution for completing the checkout in very few steps with a great and simple UX. Thanks to the information provided by Apple Pay (inserted by the user when registering a debit/credit card) the user details native screen is no longer necessary and more importantly for the user, there is no need to log in to the platform.

A further detail on the checkout is that we support two different so-called “service types” for the orders: delivery and collection. Defined as so:

1
2
3
4
5
6
typedef NS_ENUM(NSUInteger, JEServiceType)
{
    JEServiceTypeUnknown = 0,
    JEServiceTypeDelivery,
    JEServiceTypeCollection
};

On a side note, these changes soon became a challenge during the development as JUST EAT need to treat Apple Pay users (guest users) in a similar manner to users that have registered previously to our service.

How we designed around Apple Pay

At the time of writing there are already a few very good articles about a basic integration with Apple Pay. Probably the best reference worth mentioning is the NSHipster post.

Clearly also the Apple Documentation is a great start and the “Apple Pay Within Apps” video from WWDC 2015 explains really clearly all the relevant steps to have your app ready for Apple Pay.

Rather than discussing the basic concepts (creating the merchant ID, configuring the PKPaymentRequest object, handling the presentation of the PKPaymentAuthorizationViewController, sending the token to the Payment Service Provider, etc.), we think it’d be more useful to walk you through the architectural aspects we considered when designing the solution on iOS using Objective-C.

In the architecture we are proposing, the relevant components for handling an Apple Pay payment are the following:

  • ApplePayService
  • ApplePayPaymentHandler
  • ApplePayPaymentRequestFactory

Some additional components are also present in the big picture:

  • CheckoutService
  • ABRecordRefConverter
  • PaymentFlowController

written in apple, apple pay, ios, just eat Read on →

Notes on the Developer Portal. For Dummies.

Let’s make it clear. This is a post for dummies. There are some others tutorials online but I thought I could write something better focusing on the right details rather than wasting time on a brainless walkthrough. Well… here are my 50¢.

It’s since 2008 that I work with the iOS platform and still, when it comes to managing certificates and provisioning profiles within the Developer Portal, I lose my mind. Just like when you start a new bottle of vodka and you cannot remember the entire trip that brought you to the bottom of the previous bottle.

After having read this post you’ll hopefully have a better understanding of what and why you need to setup in terms of certificates and provisioning profiles for building an iOS app on device or for archiving for release. If not, at least you have some handy tutorial for dummies.

Let’s start from scratch. No keys, no certificates, no provisioning profiles, clean Mac install.

written in apple, certificates, code signing, developer portal, ios, provisioning profiles Read on →

From the Eyes of an iOS Dev at JUST EAT

It has been almost 6 months since my last blog post. Things have changed quite a lot since then. Six months ago I was still excited about my travel to San Francisco for the WWDC 2014, my girlfriend still had to move from Italy to London with me and definitely I wasn’t planning to switch job again any time soon.

Overture

I’ve been attracted by JUST EAT as a company since March 2014 but at that time it was too early for me to consider to change job. I met Ben Chester (the tech lead of the iOS team) when he gave a talk at Badoo offices (when I was still working there) and that evening he blew my mind. Later, I had a few chances to have a chat with the passionated guy he is and I immediately thought “Damn! I want to work with this guy, with brilliant guys like him and I want to work at JUST EAT!”.

Since then, I heard people talking extremely good about JUST EAT as a job place because of the values, the work environment, the company culture and the engineeristic approach to things. Every time I started with “Do you know JUST EAT as a company?” the answer was something like “Oh yeah! They are freaking cool! I have a friend working there, they do amazing stuff and he’s very very happy!”. They definitely were all good signs. Signs I decided not to underestimate anymore these days.

Another good sign was also the exposure and lots of information that the company promotes online with its tech blog giving a good insight of the technologies used, the people and teams working there and a good description of the Engineering. Benefits are also compelling.

JUST EAT offices hosted NSLondon a few times. Meetups, you know, are the perfect occasions to reach out the developers' community. I noticed too many cool companies failing at this.

After months of interest about JUST EAT and thoughts spinning in my head, I said to myself “let’s see if I have what it takes”. I decided to apply for the Senior iOS role in later October 2014 kicking off the process taking the test task. I joined the Consumer iOS app team at the begin of 2015 and after 2 months of excitement I’m summarizing some thoughts here.

wall

written in github, ios, just eat, london, open source, work Read on →

Working on Tasks With an Eye on Open Source Contributions

Have you ever realized that developers are never happy with the legacy code?

The definition of “legacy code” may vary:

  • code inherited from the previous developers of your company
  • code that doesn’t have test suites
  • code that is older that 10 minutes (…)

We all rarely find good code when joining a company, weird uh? Some reasons why good code is so hard to find can be:

  • the developer that worked on the code was good but couldn’t care less about doing things properly
  • the developer that worked on the code was simply unexperienced and created bizzare things
  • the developer that worked on the code was terrible at architecture design
  • too many developers worked on the same code without understanding what was already been done
  • code was not developed using the black box approach and without reusability in mind

All points but last are summarized here:

developers

written in github, ios, objective-c, open source, work Read on →

Flow Controllers on iOS for a Better Navigation Control

Since I’m in London conversations with iOS developers have reached high levels with no doubts. I love to discuss with friends and iOS devs about new ways to improve our coding. Often my best practices are very appreciated among them and a bunch of devs start applying day-by-day what they learnt. “An Aspect Oriented Programming Approach to iOS Analytics” and “CocoaPods: Working With Internal Pods Without Hassle” are 2 examples of good best practices. A friend asked for a post about the specific topic of flow controllers so… here we go. :)

Navigation on iOS

There are very few ways to present UIViewControllers on iOS either through UINavigationController or UIViewController:

1
2
3
4
5
6
7
8
// UIViewController
[viewControllerInstance presentViewController:modalViewController
                                     animated:YES
                                   completion:^{ /* ... */ }];

// UINavigationController
[navigationControllerInstance pushViewController:detailViewController
                                        animated:YES];

The thing I never liked is that UIViewController instances have the ability to push things on their own using the associated UINavigationController and to present other UIViewController instances within their logic. It’s not… their responsibility.

written in architecture, design, github, ios, objective-c Read on →

Objective-C, Zen and Some Satisfaction

I’m very proud to announce my last work with Luca Bernardi

zen-logo

“Zen and the Art of the Objective-C Craftsmanship”

Available on GitHub.

We started writing this book on November 2013. The initial goal was to provide guidelines to write the most clean Objective-C code possible: there are too many guidelines out there and all of them are debatable. We didn’t aim introducing hard rules but, instead, a way for writing code to be more uniform as possible across different developers. With time the scope moved to explain how to design and architecture good code.

The idea underneath is that the code should not only compile, instead it should “validate”. Good code has several characteristics: should be concise, self-explanatory, well organized, well documented, well named, well designed and stand the test of time. The main goals behind the curtain are that clarity always wins over performance and a rationale for a choice should always be provided. Some topics discussed here are general and independent from the language even if everything is tied up to Objective-C.

Then something happened…

On June 6th, 2014 Apple announced the new programming language to be used for iOS and Mac development in future: Swift. This new language is a radical departure from Objective-C and, of course, has caused a change in our plan for writing this book. It boiled down to the decision of releasing the current status of this essay without continuing our journey in unfolding the topics we originally planned to include. Objective-C is not going anywhere but at the same time continuing to write a book on a language that will not receive the same attention as it used to, is not a wise move.

During the very first 2 days after the release, the fuzz in the iOS community on Twitter was great! We really hope you will enjoy it and will improve your craftsmanship skills ;-)

written in architecture, best practices, code, design, github, ios, objective-c, programming, style, zen

Road to Circular Progress Pull to Refresh at Beamly

Pull to refresh, this friend of ours

The Pull to refresh became one of the most popular concepts used in mobile iOS apps. Loren Brichter, the author of Tweetie for iOS introduced it for the first time in 2011 and it stood the test of time. Several implementations of the pull to refresh lie out there and the most used on iOS is for sure the SVPullToRefresh by Sam Vermette. Back in 2012, the concepts of Objective-C runtime and associated objects were still obscure to most of the iOS developers but Sam used the properly to add an extra view to the UIScrollView without the need for subclassing.

Apple built a native pull to refresh publicly available as of iOS 6, called UIRefreshControl, but customizations are hard to achieve and still, too often developers fallback to an ad hoc implementations. The most common customization is implementing a circular progress view like the one used in the Pinterest app. This leads to a much cooler UI rather than the well-known yet obsolete rotating arrow, and it is recognizable and intuitive to all iOS users.

The concept proposed here has two main individual transitions that are dependent about the position of the finger:

  1. App logo becomes visible (alpha/opacity property)
  2. Circle progress becomes filled

You can see the final behaviour in the gif below, but I definitely recommend downloading and running the Beamly iOS app by yourself to get the right feeling.

animation

written in design, github, ios, objective-c, pull to refresh, ui, ux Read on →

Asynchronous Message Passing With Actors in Objective-C

Actors, these strangers

Although we are all in love with Objective-C, the power of a language itself is given by its inner features. Languages like Ada have a built-in concurrency model, while Objective-C needs external libraries (let’s say libdispatch) to try to achieve the same power of expression found in richer languages.

The same happened for the implementation of the Actor Model. The standout language for the feature of asynchronous message passing using the actor model is Erlang. From Wikipedia:

The actor model in computer science is a mathematical model of concurrent computation that treats "actors" as the universal primitives of concurrent digital computation: in response to a message that it receives, an actor can make local decisions, create more actors, send more messages, and determine how to respond to the next message received.

That said, languages like Ada and Erlang are semantically more powerful than Objective-C, as some features are expressed at the language level rather than through libraries provided in the user space.

Adopting the Actor Model means avoiding the Object Orientation orthodoxy and forcing the developer to write software as a collection of smaller communicating programs that do not share state. Software written using the Actor Model approach is inevitably more “pure” than its traditional counterpart as the paradigm expresses a better level of abstraction, no matter which language is used.

written in actor model, actors, asynchronous message passing, concurrency, ios, objective-c, thread safety Read on →

An Aspect Oriented Programming Approach to iOS Analytics

[Update 09/06/2014]

On May 2014 Peter Steinberger released Aspects inspired (a little :-) by this article and Orta and Ash Furrow improved ARAnalytics with a DSL based, again, on this article -> Tweet

orta-tweet

Analytics are a popular “feature” to include in iOS projects, with a huge variety of choices ranging from Google Analytics, Flurry, MixPanel, etc. Most of them have tutorials describing how to track specific views and events including a few lines of code inside each class.

On Ray Wenderlich’s blog there is a long article with some sample code to include in your view controller in order to track an event with Google Analytics:

1
2
3
4
5
6
7
- (void)logButtonPress:(UIButton *)button {
    id<GAITracker> tracker = [[GAI sharedInstance] defaultTracker];
    [tracker send:[[GAIDictionaryBuilder createEventWithCategory:@"UX"
                                                          action:@"touch"
                                                           label:button.titleLabel.text
                                                           value:nil] build]];
}

The code above sends an event with context information whenever a button is tapped. Things get worse when you want to track a screen view:

1
2
3
4
5
6
7
- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];

    id<GAITracker> tracker = [[GAI sharedInstance] defaultTracker];
    [tracker set:kGAIScreenName value:@"Stopwatch"];
    [tracker send:[[GAIDictionaryBuilder createAppView] build]];
}

This always looked like code smell to me. Do you see the nasty thing here? We are actually making the view controller dirty adding lines of code that should not belong there it as it’s not responsibility of the view controller to track events. You could argue that you usually have a specific object responsible for analytics tracking and you inject this object inside the view controller but the problem is still there and no matter where you hide the tracking logic: you eventually end up inserting some lines of code in the viewDidAppear:.

Here comes the idea.

written in analytics, aop, aspect oriented programming, google analytics, ios, objective-c Read on →

CocoaPods: Working With Internal Pods Without Hassle

CocoaPods is cool. I was honoured to have a chat with Fabio Pelosin, the main contributor, at the NSLondon meetup some time ago and see how much passion those guys put in this project.

I was one of the first supporters back in 2012 and I have some Pods in the Specs repo (ADB prefixed). Recently, I spent several days going through some hidden aspects of CocoaPods, ending up reading some source code from the Core and Xcodeproj.

During one of the last few NSLondon(s) of 2013, Orta explained the advantages of CocoaPods and Abizer Nasir, in the following meetup, discussed the usage of Git submodules. Basically comparing their visions.

What I’m going to explain here is a solution to a common scenario:

Manage the versioning of internal private pods within projects without hassle.

written in cocoapods, ios, objective-c, podfile, podspec Read on →

The Cost of Moving

I have friends in Italy who are eager to move to London. We all have. Most of these friends are concerned about the cost of moving within London, for some idiotic reasons people think that buses and underground are too expensive. Well… that’s bullshit. The aim of this article is to compare the cost of moving within Italy and London and prove that London is much more cheaper than expected. The assumptions here are: in Italy you need a car for living, while in London not. Don’t you think it’s the same? Bullshit again, in big cities like London you just need a public transports subscription. You really don’t want to own a car (which is a huge relief for me since I moved to London).

So… the goal to reach here is: “One wants to move around the city, to go to work or out for having fun.”. You may achieve that in different ways in Italy and London. Find below what my personal expenses were in Italy and now, that I moved to London.

Don’t misunderstand me, it might be that here I’m comparing apples to oranges to you, but just try to follow me in the process.

Let’s go bananas and run some numbers.

written in car, cost, italy, london, moving, oyster, price Read on →

iOS7 Subviews Hierarchy

In iOS6 a common approach to tweak the appearance of the UIView subclasses (like UISearchBar, UITextField etc.) was to cycle the subviews searching for a given view to alter.

1
2
3
4
5
6
7
8
9
10
11
id viewThatIWantToTweak = nil;
for (UIView *view in self.searchBar.subviews) {
    if ([view isKindOfClass:NSClassFromString(@"UISearchBarTextField")]) {
        viewThatIWantToTweak = view;
        break;
    }
}

if (viewThatIWantToTweak) {
    // do something with viewThatIWantToTweak
}

The subviews property is defined in the in the UIView interface.

1
@property (nonatomic, readonly, copy) NSArray *subviews;

Unfortunately in iOS7 viewThatIWantToTweak in the previous example will always be nil. The view hierarchy has changed for (apparently) the majority of the UI elements. It is no more sufficient to cycle the subviews to effectively retrieve the desired view: it is necessary to search recursively the subviews array.

written in ios, ios7, objective-c Read on →

Objective-C Blocks Caveat

I like blocks. I really do. It’s been at least two years now I’ve been using them and I still make syntax mistakes, but I like them.

Recently I had a long discussion with my colleagues and friends about the use of self inside blocks. I can hear you saying: “C'mon dude, it’s sooo straightforward and ridiculous!”. I’m sure there are some subtle things to consider about the __weak and the __strong qualifiers for self inside blocks.

written in blocks, ios, objective-c Read on →

Objective-C Blocks Under the Hood

Recently I was asked to describe the ‘under the hood’ memory management of variable and objects in blocks. I think that in 2013 almost every iOS dev knows the practical usage and effect of putting the __block keyword before the declaration of a variable, but maybe what’s happening for real is not so straightforward.

written in blocks, ios, objective-c Read on →

Sartoria Piquadro iPad App

I don’t think I’ve ever talked too much about Sartoria. Sartoria is a cool and important project for Piquadro, the famous fashion brand. I’m the sole developer of the official iPad app used in the Piquadro stores around the world.

Sartoria-screenshot-2

written in fashion, ios, ipad Read on →

H-Farm, H-umus and Cool Fashion Models

My last entry here was a few months ago right after my graduation; since then, I really nevere had time to update my website. It’s good to be busy day after day… btw, it’s time to write some line about something worth writing.

I started working for a startup company in H-Farm, called H-umus. H-Farm is a Venture Incubator with the mission to accelerate the development of Internet startups via a combination of seed investment and incubation services. Some kind of Italian Silicon Valley (1 and 2).

farm-summer

written in computer science, fashion, h-farm, h-umus, ios, personal Read on →

610 = 1102

Well well. I graduated in Computer Science. Master degree. Fuck yeah. I’m so happy I can’t tell. Now it’s time for a lot of new stuff. 7 days of “relax” and then H-umus is the next working step. Here are some pics of yesterday :)

Discussion

written in miscellanea, personal Read on →

iBarbra (About Duck Sauce's Song Barbra Streisand)

Yeah guys, iBarbra is the app for iPhone that lets you barbrate your name. Or whatever you type. Yes, I mean the famous, meme, celebrated, outstanding Duck Sauce’s song “Barbra Streisand“. It’s some kind of meme, so me and 3 other cool guys made up this project, with me focusing on iOS Development and backend management. Barbrate your name guys :)

written in ios Read on →

iFreddie for iPhone

iFreddie for iPhone has been relesead on the App Store today! THIS APP HAS BEEN MADE BY FREDDIE’S FANS FOR THE 20TH ANNIVERSARY OF HIS DEATH

It contains a biography about his life and career, as well as pictures and videos of this rock legend!
Available on the App Store

written in ios Read on →

101010 = 42

Today is a great day. A very very very important important day Gaga. 10/10/’10. October 10th 2010.
101010 in binary notation equals to 42 in decimal notation. And we know that 42 is to a computer scientist as shoes are to women. A constant. Check it out at Wikipedia #42

written in github, ios Read on →

Wind of Change

I quitted Absolute5 and Centrica and had taken in general a break from music, just to have more time for other important things in life: college, studies, computer science projects, travels, friends and girlfriend :)

written in personal