Skip to content

Instantly share code, notes, and snippets.

@robmathers
Forked from chriseidhof/nsnorth.swift
Created April 29, 2019 15:26
Show Gist options
  • Save robmathers/ee9464d4e129722784632fe88813b7d5 to your computer and use it in GitHub Desktop.
Save robmathers/ee9464d4e129722784632fe88813b7d5 to your computer and use it in GitHub Desktop.
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var rootVC: UINavigationController? = nil
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
window = UIWindow(frame: UIScreen.main.bounds)
window?.backgroundColor = .white
let tableVC = ListsViewController(style: .plain)
rootVC = UINavigationController(rootViewController: tableVC)
window?.rootViewController = rootVC
window?.makeKeyAndVisible()
return true
}
}
struct List: Codable {
var name: String
var id: Int
}
struct Todo: Codable {
var title: String
var done: Bool
}
let listsURL = URL(string: "http://localhost:8000/lists.json")!
func todosURL(listId: Int) -> URL {
return URL(string: "http://localhost:8000/lists/\(listId)/todos.json")!
}
struct UnknownError: Error { }
extension URLSession {
func dataTask(with url: URL, completionHandler: @escaping (Result<Data,Error>) -> Void) -> URLSessionDataTask {
return dataTask(with: url, completionHandler: { (data, response, error) in
guard let d = data else {
completionHandler(.failure(error ?? UnknownError()))
return
}
completionHandler(.success(d))
})
}
func load<A>(_ resource: Resource<A>, completionHandler: @escaping (Result<A, Error>) -> ()) {
dataTask(with: resource.url, completionHandler: { result in
switch result {
case let .failure(error):
completionHandler(.failure(error))
case let .success(data):
completionHandler(resource.parse(data))
}
}).resume()
}
}
// For videos on this, see https://talk.objc.io/collections/networking
struct Resource<A> {
let url: URL
let parse: (Data) -> Result<A, Error>
}
extension Resource where A: Codable {
init(json url: URL) {
self.url = url
self.parse = { data in
return Result { try JSONDecoder().decode(A.self, from: data) }
}
}
}
let listsResource = Resource<[List]>(json: listsURL)
final class ListsViewController: UITableViewController {
var lists: [List] = [] {
didSet {
tableView.reloadData()
}
}
override func viewDidLoad() {
URLSession.shared.load(listsResource) { (result) in
switch result {
case let .failure(error):
print("Got an error: \(error)")
case let .success(lists):
DispatchQueue.main.async {
self.lists = lists
}
}
}
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return lists.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .default, reuseIdentifier: nil)
cell.textLabel?.text = lists[indexPath.row].name
return cell
}
}
// For more information, see the paper "Theorems for Free": https://people.mpi-sws.org/~dreyer/tor/papers/wadler.pdf
func foo<A, B>(_ x: A, _ y: B) -> (B, A) {
return (y,x)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment