Skip to content

Instantly share code, notes, and snippets.

@jamiepinkham
Last active December 15, 2020 08:35
Show Gist options
  • Save jamiepinkham/5f6258841255c75ed06675d561f85ecb to your computer and use it in GitHub Desktop.
Save jamiepinkham/5f6258841255c75ed06675d561f85ecb to your computer and use it in GitHub Desktop.
//
// ScrumData.swift
// Scrumdinger
//
// Created by Jamie Pinkham on 12/15/20.
//
import SwiftUI
import Combine
//whatever
enum ScrumDataProviderError: Error {
case underlying(Error)
}
protocol ScrumDataProvider {
func load() -> AnyPublisher<[DailyScrum], ScrumDataProviderError>
func save(_ scrums: [DailyScrum]) -> AnyPublisher<Void, ScrumDataProviderError>
}
//here's the logic from the Apple sample, expressed as a ScrumDataProvider
final class DocumentsProvider: ScrumDataProvider {
func load() -> AnyPublisher<[DailyScrum], ScrumDataProviderError> {
return AnyPublisher(Future { promise in
guard let data = try? Data(contentsOf: Self.fileURL) else {
#if DEBUG
promise(.success(DailyScrum.data))
#endif
return
}
do {
let dailyScrums = try JSONDecoder().decode([DailyScrum].self, from: data)
promise(.success(dailyScrums))
} catch let error {
promise(.failure(ScrumDataProviderError.underlying(error)))
}
})
}
func save(_ scrums: [DailyScrum]) -> AnyPublisher<Void, ScrumDataProviderError> {
return AnyPublisher(
Future { promise in
do {
let data = try JSONEncoder().encode(scrums)
let outfile = Self.fileURL
promise(.success(try data.write(to: outfile)))
} catch let error {
promise(.failure(.underlying(error)))
}
}
)
}
private static var documentsFolder: URL {
do {
return try FileManager.default.url(for: .documentDirectory,
in: .userDomainMask,
appropriateFor: nil,
create: false)
} catch {
//oops, seems unrecoverable to me.
fatalError("Can't find documents directory.")
}
}
private static var fileURL: URL {
return documentsFolder.appendingPathComponent("scrums.data")
}
}
class ScrumData: ObservableObject {
@Published var scrums: [DailyScrum] = []
let provider: ScrumDataProvider
init(provider: ScrumDataProvider = DocumentsProvider()) {
self.provider = provider
}
func load() {
provider.load().replaceError(with: []).assign(to: &$scrums)
}
func save() {
provider.save(scrums) //uh-oh what do we do with all those fatal errors we had!?
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment