inaka

Latest blog entries

/
The Art of Writing a Blogpost

The Art of Writing a Blogpost

Apr 11 2017 : Matias Vera

/
SpellingCI: No more spelling mistakes in your markdown flies!

Feb 14 2017 : Felipe Ripoll

/
Fast reverse geocoding with offline-geocoder

Do you need a blazing fast reverse geocoder? Enter offline-geocoder!

Jan 18 2017 : Roberto Romero

/
Using Jayme to connect to the new MongooseIM REST services

MongooseIM has RESTful services!! Here I show how you can use them in an iOS application.

Dec 13 2016 : Sergio Abraham

/
20 Questions, or Maybe a Few More

20 Questions, or Maybe a Few More

Nov 16 2016 : Stephanie Goldner

/
The Power of Meeting People

Because conferences and meetups are not just about the technical stuff.

Nov 01 2016 : Pablo Villar

/
Finding the right partner for your app build

Sharing some light on how it is to partner with us.

Oct 27 2016 : Inaka

/
Just Play my Sound

How to easily play a sound in Android

Oct 25 2016 : Giaquinta Emiliano

/
Opening our Guidelines to the World

We're publishing our work guidelines for the world to see.

Oct 13 2016 : Brujo Benavides

/
Using NIFs: the easy way

Using niffy to simplify working with NIFs on Erlang

Oct 05 2016 : Hernan Rivas Acosta

/
Function Naming In Swift 3

How to write clear function signatures, yet expressive, while following Swift 3 API design guidelines.

Sep 16 2016 : Pablo Villar

/
Jenkins automated tests for Rails

How to automatically trigger rails tests with a Jenkins job

Sep 14 2016 : Demian Sciessere

/
Erlang REST Server Stack

A description of our usual stack for building REST servers in Erlang

Sep 06 2016 : Brujo Benavides

/
Replacing JSON when talking to Erlang

Using Erlang's External Term Format

Aug 17 2016 : Hernan Rivas Acosta

/
Gadget + Lewis = Android Lint CI

Integrating our Android linter with Github's pull requests

Aug 04 2016 : Fernando Ramirez and Euen Lopez

/
Passwordless login with phoenix

Introducing how to implement passwordless login with phoenix framework

Jul 27 2016 : Thiago Borges

/
Beam Olympics

Our newest game to test your Beam Skills

Jul 14 2016 : Brujo Benavides

/
Otec

Three Open Source Projects, one App

Jun 28 2016 : Andrés Gerace

/
CredoCI

Running credo checks for elixir code on your github pull requests

Jun 16 2016 : Alejandro Mataloni

/
Thoughts on rebar3

Thoughts on rebar3

Jun 08 2016 : Hernán Rivas Acosta

/
See all Inaka's blog posts >>

/
Otec

Andrés Gerace wrote this on June 28, 2016 under integration, ios, sample, tutorial .

The last blogpost I wrote was about an “image projector” open source utility but this time I won’t talk about something I did for you to use in your project. This time, I’m here to talk about OTEC.

Otec Logo

Let’s begin with a little introduction about why I developed it. Here, at Inaka, we take (from time to time) a few days to create and/or work on open-source projects that can help us improve our code and save time on future projects. We hope our work will help you the same way it helps us. Most of the applications we developed depend on a server behind them (I can only recall a single app that doesn’t depend on one of them) and I’m pretty sure that most of the apps in the market work in the same way. Before Swift was released around 2 years ago, we decided to create a library based on the repository pattern; so, we created IKJayma. It was an open-source, Objective-c based library that provided us with a faster way to connect to our servers from our apps and with the means to have a generic and organized way to handle the responses, making the server guys work in a more consistent way too and use always the same conventions on their side.

A few months ago, Pablo started building the Swift version of IKJayma, Jayme. It's also built around the repository pattern, but in a much more cooler and easier way than its predecesor, IKJayma. We didn’t have a real chance to test it on a project, yet. So Brujo had the brilliant idea to create a sample app that uses two of our most complex and coolest open-source Swift libraries: Jayme and Event-Source. This one was developed by Andres and it is a Swift version of a javascript library also called EventSource. It allows you to implement the client portion of the Server-Sent Events protocol. Check its blogpost. Since we needed a server to test both of them, we decided to use Canillita, an erlang server developed by Harry that provides API-REST endpoints to create/retrieve news and newspapers, and one that works with the SSE protocol to listen to upcoming news items. If you want to read/learn more about how it works or how it was developed, check this blogpost. The idea of this blog post is to show you how simple is to use Jayme and EventSource. Based on the repository pattern and Canillita’s functionality, I needed to create two different models to represent the entities I needed to handle : News and Newspapers. So, based on how Jayme works, this is my News model:

struct News: Identifiable {
    let id: String
    let title: String
    let body: String
    let newspaper: String
}

I declared the required properties: a title, a body and the newspaper name the news item belongs to. Then I declared the id, which is required by the Identifiable protocol, so Jayme would be able to know which object we are using. To simplify things, I ignored the creation date Canillita is retrieving along with this data (maybe I’ll include it in the future).

In order to let Jayme handle any News item, the News model needed to comply with the DictionaryInitializable, DictionaryRepresentable so in the same file I added an extension to News

extension News: DictionaryInitializable,
   DictionaryRepresentable {
    
  init(dictionary: [String: AnyObject]) throws{
    let json = JSON(dictionary)
    guard let
      id = json["id"].string,
      title = json["title"].string,
      body = json["body"].string,
      newspaper = json["newspaper_name"].string
      else { throw .ParsingError }
    self.id = id
    self.title = title
    self.body = body
    self.newspaper = newspaper
  }

  var dictionaryValue: [String: AnyObject] {
    return [
      "id": self.id,
      "title": self.title,
        "body": self.body,
        "newspaper": self.newspaper
    ]
  }
   
}

There are two important things to remark here: First, the throwable init. It will allow Jayme to know if it has to return either a News object or an error, as a JaymeError, in case something wrong happens while trying to parse the dictionary response into an object. The second one is that all the properties are declared as constants with let. This methodology of having immutable complete objects is a good practice we encourage for all the languages we work with (check this 7 Heuristics for Development Post if you want to read more about that). Apple also encourages this as a good practice. It will depend on your business model, but as long as you can, you should avoid using var variables. Using all let variables with no initial values will force you to fill all the properties in the init method, as you can notice. Otherwise you'll get a compile error. The dictionaryValue method is the way you have to tell Jayme how your objects need to be translated into a dictionary to be sent to the server. It will also depend on your business model. You’ll see below, when I show you the Newspaper model, that the property names don't always match with the dictionary keys the server can understand.

And this is our Newspaper model:

struct Newspaper: Identifiable {
  let id: String
  let newspaperDescription: String
}

Even simpler than the News model. In this case, the id is the name of the newspaper, so now you’ll see how the model complies to the DictionaryRepresentable protocol.

extension Newspaper: DictionaryInitializable,
  DictionaryRepresentable {
    
  init(dictionary: [String: AnyObject]) throws{
    let json = JSON(dictionary)
    guard let
      id = json["name"].string,
      description = json["description"].string
      else { throw JaymeError.ParsingError }
    self.id = id
    self.newspaperDescription = description
  }
    
  var dictionaryValue: [String: AnyObject] {
    return [
      "name": self.id,
      "description": self.newspaperDescription
    ]
  }
}

Again, we have a throwable init, for the same reasons as above, but you can see that the dictionaryValue returns a dictionary with keys that don't match the properties' names as they do on the dictionaryValue in the News struct. In this case, the property id needs to be sent as name to the server and the property description may generate conflicts with the description property declared on the CustomStringConvertible Swift protocol, so I changed it to newspaperDescription.

We have our models now so, according to the repository pattern, we need to create the repositories that will hold the system's business logic. They'll also be used by Jayme to handle the server response and create objects from this models with that response. Let’s take a look to the NewspaperRepository class and then explain it.

class NewspaperRepository: CRUDRepository {

  typealias EntityType = Newspaper
  let backend = 
    NSURLSessionBackend.otecBackend()
  let name = "newspapers"

}

Jayme provides us the CRUDRepository protocol ( Create, Read, Update and Delete ) which already have default implementation for those 4 actions. So, unless those default implementations don't work for you, you should be good to go by just declaring the EntityType (Newspaper, in this case) the repository will handle, the backend ( we’ll jump to that later, let’s just say that’s the object that handles the real connection with the server ) and the name of the endpoint we want to hit.

Lets jump to the NewsRepository

class NewsRepository: CRUDRepository {

  typealias EntityType = News
  let backend =
    NSURLSessionBackend.otecBackend()
  var name: String {
      let userNewspaper = 
        UserNewspaperSession.userNewspaperName()
        
    return "newspapers"+"/"+userNewspaper+"/news"
  }
}

Again, we are declaring the EntityType (as News, in this case), the name of the endpoint, and the OtecBackend. Note that the only "tricky" thing here is the declaration of the var name as a computed property. I had to do that because Canillita has to know what Newspaper will be the owner of the News by declaring it in the URL (something like /newspaper/:newspaperName/news). But even with those extra lines of code, I almost didn't write anything.

Now, let's move to the backend. The backend is the object that will create the requests and execute them in the lowest layer of our app. Then, it’ll take the response and translate it into something we call a Future (Basically, an enum with .Failure or .Succes with associated values) and return that to the repository that will parse the data into model objects and return that to the controller that owns it. Jayme provides us with an NSURLSessionBackend that has a default configuration (Url and HTTPHeaders). You can extend this Backend to retrieve one with the right configuration for you. Let’s see how:

extension NSURLSessionBackend {
  static func otecBackend() -> 
    NSURLSessionBackend {
      let httpHeaders = 
        [HTTPHeader(field: "Accept",
                    value: "application/json"),
            HTTPHeader(field: "Content-Type",
                    value: "application/json")]


      let configuration = 
        NSURLSessionBackendConfiguration(
        basePath:Constants.CanillitaBackendURL, 
        httpHeaders:httpHeaders)

      return NSURLSessionBackend(configuration:
                                 configuration)
    }
}

You create a static method that returns a backend initialized with custom headers and a custom URL. In this case, I have my URL as a constant on a file I’m using to store different kinds of constants. This is not the best approach to do this, but the purpose of Otec is to show you how easy it is to use our libraries, and not to focus on the best approaches to develop an app. You can check our guidelines for that. So, when you declare the backend on your repository, you will use this one instead of a regular NSURLSessionBackend. Something like :

let backend = NSURLSessionBackend.otecBackend()

Let's talk about the other important topic of this blogpost: EventSource

This was the first time I implemented SSE, and the magic that makes it work is still deep-dark magic to me. But, thanks to EventSource, I don’t need to understand how Satan is moving the events from the server to my device. All I need to do is add listeners to specific events, know what the event has inside, parse it, and use it.

class NewsListener {
    
  let name = "news"
    
  func listenToNewsWithEventSource(
    eventSource: EventSource,
    forNewspapersIDs newspapersIDs: [String],
    newReceivedCompletion 
      completion: Result <News, JaymeError> 
        -> ()) {
    
    newspapersIDs.forEach {

      eventSource.addEventListener($0) { 
        (esId, esEvent, esData) in
        guard let id = esId,
              let event = esEvent,
              let data =  esData else {

          completion (.Failure(.BadResponse))
          return

        }

        guard let new = try? 
          self.createNewFromSSEEvent
            (id, event: event, data: data)
              else {

          completion (.Failure(.ParsingError))
          return

        }

        completion(Result.Success(new))
      }

    }

  }
    
  func newsEventSource() -> EventSource {

    let url = self.urlStringWithPath(self.name)
    return EventSource(url: url,
      headers: ["Accept":"application/json"])

  }
    
  private func urlStringWithPath(path: String) 
    -> String {

    let url = 
      Constants.CanillitaBackendLocalHostURL
    return url + "/" + path

  }

}

extension NewsListener {

  private func createNewFromSSEEvent(
    id: String,
    event: String,
    data: String)
    throws -> News {

      let titleAndBodyOfNew = 
        data.componentsSeparatedByString("\n")
      let title = titleAndBodyOfNew[0]
      let body = titleAndBodyOfNew[1]
        
      let newDictionary = ["title":title,
                          "body":body,
                         "id":id,
                        "newspaper_name":event]
      guard let new = try? News(dictionary: 
                          newDictionary) else {

        throw JaymeError.ParsingError
      }

      return new

  }

}

This is the only class that is long enough to MAYBE be annoying. But it’s not hard to understand. The listener receives a closure to handle the events received by the EventSource object. It also receives an array with all the newspaper Ids it should start listening to. The response parsing happens in the method called createNewsFromSSEEvent and, if something goes wrong, it returns a JaymeError instead of a News object. In this case, the title and the body are coming in the string data separated by a \n so, I just parse that string into two different strings and use them. Event source will handle disconnection and will always send the last event-id retrieved to avoid getting events you already received. That's what SSE is supposed to do: avoid getting lots of information you already received once. With this said, in this app we are not storing info in any local database, but the idea is to store every event you receive to keep a record of all of them once they arrived to the app.

And... that’s it. The rest of the project is just regular swift-app code. You can check it out if you want in here.
Hey! Did you see that? We have an app that connects to a REST+SEE server API and we haven't even thought about:

  • AFNetworking
  • TCP connections
  • Objective-C integrations
  • Response parsing code
  • Switching threads

Where is all that? By using libraries like Jayme and EventSource, you can forget about all those boring tasks and concentrate on the really important pieces of your code, the ones that make your app unique.

Feel free to check the code, use it or change it. You can open issues here or just change things and create a PR; I'll make sure to check it. Also, I would appreciate if you can help me improve the app UI (I'll create issues for that so you can pick one of them).