O objetivo aqui, é criar uma api com reaproveitamento de modelo de dados para uso em aplicativo nativo.
Instalando o Vapor
Siga as instruções do site oficial: https://docs.vapor.codes/3.0/install/macos/
Após instalado e com o XCode aberto, vamos instalar o Fluent para o PostreSQL, que será o responsável por toda a comunicação de model / vapor com nosso banco de dados.
Adicione o pacote no arquivo Package.swift:
dependencies: [
// ? A server-side Swift web framework.
.package(url: "https://github.com/vapor/vapor.git", from: "3.0.0"),
.package(url: "https://github.com/vapor/fluent-sqlite.git", from: "3.0.0")
.package(url: "https://github.com/vapor/fluent-postgresql.git", from: "1.0.0"),
],
targets: [
.target(name: "App", dependencies: ["FluentSQLite", "FluentPostgreSQL", "Vapor"]),
Após adicionar as linhas e dependências, execute novamente o comando a seguir para que sejam instaladas as dependências no projeto.:
$ vapor xcode
Faça isso sempre que adicionar e ou remover alguma dependência. Feito isso, vamos começar as configurações:
Configurações de Serviços, IP e porta
IP e Porta
//Configure IP And Port
let serverConfiure = NIOServerConfig.default(hostname: "0.0.0.0", port: 8080)
services.register(serverConfiure)
Fluent PostgreSQL DataBase
/// Configure a PostgreSQL database
var databases = DatabasesConfig()
let databaseConfig = PostgreSQLDatabaseConfig(hostname: "localhost", username: "michel", database: "todoDemo1")
let dataBase = PostgreSQLDatabase(config: databaseConfig)
databases.add(database: dataBase, as: .psql)
services.register(databases)
Migrations
/// Configure migrations
var migrations = MigrationConfig()
migrations.add(model: Todo.self, database: .psql)
//migrations.add(model: Todo.self, database: .psql)
services.register(migrations)
Configurando Model: Sources > App > Models > Todo.Swift

Vamos alterar o model Todo para o seguinte formato, removendo o import do FluentSQLite e também o protocolo SQLiteModel, substituindo por Codable. Adicionaremos um atributo/campo do tipo Bool:
import Foundation
/// A single entry of a Todo list.
final class Todo: Codable {
/// The unique identifier for this `Todo`.
var id: Int?
/// A title describing what this `Todo` entails.
var title: String
/// A flag describing if this `Todo` is done.
var done: Bool?
/// Creates a new `Todo`.
init(id: Int? = nil, title: String, done: Bool? = false) {
self.id = id
self.title = title
self.done = false
}
}
Agora recortaremos as seguintes linhas que estão abaixo da class Todo:
/// Allows `Todo` to be used as a dynamic migration.
extension Todo: Migration { }
/// Allows `Todo` to be encoded to and decoded from HTTP messages.
extension Todo: Content { }
/// Allows `Todo` to be used as a dynamic parameter in route definitions.
extension Todo: Parameter { }
Agora abra o arquivo: Sources > App > Controllers > TodoController.Swift

Logo abaixo do import Vapor, cole o código que copiamos do arquivo Todo.swift.
Vamos aproveitar e importar também a Lib FluentPostgreSQL e adicionar a Extension para o mesmo.
extension Todo: PostgreSQLModel { }
Nosso arquivo após os ajustes devem ficar assim:
import Vapor
import FluentPostgreSQL
extension Todo: PostgreSQLModel { }
/// Allows `Todo` to be used as a dynamic migration.
extension Todo: Migration { }
/// Allows `Todo` to be encoded to and decoded from HTTP messages.
extension Todo: Content { }
/// Allows `Todo` to be used as a dynamic parameter in route definitions.
extension Todo: Parameter { }
/// Controls basic CRUD operations on `Todo`s.
final class TodoController {
/// Returns a list of all `Todo`s.
func index(_ req: Request) throws -> Future<[Todo]> {
return Todo.query(on: req).all()
}
/// Saves a decoded `Todo` to the database.
func create(_ req: Request) throws -> Future<Todo> {
return try req.content.decode(Todo.self).flatMap { todo in
return todo.save(on: req)
}
}
/// Deletes a parameterized `Todo`.
func delete(_ req: Request) throws -> Future<HTTPStatus> {
return try req.parameters.next(Todo.self).flatMap { todo in
return todo.delete(on: req)
}.transform(to: .ok)
}
}
Fizemos esses ajustes para isolarmos o arquivo de model Todo para usá-lo tanto no Vapor, quanto em um projeto de app sem se preocupar com dependências.
Neste momento já podemos rodar o projeto e ver o banco criado com o Target Run selecionado, aperte “Command” + “R” para rodar o projeto.
Se tudo deu certo você deve ter a seguinte saída no console do XCode:

E se você abrir seu gerenciador de banco, terá o banco criado também (eu uso o pgAdmin).

Podemos fazer um commit de nossas alterações e partir para o próximo branch.
Testando API com Postman
Você pode facilmente testar a api com o Aplicativo Postman:

Se fizermos um get no mesmo endereço já teremos a listagem com as Todos criadas. Se acessarmos no navegador o endereço http://localhost:8080/todos, também teremos acesso às todos criadas.
Criando um App de Todo e Reaproveitando o Model
Primeiro precisamos adicionar um novo Target no projeto:
1. Selecione o Projeto e clique no ícone “+“, conforme na imagem abaixo:

2. Selecione Single View App:

3. Preencha os campos conforme preferir e dê ok:

Pronto, você tem um novo target criado. Agora precisamos fazer com que o Model seja visto por nosso novo target.
Para isso selecione o arquivo de model e na coluna de Utilities marque o target do App, conforme imagem abaixo:

Agora o Model Todo já está visivel para o Target do App.
Não vou entrar no melhor modo de fazer um app de Todo, mas vou deixar o projeto final no GitHub para que vocês vejam o tutorial rodando e criando registros.
- Link do projeto final: https://github.com/micheltlutz/todoCocoaHeads
- Slides disponíveis no link a seguir: https://www.slideshare.net/michelboss/cocoaheads-poa-agosto-18
Fique à vontade e crie como preferir.
Espero que tenham gostado e em breve trarei novos artigos sobre o Vapor!




