Skip to content

Instantly share code, notes, and snippets.

@hmhmsh
Last active January 30, 2020 06:34
Show Gist options
  • Save hmhmsh/21959eaaae33601de1b0e639763d06e4 to your computer and use it in GitHub Desktop.
Save hmhmsh/21959eaaae33601de1b0e639763d06e4 to your computer and use it in GitHub Desktop.
非同期処理でcompletionをメソッドチェーンで書く
struct DataProvider<T: Decodable> {
let function: (@escaping (Result<T, Error>) -> Void) -> Void
func completion(_ completion: @escaping (Result<T, Error>) -> Void) {
function(completion)
}
}
enum DataStoreError: Error {
case urlSessionValueError
}
protocol DataStoreProtocol {
func dataTask<T: Decodable>(urlRequest: URLRequest, completion: @escaping (Result<T, Error>) -> Void)
}
extension DataStoreProtocol {
func dataTask<T: Decodable>(urlRequest: URLRequest, completion: @escaping (Result<T, Error>) -> Void) {
URLSession
.shared
.dataTask(with: urlRequest) { data, _, error in
switch (data, error) {
case (let data?, _):
do {
let entity = try JSONDecoder().decode(T.self, from: data)
completion(.success(entity))
} catch let error {
completion(.failure(error))
}
case (_, let error?):
completion(.failure(error))
default:
completion(.failure(DataStoreError.urlSessionValueError))
}
}
.resume()
}
}
// DataStore for login
struct LoginDataStore: DataStoreProtocol {
enum LoginError: Error {
case cannnotConvertToUrl
}
func login(id: String, password: String) -> DataProvider<UserEntity> {
return DataProvider { completion in
guard let url = URL(string: "https:/host/login?" + "id=" + id + "&" + "password=" + password) else {
completion(.failure(LoginError.cannnotConvertToUrl))
return
}
var urlRequest = URLRequest(url: url)
urlRequest.httpMethod = "post"
self.dataTask(urlRequest: urlRequest, completion: completion)
}
}
}
// Login entity
struct UserEntity: Codable {
let token: String
}
// usage
let dataStore = LoginDataStore()
dataStore
.login(id: "id", password: "pass")
.completion { result in
switch result {
case .success(let user):
print(user)
case .failure(let error):
print(error)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment