Skip to content

Instantly share code, notes, and snippets.

@wildthink
Last active November 15, 2019 22:11
Show Gist options
  • Save wildthink/567608a37253da877eb6a2f69d7e99fc to your computer and use it in GitHub Desktop.
Save wildthink/567608a37253da877eb6a2f69d7e99fc to your computer and use it in GitHub Desktop.
Volatile Resource Wrapper inspired by Siesta
//
// Resource.swift
//
// Copyright (c) 2019 Jason Jobe. All rights reserved.
// https://gist.github.com/wildthink/567608a37253da877eb6a2f69d7e99fc
// Inspired by https://bustoutsolutions.github.io/siesta/
// Created by Jason Jobe on 5/11/19.
//
import Foundation
public class Resource<C: Codable> {
public enum State { case ready, requested, failed, received }
public let name: String
public let url: URL
public private(set) var value: C?
public private(set) var timestamp: Date?
public private(set) var last_error: Error?
public private(set) var state: State = .ready
public init (_ name: String, url: URL) {
self.name = name
self.url = url
}
public func decode(response: URLResponse?, data: Data) throws -> C? {
// FIXME: Confirm its really JSON
return try JSONDecoder().decode(C.self, from: data)
}
public func fetch (complete: ((Resource, URLResponse?) -> Void)? = nil) {
guard state != .requested else { return }
let task = URLSession.shared.dataTask(with: url) { [weak self]
(data, response, error) in
guard let self = self else { return }
if let data = data {
do {
self.value = try self.decode(response: response, data: data)
}
catch {
self.last_error = error
}
} else {
self.last_error = error
}
self.state = (self.last_error == nil ? .received : .failed)
self.timestamp = Date()
complete?(self, response)
}
state = .requested
timestamp = Date()
task.resume()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment