Skip to content

Instantly share code, notes, and snippets.

View Andrea-Scuderi's full-sized avatar

Andrea Scuderi Andrea-Scuderi

View GitHub Profile
@Andrea-Scuderi
Andrea-Scuderi / .swift
Last active August 1, 2019 14:00
Vapor API client for auth-template: Create User
import Cocoa
import Foundation
let baseURL = "http://localhost:8080"
enum APIError: Error {
case invalidBody
case invalidEndpoint
case invalidURL
case emptyData
@Andrea-Scuderi
Andrea-Scuderi / .swift
Last active August 1, 2019 09:57
Vapor API client for auth-template: Create User - part 2
import Combine
// With Combine we return a DataTaskPublisher instead of using the completion handler of the DataTask
func postUser(user: User) throws -> URLSession.DataTaskPublisher {
let headers = [
"Content-Type": "application/json",
"cache-control": "no-cache",
]
let encoder = JSONEncoder()
guard let postData = try? encoder.encode(user) else {
@Andrea-Scuderi
Andrea-Scuderi / .swift
Last active August 1, 2019 09:58
Vapor API client for auth-template: Create User - part 3
// In a real world App we want to decode our JSON data response into a Codable Object
struct CreateUserResponse: Codable {
let id: Int
let email: String
let name: String
}
// Decoding CreateUserResponse inside a DataTask API client
@Andrea-Scuderi
Andrea-Scuderi / .swift
Last active August 1, 2019 13:58
Vapor API client for auth-template: Create User - part 4
// Refactoring of the URLRequest with dataTask avoiding Throws using fatalError
func buildCreateUserURLRequest(user: User) -> URLRequest {
let headers = [
"Content-Type": "application/json",
"cache-control": "no-cache",
]
let encoder = JSONEncoder()
guard let postData = try? encoder.encode(user) else {
fatalError("APIError.invalidBody")
}
@Andrea-Scuderi
Andrea-Scuderi / .swift
Created July 31, 2019 16:37
Vapor API Client for auth-template - Part 4
//Login
func buildLoginRequest(email: String, password: String) throws -> URLRequest {
let loginString = String(format: "%@:%@", email, password)
let loginData: Data = loginString.data(using: .utf8)!
let base64LoginString = loginData.base64EncodedString()
let headers = [
"Content-Type": "application/json",
@Andrea-Scuderi
Andrea-Scuderi / .swift
Last active August 1, 2019 10:02
Part 5
// Completing the API with Combine and dataTaskPublisher
// POST - Login
func buildLoginRequest(email: String, password: String) -> URLRequest {
let loginString = String(format: "%@:%@", email, password)
let loginData: Data = loginString.data(using: .utf8)!
let base64LoginString = loginData.base64EncodedString()
@Andrea-Scuderi
Andrea-Scuderi / .swift
Last active August 1, 2019 10:18
Combine API - Part 7
//Let's use our brand new Publishers
let todoList = [Todo(id: nil, title: "Learn Composite"),
Todo(id: nil, title: "Learn SwiftUI")]
// use login to get the Bearer Token
let cancellableLogin = login(email: "[email protected]", password: "password2")
.sink(receiveCompletion: { (completion) in
switch completion {
// Use of the dataTaskPublisher API to implement Publisher with the decoded data
struct Token: Codable {
let string: String
}
// We'll use the following function to validate our dataTaskPublisher output in the pipeline
func validate(_ data: Data, _ response: URLResponse) throws -> Data {
guard let httpResponse = response as? HTTPURLResponse else {
throw APIError.invalidResponse
}
@Andrea-Scuderi
Andrea-Scuderi / .swift
Last active August 1, 2019 10:22
Part 8
// Combining login and postTodo in a single call
func post(email: String, password: String, todo: Todo) -> AnyPublisher<Todo, Error>? {
return login(email: email, password: password)
.map { token -> String in
return token.string
}
.flatMap { (token) -> AnyPublisher<Todo, Error> in
return postTodo(authToken: token, todo: todoList[1])
}
.eraseToAnyPublisher()
@Andrea-Scuderi
Andrea-Scuderi / .swift
Created September 3, 2019 10:23
CombineAPIDemo
import Combine
import Foundation
enum APIError: Error {
case invalidBody
case invalidEndpoint
case invalidURL
case emptyData
case invalidJSON
case invalidResponse