Skip to content
Marek Fořt edited this page Aug 30, 2018 · 7 revisions

Entities

There is not much included from this part in our project template for more reasons. Each project has a different data model and different needs so here is just a short description how we usually do that.

When there is no requirement for storing objects in local database, we use structs as model objects. Most of our server APIs use JSON of course, so model objects are deserialized from JSON using Marshal. We prefer Marshal to Codable for historical reasons - Marshal was here long before Codable was introduced, we have nice reactive extensions for it and we just know it well. But it's up to you how you will deserialize objects 🙂

When we need local database we use Realm Database. We gave up with CoreData some time ago and we realized Realm is easier to use and understand for us.

Services and managers

Typical service/manager objects are API services or UserManager. You can see both in the code.

UserManager

There is HasUserManager protocol definition at the top (see Dependency injection for more details). Below that you can see 2 more protocol definitions.

protocol UserManagingActions {
    var login: LoginAction { get }
    var logout: LogoutAction { get }
}

This action's protocol is just for namespacing - then you can call userManager.actions.login. Not important, you don't have to use it, just syntax sugar.

protocol UserManaging {
    var actions: UserManagingActions { get }

    var isLoggedIn: Property<Bool> { get }
    var user: Property<User?> { get }
}

All services/managers are "hidden" behind the protocol to be easily mockable in tests. That's the place where you define public interface of the object.

Then follows UserManager implementation which is individual for different use cases.

API

Our API services are based on 4 layers:

  • Network
  • JSONAPIService
  • AuthenticatedJSONAPIService
  • particular API service (eg. ExampleAPIService)

Network

Network layer is responsible just for downloading data from network and passing it to the next layer. We use Alamofire for networking but any other framework or NSURLSession could be used.

JSONAPIService

It "only" converts downloaded data to JSON response object. This layer can be replaced with XMLAPIService for example or whatever you need.

AuthenticatedJSONAPIService

In fact this is just a little different JSONAPIService. It extends JSONAPIService with authentication handling. When response with code 401 is returned from the server it tries to refresh token and restart original request. So you don't have to bother with handling authentication anymore. See UnauthorizedHandling.swift and AuthHandler.swift for more details.

ExampleAPIService

It has JSONAPIService as a dependency (or AuthenticatedJSONAPIService when you need requests to be authorized). Thats' the place where you define request URL, parameters, deserialize response etc.


Continue to ViewControllers ➡️