Created
November 16, 2016 16:02
-
-
Save cmoulton/733356fd0a29411153155606c0cdc2ba to your computer and use it in GitHub Desktop.
Demo code for Strongly-Typed GET and POST Calls With Alamofire at https://grokswift.com/strongly-typed-api-calls/. Uses Swift 3.0 and Alamofire 4.0.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
import Alamofire | |
enum BackendError: Error { | |
case objectSerialization(reason: String) | |
} | |
extension Todo { | |
class func endpointForID(_ id: Int) -> String { | |
return "https://jsonplaceholder.typicode.com/todos/\(id)" | |
} | |
class func endpointForTodos() -> String { | |
return "https://jsonplaceholder.typicode.com/todos/" | |
} | |
convenience init?(json: [String: Any]) { | |
guard let title = json["title"] as? String, | |
let userId = json["userId"] as? Int, | |
let completed = json["completed"] as? Bool | |
else { | |
return nil | |
} | |
let idValue = json["id"] as? Int | |
self.init(title: title, id: idValue, userId: userId, completedStatus: completed) | |
} | |
func toJSON() -> [String: Any] { | |
var json = [String: Any]() | |
json["title"] = title | |
if let id = id { | |
json["id"] = id | |
} | |
json["userId"] = userId | |
json["completed"] = completed | |
return json | |
} | |
class func todoByID(_ id: Int, completionHandler: @escaping (Result<Todo>) -> Void) { | |
Alamofire.request(Todo.endpointForID(id)) | |
.responseJSON { response in | |
let result = Todo.todoFromResponse(response: response) | |
completionHandler(result) | |
} | |
} | |
func save(completionHandler: @escaping (Result<Todo>) -> Void) { | |
let fields = self.toJSON() | |
Alamofire.request(Todo.endpointForTodos(), | |
method: .post, | |
parameters: fields, | |
encoding: JSONEncoding.default, | |
headers: nil) | |
.responseJSON { response in | |
let result = Todo.todoFromResponse(response: response) | |
completionHandler(result) | |
} | |
} | |
private class func todoFromResponse(response: DataResponse<Any>) -> Result<Todo> { | |
guard response.result.error == nil else { | |
// got an error in getting the data, need to handle it | |
print(response.result.error!) | |
return .failure(response.result.error!) | |
} | |
// make sure we got JSON and it's a dictionary | |
guard let json = response.result.value as? [String: Any] else { | |
print("didn't get todo object as JSON from API") | |
return .failure(BackendError.objectSerialization(reason: | |
"Did not get JSON dictionary in response")) | |
} | |
// turn JSON in to Todo object | |
guard let todo = Todo(json: json) else { | |
return .failure(BackendError.objectSerialization(reason: | |
"Could not create Todo object from JSON")) | |
} | |
return .success(todo) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
class Todo { | |
var title: String | |
var id: Int? | |
var userId: Int | |
var completed: Bool | |
required init?(title: String, id: Int?, userId: Int, completedStatus: Bool) { | |
self.title = title | |
self.id = id | |
self.userId = userId | |
self.completed = completedStatus | |
} | |
func description() -> String { | |
return "ID: \(self.id), " + | |
"User ID: \(self.userId), " + | |
"Title: \(self.title)\n" + | |
"Completed: \(self.completed)\n" | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
class ViewController: UIViewController { | |
override func viewWillAppear(_ animated: Bool) { | |
super.viewDidAppear(animated) | |
// MARK: Get Todo #1 | |
Todo.todoByID(1) { result in | |
if let error = result.error { | |
// got an error in getting the data, need to handle it | |
print("error calling POST on /todos/") | |
print(error) | |
return | |
} | |
guard let todo = result.value else { | |
print("error calling POST on /todos/ - result is nil") | |
return | |
} | |
// success! | |
print(todo.description()) | |
print(todo.title) | |
} | |
// MARK: Create new todo | |
guard let newTodo = Todo(title: "My first todo", | |
id: nil, | |
userId: 1, | |
completedStatus: true) else { | |
print("error: newTodo isn't a Todo") | |
return | |
} | |
newTodo.save { result in | |
guard result.error == nil else { | |
// got an error in getting the data, need to handle it | |
print("error calling POST on /todos/") | |
print(result.error!) | |
return | |
} | |
guard let todo = result.value else { | |
print("error calling POST on /todos/. result is nil") | |
return | |
} | |
// success! | |
print(todo.description()) | |
print(todo.title) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment