Last active
December 15, 2020 08:35
-
-
Save jamiepinkham/5f6258841255c75ed06675d561f85ecb to your computer and use it in GitHub Desktop.
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
// | |
// 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