Skip to content

Instantly share code, notes, and snippets.

View dmytro-anokhin's full-sized avatar
🔨

Dmytro Anokhin dmytro-anokhin

🔨
View GitHub Profile
protocol RemoteContent : ObservableObject {
associatedtype Value
var loadingState: RemoteContentLoadingState<Value> { get }
func load()
func cancel()
}
enum RemoteContentLoadingState<Value> {
case initial
case inProgress
case success(_ value: Value)
case failure(_ error: Error)
}
let view: PostView
if useNetworkingA {
let postsDataProviderA = PostsDataProviderA()
view = PostView(dataProvider: postsDataProviderA)
}
else {
let postsDataProviderB = PostsDataProviderB()
view = PostView(dataProvider: postsDataProviderB)
}
struct PostsDataProviderA: DataProvider {
let networkService: NetworkingA
let userService: UserService
func fetchPosts(withURL url: URL, completion: @escaping (Result<[Post], Error>) -> Void) {
networkService.loadJSON(withURL: url, type: [Post].self, completion: completion)
}
func fetchUser(withId id: Int, completion: @escaping (User?) -> Void) {
protocol DataProvider {
func fetchPosts(withURL url: URL, completion: @escaping (Result<[Post], Error>) -> Void)
func fetchUser(withId id: Int, completion: @escaping (User?) -> Void)
}
struct PostView: View {
let userService: UserService
if useNetworkingA {
let networkServiceA = NetworkServiceA()
userService = UserService(networkService: networkServiceA)
}
else {
let networkServiceB = NetworkServiceB()
userService = UserService(networkService: networkServiceB)
}
extension NetworkingA: UserNetworkService {
func loadUsers(withURL url: URL, completion: @escaping (Result<[User], Error>) -> Void) {
loadJSON(withURL: url, type: [User].self, completion: completion)
}
}
extension NetworkingB: UserNetworkService {
protocol UserNetworkService {
func loadUsers(withURL url: URL, completion: @escaping (Result<[User], Error>) -> Void)
}
class UserService {
let networkService: UserNetworkService
import Foundation
class NetworkingA {
func loadJSON<T: Decodable>(withURL url: URL, type: T.Type = T.self, completion: @escaping (Result<T, Error>) -> Void) {
urlSession.dataTask(with: url) { data, response, error in
// ...
}.resume()
}
}
extension ImageDecoder {
/// Creates static or animated image depending on `frameCount`.
var uiImage: UIImage?
/// Creates animated image if there is more than one frame.
var animatedUIImage: UIImage?
/// Creates static image from the first frame.
var staticUIImage: UIImage?