我尝试在我的Repository
类中重构几个通用方法,这些方法为API调用创建完成闭包。我要实现的主要更改是实现新的Swift 5 Result
类型,并进一步概括完成。
以前的版本(和工作版本)如下:
private func getAllCompletion<T>(_ type: T.Type, completion: (() -> Void)?) throws -> ((GetResourceRequest<T>) -> Void) where T: Codable{
switch type {
case is Acronym.Type:
return getCompletion(for: \Repository.acronyms, completion: completion) as! ((GetResourceRequest<T>) -> Void)
case is User.Type:
return getCompletion(for: \Repository.users, completion: completion) as! ((GetResourceRequest<T>) -> Void)
case is Category.Type:
return getCompletion(for: \Repository.categories, completion: completion) as! ((GetResourceRequest<T>) -> Void)
default:
throw ErrorFactory.invalidType(type).error
}
}
private func getCompletion<T>(for keyPath: ReferenceWritableKeyPath<Repository, [T]>, completion: (() -> Void)?) -> ((GetResourceRequest<T>) -> Void) {
return {[weak self] resourceRequest in
switch resourceRequest {
case .success(let resource):
self?[keyPath: keyPath] = resource
case .failure:
break
}
completion?()
}
}
我重构并尝试以这种方式将其概括化:
private func getCompletion<ResourceType>(_ type: ResourceType.Type, completion: ((Error) -> Void)?) -> ((Result<ResourceType, Error>) -> Void) where ResourceType: Codable{
switch type {
case is [Acronym].Type:
getCompletion(for: \Repository.acronyms, with: completion)
case is [User].Type:
getCompletion(for: \Repository.users, with: completion)
case is [Category].Type:
getCompletion(for: \Repository.categories, with: completion)
default:
let error = ErrorFactory.invalidType(type).error
completion?(error)
}
}
private func getCompletion<ResourceType>(for keyPath: ReferenceWritableKeyPath<Repository, ResourceType>, with completion: ((Error?) -> Void)?) -> ((Result<ResourceType, Error>) -> Void) {
return { [weak self] result in
switch result {
case .success(let resource):
self?[keyPath: keyPath] = resource
completion?(nil)
case .failure(let error):
completion?(error)
}
}
}
我无法弄清我想念的是什么,但是它无法编译。我在所有三个getCompletion(for:completion)
通话中收到的消息如下:
Cannot convert value of type 'ReferenceWritableKeyPath<Repository, [Acronym]>' to expected argument type 'ReferenceWritableKeyPath<Repository, _>'
在此先感谢您的回答,如果我确实缺少一些明显的内容,对不起。
我还知道,使用基于Rx
的解决方案而不是使用补全会更好,但是对于这个特定示例,我不想使用任何第三方库,因为我想看看是否没有他们就可以管理:)。