evermeer / AlamofireJsonToObjects

An Alamofire extension which converts JSON response data into swift objects using EVReflection
Other
161 stars 28 forks source link

Migration help needed #28

Closed Dbigshooter closed 8 years ago

Dbigshooter commented 8 years ago

Hi there,

I've trying to use the Swift 3 branch, and adopt some thing to Alamofire 4. I get this warning, and I can't quite understand it? This is my code:

`Alamofire.request(apiURL + "users", headers: headers).responseObject { (response: Result<User>) in
                if let user = response.value {
                    completionHandler(user, nil);
                } else {
                    completionHandler(nil, response.error as NSError?);
                }
            }
    }
`

My previous code looked like this:

Alamofire.request(.GET, apiURL + "users", headers: headers).responseObject { (response: Result<User, Error>) in
                if let user = response.value {
                    print(user)
                    completionHandler(user, nil);
                } else {
                    completionHandler(nil, response.error);
                }
            }
    }

However this gives me this error: Generic type Result specialized with too many type parameters (got 2, but expected 1)

I also seem to get another, for me, not understandable error in this piece of code


func getPackage(completionHandler: @escaping (Package?, NSError?) -> ()){

        Alamofire.request(URL + "package", method: .get, headers: headers())
            .responseObject { (response: Result<Package>) in
                if let userPackage = response.value {
                    print(userPackage);

                    completionHandler(userPackage, nil);
                } else {
                    completionHandler(nil, response.error);
                }
        }
    }

This gives me the following error: Cannot convert value of type '(Result<Package>) -> ()' to expected argument type '(URLRequest?, HTTPURLResponse?, Result<_>) -> Void'

evermeer commented 8 years ago

Indeed you don't have to specify the Error anymore for the result object. So At first you had 2 parameters <User, Error> and now you only have 1

As for the second error it looks like you have to call it with something like:


            Alamofire.request(URL + "package", method: .get, headers: headers())
                .responseObject { (request: URLRequest?, HTTPURLResponse: HTTPURLResponse?, response: Result<Package>) in
Dbigshooter commented 8 years ago

@evermeer I thought so, but when I implement it as you above, I get:

Contextual closure tye '(Result<_>) -> Void' expects 1 argument, but 3 were used in closure body

evermeer commented 8 years ago

It looks like Alamofire.request only has these function signatures now or am I missing something?

            Alamofire.request(URLConvertible)
            Alamofire.request(URLConvertible, method: HTTPMethod, parameters: Parameters?, encoding: ParameterEncoding, headers: HTTPHeaders?)
            Alamofire.request(URLRequestConvertible)

So you should rewrite it to one of these then...

Dbigshooter commented 8 years ago

@evermeer I've tried, I ended up with this:

func getPackage(completionHandler: @escaping (Package?, NSError?) -> ()){
Alamofire.request("\(apiURL)package", method: .get, parameters: nil, headers: headers()).responseObject { ( response: Result<Package>) in
            if let Package = response.value {
                print(Package);

                completionHandler(Package, nil);
            } else {
                completionHandler(nil, response.error);
            }

        }
}

Still gives me: Cannot convert value of type '(Result<Package>) -> ()' to expected argument type '(URLRequest?, HTTPURLResponse?, Result<_>) -> Void' And if I try to add those, so my code looks like this:

func getPackage(completionHandler: @escaping (Package?, NSError?) -> ()){
Alamofire.request("\(apiURL)package", method: .get, parameters: nil, headers: headers()).responseObject { ( request: URLRequest?, HTTPURLResponse: HTTPURLResponse?, response: Result<Package>) in
            if let Package = response.value {
                print(Package);

                completionHandler(Package, nil);
            } else {
                completionHandler(nil, response.error);
            }

        }
}        

I get: Contextual closure type '(Result<_>) -> Void' expects 1 argument, but 3 were used in closure body

Dbigshooter commented 8 years ago

@evermeer Am I the only one experiencing this problem?

shaljam commented 8 years ago

Mine working with something like this:

        Alamofire.request(uri).responseObject { (response: Result<RegisterResponse>) in
            if let result = response.value {

                //
            }
        }

with following pods:

   pod 'Alamofire', '~> 4.0'
   pod 'IQKeyboardManagerSwift', '4.0.6'
   pod 'EVReflection', :git => 'https://github.com/evermeer/EVReflection.git', :branch => 'Swift3'
   pod 'AlamofireJsonToObjects', :git => 'https://github.com/evermeer/AlamofireJsonToObjects.git', :branch => 'Swift3'
Dbigshooter commented 8 years ago

@shaljam I can get that to work as well. The problem occurs when I want to add in parameters and headers. Can you get that to work?

evermeer commented 8 years ago

OK... I have done a complete refactor of AlamofireJsonToObject. All 3 types of Alamofire.request methods are now supported. See testResponseObject1, 2 and 3 at: https://github.com/evermeer/AlamofireJsonToObjects/blob/Swift3/AlamofireJsonToObjectsTests/AlamofireJsonToObjectsTests.swift#L100 The syntax is a little different:

Here are the 3 samples:

       Alamofire.request(URL)
            .responseObject { (response: DataResponse<WeatherResponse>) in

        Alamofire.request(URLRequestConvertible)
            .responseObject { (response: DataResponse<WeatherResponse>) in

        Alamofire.request(URL, method: HTTPMethod.get, parameters: nil, encoding: URLEncoding.default, headers: nil)
            .responseObject { (response: DataResponse<WeatherResponse>) in

If you want the same result object, then you can now get response.result. You can also access the URLRequest with response.request, the HTTPURLResponse by response.response the raw Data with response.data and you can have some nice statistics by using result.timeline

Dbigshooter commented 8 years ago

@evermeer Works like a charm! Thanks for your attention!