处理闭包 - 使代码更通用

时间:2016-01-06 16:35:22

标签: ios swift closures

有两个功能,如下所示。大多数功能在两者中都是相同的。它的想法是从getResponse()[Helper Callback]获取webservice的输出,解析并通过getResult()将信息传递给包装器回调。

 static func getAllDealers(dealerSearchServiceDomain: ARSDealerSearchServiceDomain, wrapperCallback:(getResult: () throws -> Void) -> Void) throws
    {
        try ARSInputValidator.validateZipCode(dealerSearchServiceDomain.zip)

        try ARSDealerConnection.getAllDealers(dealerSearchServiceDomain, helperCallback: { (getResponse) -> Void in

            do
            {
                let result = try getResponse()

                try ARSDealerParser.parseDealerSearchResponse(dealerSearchServiceDomain)

                wrapperCallback(getResult: { return })
            }
            catch
            {
                wrapperCallback(getResult: { throw error })
            }
        })
    }

    static func getDealerDetails(dealerDetailsServiceDomain: ARSDealerDetailsServiceDomain, wrapperCallback:(getResult: () throws -> Void) -> Void) throws
    {
        try ARSDealerConnection.getDealerDetails(dealerDetailsServiceDomain, helperCallback: { (getResponse) -> Void in

            do
            {
                let result = try getResponse()

                try ARSDealerParser.parseDealerDetailsResponse(dealerDetailsServiceDomain)

                wrapperCallback(getResult: { return })
            }
            catch
            {
                wrapperCallback(getResult: { throw error })
            }

        })
    }

我正在尝试为常用功能添加单独的功能,例如

static func parser(serviceCallDomain: ARSServiceCallDomain ,wrapperCallback:(getResult:() throws -> String) -> Void,  helperCallback:(getResponse:() throws -> String) -> Void) throws
    {
        helperCallback { (getResponse) -> Void in

但是有一个编译错误&我无法完成它。有15个以上的Web服务调用,所以我正在尝试的常见显示将非常有帮助。

下一步,我还需要传递函数parseDealerSearchResponse()& parseDealerDetailsResponse()到公共函数。

我是封闭新手。请帮助。

//编辑 - 添加样本

我在Git中有一个问题示例 - 请参阅Layer1.swift类 https://github.com/vivinjeganathan/ErrorHandling/tree/Closures-Refactor

1 个答案:

答案 0 :(得分:1)

我认为重构代码的最佳方法是定义一个处理一些常见功能的函数,如解析和验证,最终将完成闭包调用回控制器,如下所示:

static func handleResponse(parser: Parser, validator: Validator, getResult: () throws -> AnyObject, completion: (getParsedResult: () throws -> AnyObject) -> Void)  {
    do
    {
        let result = try getResult()
        let parsedObject = try parser.parse(result)
        try validator.validate(parsedObject)
        completion(getParsedResult: { return parsedObject })
    }
    catch
    {
        completion(getParsedResult: { throw error })
    }
}

注意它接收到解析器,验证器,从下面的层捕获结果的闭包以及属于最终用户(通常是View Controller)的完成闭包,然后可以像这样使用此函数: / p>

static func getAllDealers(dealerSearchServiceDomain: AnyObject, wrapperCallback:(getResult: () throws -> AnyObject) -> Void) throws {
    let validator = DealersValidator() // create real validator
    let parser = DealersParser() // create real parser

    try validator.validate(dealerSearchServiceDomain)

    try ARSDealerConnection.getAllDealers(dealerSearchServiceDomain, helperCallback: { (getResponse) -> Void in
        self.handleResponse(parser, validator: validator, getResult: getResponse, completion: wrapperCallback)
    })
}

在这种情况下handleResponsegetAllDealers位于同一个类中,但它实际上可以是每个服务都可以调用的全局函数。

我认为使用泛型编写更好的实现可能是可能的,但它不会比这短得多,最终你可以避免创建验证器和解析器并调用下一层。