Alamofire POST request with Swift 2
Asked Answered
C

2

6

I am trying to make a POST request in Alamofire to return a JSON object. This code worked in Swift 1, but in swift 2 I get this invalid parameter issue:

Tuple types '(NSURLRequest?, NSHTTPURLResponse?, Result<AnyObject>)' (aka '(Optional<NSURLRequest>, Optional<NSHTTPURLResponse>, Result<AnyObject>)') and '(_, _, _, _)' have a different number of elements (3 vs. 4)

It seems like the error parameter was removed, but I am using the error parameter inside the function to check for errors, so how would I do that without an error param?

Here's my code for the POST request:

            let response = Alamofire.request(.POST, urlPath, parameters: parameters, encoding: .URL)
            .responseJSON { (request, response, data, error) in
                if let anError = error
                {
                    // got an error in getting the data, need to handle it
                    print("error calling POST on /posts")
                    print(error)
                }
                else if let data: AnyObject = data
                {
                    // handle the results as JSON, without a bunch of nested if loops
                    let post = JSON(data)
                    // to make sure it posted, print the results
                    print("The post is: " + post.description)
                }
        }
Clericals answered 28/8, 2015 at 18:35 Comment(2)
man, sorry for offtop, but can you please help me with steps to add alamofire into xcode 7 beta 6? I can't do it as earlier because in "linked framework" I dont see alamofire. thx)Lucylud
You need to add the pod for the swift 2 branch, your Podfile for Alamofire should look like this: pod 'Alamofire', :git => 'github.com/Alamofire/Alamofire.git', :branch => 'swift-2.0'Clericals
T
9

If you see the documentation in the branch Swift2.0 you can see that the responseJSON function has changed as the error says, it have now three parameters but you can catch the error too, lets take a look:

public func responseJSON(
    options options: NSJSONReadingOptions = .AllowFragments,
    completionHandler: (NSURLRequest?, NSHTTPURLResponse?, Result<AnyObject>) -> Void)
    -> Self
{
    return response(
        responseSerializer: Request.JSONResponseSerializer(options: options),
        completionHandler: completionHandler
    )
}

Now it returns an enum Result<AnyObject> and according to the doc :

Used to represent whether a request was successful or encountered an error.

- Success: The request and all post processing operations were successful resulting in the serialization of the 
           provided associated value.
- Failure: The request encountered an error resulting in a failure. The associated values are the original data 
           provided by the server as well as the error that caused the failure.

And it have inside an property entitled error, with the following doc:

/// Returns the associated error value if the result is a failure, `nil` otherwise.
public var error: ErrorType? {
    switch self {
    case .Success:
        return nil
    case .Failure(_, let error):
        return error
    }
}

Then if you follow this test case inside Alamofire you can see how to get the error properly:

func testThatResponseJSONReturnsSuccessResultWithValidJSON() {
    // Given
    let URLString = "https://httpbin.org/get"
    let expectation = expectationWithDescription("request should succeed")

    var request: NSURLRequest?
    var response: NSHTTPURLResponse?
    var result: Result<AnyObject>!

    // When
    Alamofire.request(.GET, URLString, parameters: ["foo": "bar"])
        .responseJSON { responseRequest, responseResponse, responseResult in
            request = responseRequest
            response = responseResponse
            result = responseResult

            expectation.fulfill()
        }

    waitForExpectationsWithTimeout(defaultTimeout, handler: nil)

    // Then
    XCTAssertNotNil(request, "request should not be nil")
    XCTAssertNotNil(response, "response should not be nil")
    XCTAssertTrue(result.isSuccess, "result should be success")
    XCTAssertNotNil(result.value, "result value should not be nil")
    XCTAssertNil(result.data, "result data should be nil")
    XCTAssertTrue(result.error == nil, "result error should be nil")
}

UPDATE:

Alamofire 3.0.0 introduces a Response struct. All response serializers (with the exception of response) return a generic Response struct.

public struct Response<Value, Error: ErrorType> {
   /// The URL request sent to the server.
   public let request: NSURLRequest?

   /// The server's response to the URL request.
   public let response: NSHTTPURLResponse?

   /// The data returned by the server.
   public let data: NSData?

   /// The result of response serialization.
   public let result: Result<Value, Error>
}

So you can call it like the following way:

Alamofire.request(.GET, "http://httpbin.org/get")
     .responseJSON { response in
         debugPrint(response)
}

You can read more about the migration process in the Alamofire 3.0 Migration Guide.

I hope this help you.

Tagore answered 28/8, 2015 at 19:25 Comment(5)
Thank you, do you have the link to the Swift 2 docs you're referring to?Clericals
You're welcome. If you change the branch in Github to Swift2.0 you can see the updated documentation below. But if you want to know a little more you have to introduce yourself in the source code, it's not hard to follow.Tagore
@VictorSigler Showing error at -> Self. Please help me!Tout
@iRealMe Be careful , it's the code in the branch of Swift 2.0 in the Alamofire repo , it is a class as I remember. What's your problem exactly?Tagore
@VictorSigler lets discuss hereTout
D
2

Have you tried using three parameters in the .responseJSON and inserting a try catch block around the areas you want error logging, check out this link if you need help with swift 2 try catchs

Diffusive answered 28/8, 2015 at 18:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.