Swift: получение "неоднозначного выражения" при попытке передать кортеж функции обратного вызова

У меня есть этот класс для аутентификации пользователя против моего бэкэнда.

class BackendService {


class func performLogin(#email: String, password: String, success:((res: NSHTTPURLResponse, json: JSON, statusCode: HTTPStatus))->(), failure: (NSError)->()) {

    let loginURL = baseURL + "/login"
    let parameters = ["email": email, "password": password]

    Alamofire.request(.POST, loginURL, parameters: parameters).responseJSON { (req, res, json, err) in

        if(err != nil) {
            let response = (error: err!)
            failure(response)
        }
        else {


            if let httpStatus = HTTPStatus(rawValue: res!.statusCode) {
                let response = (res: res, json: JSON(json!) , statusCode: httpStatus)
                success(response)
            }
        }
    }

}

В success(response) я получаю Type of expression is ambiguous without more context. Есть идеи?

Есть ли лучший, более Swifty способ написать этот класс?

Ответ 1

Причина, по которой она не компилировалась, заключалась в том, что у вас был дополнительный набор круглых скобок вокруг объявления набора параметров успеха. Если вы их удалите, он будет скомпилирован. Здесь обновленная версия вашей функции имеет как можно меньше изменений, которые компилируются.

Вам нужно убедиться, что у вас есть baseURL.

class func performLogin(#email: String, password: String, success:(res: NSHTTPURLResponse, json: JSON, statusCode: HTTPStatus)->(), failure: (NSError)->()) {

    let loginURL = baseURL + "/login"
    let parameters = ["email": email, "password": password]

    Alamofire.request(.POST, loginURL, parameters: parameters).responseJSON { (req, res, json, err) in

        if (err != nil) {
            let response = (error: err!)
            failure(response)
        }
        else {
            if let httpStatus = HTTPStatus(rawValue: res!.statusCode) {
                let response = (res: res!, json: JSON(json!), statusCode: httpStatus)
                success(response)
            }
        }
    }
}

Здесь обновленная версия вашей оригинальной функции, которая, безусловно, более чистая, но еще не полностью безопасна. Хорошее эмпирическое правило - чем больше восклицательных знаков, тем больше риск.

typealias LoginSuccessHandler = (NSHTTPURLResponse, JSON, HTTPStatus) -> Void
typealias LoginFailureHandler = (NSError) -> Void

class func performLogin(#email: String, password: String, success: LoginSuccessHandler?, failure: LoginFailureHandler?) {
    let loginURL = baseURL + "/login"
    let parameters = ["email": email, "password": password]

    Alamofire.request(.POST, loginURL, parameters: parameters).responseJSON { request, response, json, error in
        if let error = error {
            failure?(error)
        } else {
            if let httpStatus = HTTPStatus(rawValue: response!.statusCode) {
                success?(response!, JSON(json!), httpStatus)
            }
        }
    }
}

Вы действительно должны взглянуть на замечательную логику проверки @mattt, встроенную в класс Alamofire.Request. Таким образом, вы можете полностью удалить нумерацию HTTPStatus.

  • public func validate() -> Self
  • public func validate(contentType array: [String]) -> Self
  • public func validate(statusCode array: [Int]) -> Self
  • public func validate(statusCode range: Range<Int>) -> Self
  • public func validate(validation: Validation) -> Self