Last active
August 7, 2017 09:24
-
-
Save andreacipriani/574fa2975c14b0e5c8b53ff628418c31 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
import Foundation | |
// Models: | |
struct TrackModel { | |
let title: String | |
} | |
struct UserModel { | |
let name: String | |
} | |
struct PlaylistModel { | |
let genre: String | |
} | |
enum RepositoryData { | |
case tracks([TrackModel]) | |
case users([UserModel]) | |
case playlists([PlaylistModel]) | |
} | |
// Interfaces: | |
enum Result<RepositoryData,Error> { | |
case success(RepositoryData) | |
case failure(Error) | |
} | |
protocol Fetching { | |
func fetch(completion: @escaping ((Result<RepositoryData, Error>) -> ())) | |
} | |
protocol RepositoryChaining: Fetching { | |
var next: RepositoryChaining? { get } | |
} | |
class RepositoryChain: RepositoryChaining { | |
let fetcher: Fetching | |
var next: RepositoryChaining? | |
init(fetcher: Fetching, next: RepositoryChaining? = nil) { | |
self.fetcher = fetcher | |
self.next = next | |
} | |
func fetch(completion: @escaping ((Result<RepositoryData, Error>) -> ())) { | |
fetcher.fetch { result in | |
switch result { | |
case .success(let entity): | |
//execute success operation? | |
completion(.success(entity)) | |
case .failure(let error): | |
//execute failure operation? | |
if self.next != nil { | |
self.next?.fetch(completion: completion) | |
} else { | |
completion(.failure(error)) | |
} | |
} | |
} | |
} | |
} | |
// Fetchers: | |
class CoreDataFetcher: Fetching { | |
let failing: Bool | |
init(failing: Bool = false) { | |
self.failing = failing | |
} | |
func fetch(completion: @escaping ((Result<RepositoryData, Error>) -> ())) { | |
let tracks = [TrackModel(title: "track from core data")] | |
failing ? completion(.failure(NSError())) : completion(.success(.tracks(tracks))) | |
} | |
} | |
class NetworkFetcher: Fetching { | |
let failing: Bool | |
init(failing: Bool = false) { | |
self.failing = failing | |
} | |
func fetch(completion: @escaping ((Result<RepositoryData, Error>) -> ())) { | |
let tracks = [TrackModel(title: "track from the network")] | |
failing ? completion(.failure(NSError())) : completion(.success(.tracks(tracks))) | |
} | |
} | |
class RepositoryFactory { | |
static func makeCoreDataNewtworkRepo() -> Fetching { | |
let networkRepo = RepositoryChain(fetcher: NetworkFetcher()) | |
return RepositoryChain(fetcher: CoreDataFetcher(failing: true), next: networkRepo) | |
} | |
} | |
// Example: | |
let coreDataNewtorkRepo = RepositoryFactory.makeCoreDataNewtworkRepo() | |
coreDataNewtorkRepo.fetch { result in | |
print(result) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment