Skip to content

Instantly share code, notes, and snippets.

@omayib
Created April 26, 2017 06:04
Show Gist options
  • Save omayib/56152d931f0923292d9221bf180a822e to your computer and use it in GitHub Desktop.
Save omayib/56152d931f0923292d9221bf180a822e to your computer and use it in GitHub Desktop.
handling multiple data source in swift
//: Playground - noun: a place where people can play
import UIKit
import Foundation
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
enum Response<T> {
case succeed(T)
case failed(message: String)
}
enum DataManagerResult<T> {
case onNext(T)
case onFinished(T)
}
class Doctors : CustomStringConvertible {
var name: String?
var phoneNumber: String?
var isOnline: Bool?
init(name: String, phoneNumber: String, isOnline: Bool = false) {
self.name = name
self.phoneNumber = phoneNumber
self.isOnline = isOnline
}
public var description:String {
return "{name : \(name!) , phoneNumber : \(phoneNumber!) , isOnline : \(isOnline!)}"
}
}
//====================== REPOSITORY MODULE ==============
protocol Repository{
var consultans: [Doctors]{get set}
func dislayConsultans(completion: @escaping (Response<[Doctors]>)->())
}
protocol DataManagerCase{
func displayConsultans(completion: @escaping (DataManagerResult<[Doctors]>)->())
}
class CacheRepository : Repository {
var consultans: [Doctors] = []
init() {
}
func dislayConsultans(completion: @escaping (Response<[Doctors]>) -> ()) {
print("CacheRepository fetching....\(self.consultans.count)")
completion(Response.succeed(self.consultans))
}
}
class LocalRepository : Repository {
var consultans: [Doctors] = []
init() {
}
func dislayConsultans(completion: @escaping (Response<[Doctors]>) -> ()) {
print("localRepository fetching...")
DispatchQueue.main.asyncAfter(deadline: .now() + 2, execute: {
completion(Response.succeed(self.consultans))
})
}
}
class RemoteRepository : Repository {
var consultans: [Doctors] = []
init() {
}
func dislayConsultans(completion: @escaping (Response<[Doctors]>) -> ()) {
print("RemoteRepository fetching...")
DispatchQueue.main.asyncAfter(deadline: .now() + 3, execute: {
self.consultans.removeAll()
self.consultans.append(contentsOf: [Doctors(name: "c1", phoneNumber: "191",isOnline: true),
Doctors(name: "c2", phoneNumber: "092",isOnline: false),
Doctors(name: "c3", phoneNumber: "093",isOnline: true)])
completion(Response.succeed(self.consultans))
})
}
}
class DataManager {
var cache: Repository?
var local: Repository?
var remote: Repository?
var consultanss: [Doctors] = []
init() {
cache = CacheRepository()
local = LocalRepository()
remote = RemoteRepository()
}
func displayConsultans(completion: @escaping (DataManagerResult<[Doctors]>)->()){
self.cache?.dislayConsultans(completion: { response in
switch response{
case .failed(message: _):
break
case .succeed(let data):
if data.isEmpty {
return
}
self.consultanss.removeAll()
self.consultanss.append(contentsOf: data)
print("from cache")
completion(DataManagerResult.onNext(self.consultanss))
break
}
})
self.local?.dislayConsultans(completion: { response in
switch response{
case .failed(message: _):
break
case .succeed(let data):
if data.isEmpty {
return
}
//update the cache
self.cache?.consultans.removeAll()
self.cache?.consultans.append(contentsOf: data)
self.consultanss.removeAll()
self.consultanss.append(contentsOf: data)
print("from disk")
completion(DataManagerResult.onNext(self.consultanss))
break
}
})
self.remote?.dislayConsultans(completion: { response in
switch response{
case .failed(message: _):
break
case .succeed(let data):
if data.isEmpty {
return
}
//update the cache
self.cache?.consultans.removeAll()
self.cache?.consultans.append(contentsOf: data)
//update the local
self.local?.consultans.removeAll()
self.local?.consultans.append(contentsOf: data)
self.consultanss.removeAll()
self.consultanss.append(contentsOf: data)
print("from remote")
break
}
})
DispatchQueue.main.asyncAfter(deadline: .now() + 3.0, execute: {
completion(DataManagerResult.onFinished(self.consultanss))
})
}
}
class Context{
let dataManager: DataManager
init() {
dataManager = DataManager()
}
func execute(){
dataManager.displayConsultans { result in
switch result{
case .onNext(let data):
print("onNext. refreash \(data)")
break
case .onFinished(let data):
print("onFinished. refreash \(data)")
break
}
}
}
}
let app = Context()
app.execute()
DispatchQueue.main.asyncAfter(deadline: .now()+10) {
print("============load again================")
app.execute()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment