High-level design

This section explains the high-level design of the frontend and backend.

Frontend

Application design follows a slightly different version of the Model-View-Controller (MVC) pattern, with the addition of the Actions , Store, State, and Communication layers to simplify the controller layer of traditional iOS application MVC pattern. All application layers are explained in the following sections.

Models

Plain old model structures. These models do not have any logic and only consist of properties. There are four types of models:

  • TodoRequest: This is a struct that is used in backend request calls and conforms to RequestProtocol
  • Todo: This is a struct that represents the Todo data, and uses the Argo and Curry libraries to decode the object from JSON
  • TodoViewModel and TodosViewModel: These structs represent data and are used in views and shown to the user
  • TodoLens: These lenses modify the Todo model

All the aforementioned models are immutable value types.

Views

We have two View subclasses: one to provide a custom UITableViewCell called TodoTableViewCell and a subclass of UIView named FooterView.

Both of these Views are subclasses of iOS SDK-provided classes. Besides these classes, we will have our UIViewController scenes in the storyboard.

ViewController

ViewController is a subclass of UIViewController or UITableViewController, and it connects views to logic:

  • MasterViewController: This is a subclass of UITableViewController to present Todo items
  • DetailsViewController: This is a subclass of UIViewController to present details of each Todo item to the user

To develop iOS applications, we have to rely on iOS SDK-provided classes such as UIViewController and UITableViewController. The ViewController and UIView subclasses are the only classes that will be used in this case study.

State

In iOS application development, we need to handle states. We use the Delta and ReactiveCocoa libraries to manage our Todo App's state.

Delta takes an App that has custom state management spread throughout all the ViewControllers and simplifies it by providing a simple interface to change state and subscribe to its changes.

ReactiveCocoa is a FRP cocoa framework that provides APIs for composing and transforming streams of values over time.

We will implement a State struct that will provide the observable properties.

Store

Our Store struct will wrap the State struct and provide properties to observe its changes. Store conforms to the Delta library's StoreType protocol, which defines the storage of an observable state and dispatch methods to modify it. Also, Store uses ReactiveCocoa's MutableProperty value and allows observation of its changes in a thread-safe manner.

Actions

Actions are structs that conform to the ActionType protocol from the Delta library. ActionType is used when we want to make modifications to the store's state. All changes to the store go through this type.

We will develop the following actions in the application:

  • ClearCompletedTodosAction: This is used to delete completed Todo items from the list
  • CreateTodoAction: This is used to create a new Todo item
  • DeleteTodoAction: This is used to delete a Todo item
  • DetailsTodoAction: This is used to present the details of an item
  • LoadTodosAction: This is used to list all Todo items
  • SetFilterAction: This is used to filter Todo items
  • ToggleCompletedAction: This is used to mark a Todo item as completed
  • UpdateTodoAction: This is used to update a Todo item

Manager

TodoManager provides global functions to handle backend API calls and JSON payload mapping. TodoManager uses WebServiceManager for backend calls and the Argo library to map JSON payloads to the Todo model. Also, TodoManager will update the State in the Store through Lenses and Action.

Communication

The communication layer is responsible for backend communication. It includes the following components:

  • WebServiceManager: This provides a global function named sendRequest that is used by TodoManager to call the backend API. Also, it uses configureHeaders to perform a reflection on request to get its properties and respective values.
  • Urls: This enum provides a proper HTTP request method and a full URL address by pattern matching and extension.
  • Alamofire: This is a library that is used by WebServiceManager for HTTP request handling.
  • Argo: This library maps model objects from and to JSON functionally.

Communication between layers

Application uses closures and ReactiveCocoa signals for communication between layers.

Third-party libraries

The following third-party libraries/frameworks are used in our iOS application:

  • Alamofire: This is a web service calling and management framework
  • Argo: This is a functional JSON parsing library
  • CocoaPods: This is responsible for dependency management
  • Delta: This is the state management library
  • ReactiveCocoa: This is a Functional Reactive Programming (FRP) library to handle signals and streams
  • Quick: This is a behavior-driven development framework used for unit testing

Cross-cutting concerns

This section explains cross-cutting concerns such as error management, exception handling, and so on.

Error management and exception handling

As discussed in previous chapters of this book.

Crash reporting

We will use Crashlytics, which is a part of fabric.io offering by Twitter.

Analytics

We will use fabric.io Answers to monitor application usage. There are other analytics services such as Google Analytics, Flurry, and Mixpanel that can be used for this case study. We are going to use Answers for the sake of simplicity.

Tools

Tools We will use Xcode to develop our application. AppCode by JetBrains is another IDE for iOS application development with better refactoring capabilities that can be used for this case study.

Backend

There are various web framework and HTTP servers for Swift, which are works-in-progress. Kitura, Perfect, and Vapor are three of the most popular ones. None of them are designed and developed in FP style. We will use Vapor in our example to provide a backend that can be leveraged by our frontend application.

Vapor

Vapor (https://github.com/qutheory/vapor) is a popular Laravel/Lumen-inspired web framework that is MIT-licensed. It is purely written in Swift and is modular.

Vapor provides CLI tools to simplify building and running Vapor applications.

vapor new <project-name> can be used to create a new project, vapor build can be used to build the project and download dependencies, vapor xcode can be used to create Xcode project, and vapor run can be used to run the project.

Vapor uses Swift Package Manager (SPM) as the dependency manager and starting an application with Vapor is as easy as importing Vapor and adding the following lines to the main file:

let app = Application()
app.start(port: 8080)

Routing

Routing in Vapor is simple:

app.get("welcome") { request in
    return "Hello, World"
}

Adding the preceding code to the main file will make our web application respond to all GET requests to localhost:8080/welcome with the string Hello, World.

JSON

It is easy to respond with JSON:

app.get("version") { request in
    return Json(["version": "0.1"])
}

The preceding code responds to all GET requests to localhost:8080/version with the JSON dictionary {"version": "0.1"} and Content-Type: application/json.

Requesting data

Every route call gets passed a request object that can be used to grab query and path parameters.

The following example shows how to access JSON, Query, and form-encoded data from the request:

app.post("hello") { request in
    guard let name = request.data["name"]?.string else {
        return "Please include a name"
    }

    return "Hello, (name)!"
}

In this example, we read the request data and return a string.

Vapor also provides the means for session management, database connection, and view responses with HTML or Stencil template-included HTML pages. There is an example Vapor project (https://github.com/qutheory/vapor-example) that can be used and modified for our purposes. We are not going to explore Vapor in depth since it is still in a work-in-progress.

SPM

SPM is an open source build and dependency management tool provided for Swift 3.0. It is integrated with the Swift build system to automate the process of downloading, compiling, and linking dependencies.

Vapor uses SPM and to create a Vapor project we need to add the following dependency to the Packages.swift file:

.Package(url: "https://github.com/qutheory/vapor.git",
  majorVersion: xx, minor: x),
.Package(url: "https://github.com/qutheory/vapor-zewo-mustache.git",
  majorVersion: xx, minor: xx)

As stated in the Vapor section, we can use Vapor CLI tools to build and run the application with SPM.

It is recommended to read more about Vapor and SPM since we do not cover most of the related topics in this book. In the following section, we will develop a very simple backend with Vapor.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset