mirror of
https://github.com/ivanvorobei/SwiftUI.git
synced 2026-03-31 14:33:39 +02:00
Add examples project
This commit is contained in:
41
Examples/GitHub Search/GitHubSearchWithSwiftUI/Extension/Combine.swift
Executable file
41
Examples/GitHub Search/GitHubSearchWithSwiftUI/Extension/Combine.swift
Executable file
@@ -0,0 +1,41 @@
|
||||
//
|
||||
// Combine.swift
|
||||
// GitHubSearchWithSwiftUI
|
||||
//
|
||||
// Created by marty-suzuki on 2019/06/05.
|
||||
// Copyright © 2019 jp.marty-suzuki. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct CombineExtension<Base> {
|
||||
let base: Base
|
||||
|
||||
init(_ base: Base) {
|
||||
self.base = base
|
||||
}
|
||||
}
|
||||
|
||||
protocol CombineCompatible {
|
||||
associatedtype CombineExtensionBase
|
||||
|
||||
static var combine: CombineExtension<CombineExtensionBase>.Type { get set }
|
||||
var combine: CombineExtension<CombineExtensionBase> { get set }
|
||||
}
|
||||
|
||||
extension CombineCompatible {
|
||||
|
||||
static var combine: CombineExtension<Self>.Type {
|
||||
get {
|
||||
return CombineExtension<Self>.self
|
||||
}
|
||||
set {}
|
||||
}
|
||||
|
||||
var combine: CombineExtension<Self> {
|
||||
get {
|
||||
return CombineExtension<Self>(self)
|
||||
}
|
||||
set {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
//
|
||||
// JSONDecoder.Extension.swift
|
||||
// GitHubSearchWithSwiftUI
|
||||
//
|
||||
// Created by marty-suzuki on 2019/06/06.
|
||||
// Copyright © 2019 jp.marty-suzuki. All rights reserved.
|
||||
//
|
||||
|
||||
import Combine
|
||||
import Foundation
|
||||
|
||||
extension JSONDecoder: TopLevelDecoder {}
|
||||
@@ -0,0 +1,58 @@
|
||||
//
|
||||
// URLSession.Combine.swift
|
||||
// GitHubSearchWithSwiftUI
|
||||
//
|
||||
// Created by marty-suzuki on 2019/06/05.
|
||||
// Copyright © 2019 jp.marty-suzuki. All rights reserved.
|
||||
//
|
||||
|
||||
import Combine
|
||||
import Foundation
|
||||
|
||||
extension URLSession: CombineCompatible {}
|
||||
|
||||
extension CombineExtension where Base == URLSession {
|
||||
|
||||
func send(request: URLRequest) -> AnyPublisher<Data, URLSessionError> {
|
||||
|
||||
AnyPublisher<Data, URLSessionError> { [base] subscriber in
|
||||
|
||||
let task = base.dataTask(with: request) { data, response, error in
|
||||
|
||||
guard let response = response as? HTTPURLResponse else {
|
||||
subscriber.receive(completion: .failure(.invalidResponse))
|
||||
return
|
||||
}
|
||||
|
||||
guard 200..<300 ~= response.statusCode else {
|
||||
let e = URLSessionError.serverError(statusCode: response.statusCode,
|
||||
error: error)
|
||||
subscriber.receive(completion: .failure(e))
|
||||
return
|
||||
}
|
||||
|
||||
guard let data = data else {
|
||||
subscriber.receive(completion: .failure(.noData))
|
||||
return
|
||||
}
|
||||
|
||||
if let error = error {
|
||||
subscriber.receive(completion: .failure(.unknown(error)))
|
||||
} else {
|
||||
_ = subscriber.receive(data)
|
||||
subscriber.receive(completion: .finished)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: cancel task when subscriber cancelled
|
||||
task.resume()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum URLSessionError: Error {
|
||||
case invalidResponse
|
||||
case noData
|
||||
case serverError(statusCode: Int, error: Error?)
|
||||
case unknown(Error)
|
||||
}
|
||||
Reference in New Issue
Block a user