Last active
January 30, 2020 06:34
-
-
Save hmhmsh/21959eaaae33601de1b0e639763d06e4 to your computer and use it in GitHub Desktop.
非同期処理でcompletionをメソッドチェーンで書く
This file contains hidden or 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
struct DataProvider<T: Decodable> { | |
let function: (@escaping (Result<T, Error>) -> Void) -> Void | |
func completion(_ completion: @escaping (Result<T, Error>) -> Void) { | |
function(completion) | |
} | |
} |
This file contains hidden or 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
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() | |
} | |
} |
This file contains hidden or 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
// 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