如何在通用方法中使用快捷键路径

时间:2019-03-31 06:02:32

标签: swift generics swift5 swift-keypath

我尝试在我的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的解决方案而不是使用补全会更好,但是对于这个特定示例,我不想使用任何第三方库,因为我想看看是否没有他们就可以管理:)。

0 个答案:

没有答案