1

I have an iOS app written in Swift 2.0 wich uploads images to Microsoft Azure Blob Storage. I use Alamofire for the requests.

On an device with iOS 8 everything works fine, but on iOS 9 it get errors on upload:

    let AlamofireManager = Alamofire.Manager.sharedInstance
    AlamofireManager.session.configuration.HTTPAdditionalHeaders = [
        "Content-Type": "image/jpg",
        "x-ms-blob-type": "BlockBlob"
    ]
    AlamofireManager.upload(.PUT, uploadURL, data: imageData)
        .responseJSON { (request, response, result) in
            print("Request=\(request)")
            print("response=\(response)")
            print("result=\(result)")
            if (response) != nil {
                let statusString = String(stringInterpolationSegment: response!.statusCode)
                let statusCode = self.getStatusCodeFromStatusString(statusString)
                if (statusCode == 201) {
                    // MY SUCCESS CODE IS HERE
                }
                else {
                    // STATUSCODE != 201
                }
            }
            else {
                // OTHER ERROR
            }
       }

An sample URL for the upload (uploadURL) might be:

https://mystorage.blob.core.windows.net:443/thumbs/7346e38a-eb54-48ea-b0fe-89357100dd18.jpg?sv=2013-08-15&sr=b&sig=GYwHvnUc52GsajFJCAu1v4W5qG0wSBpaXvxncD%2FAt34%3D&st=2015-10-01T11%3A25%3A57Z&se=2015-10-01T11%3A40%3A57Z&sp=w

For Azure it is important, that: a) The HTTP-Verb is PUT b) The Url parameters are included in Url and not as multipart data (this is the access token for the upload).

Perhaps Alamofire has problems on creating the URL with parameters in combination with the PUT?

This solution does not work, because it´s based on multipart data upload: Upload image with parameters in Swift

Because I think about the URL parameter problem, I tried following:

    let AlamofireManager = Alamofire.Manager.sharedInstance
    AlamofireManager.session.configuration.HTTPAdditionalHeaders = [
        "Content-Type": "image/jpg",
        "x-ms-blob-type": "BlockBlob"
    ]
    var URLRequest: NSMutableURLRequest {
        let URL = NSURL(string: uploadURL)!
        var mutableRequest = NSMutableURLRequest(URL: URL)
        mutableRequest.HTTPMethod = Alamofire.Method.PUT.rawValue
        return mutableRequest
    }
    AlamofireManager.upload(URLRequest, data: imageData)
:
: rest is same like above
:

But this does´t work, too. In both cases I always get an 400 error (in response.statusCode) from the server. result contains Failure and the information NSCocoaErrorDomain - code 3840 with description Invalid value around character 3.

But on iOS 8, the solution works like a charm :(

Any ideas, what the problem is and how to solve it?

Edit: Or could the port be the problem?

Community
  • 1
  • 1
Oliver Apel
  • 1,808
  • 3
  • 19
  • 31

1 Answers1

0

Got it on my own. Alamofire seems not to send the HTTP-Headers as expected with the AlamofireManager. I added the headers manually:

    var URLRequest: NSMutableURLRequest {
        let URL = NSURL(string: uploadURL)!
        var mutableRequest = NSMutableURLRequest(URL: URL)
        mutableRequest.HTTPMethod = Alamofire.Method.PUT.rawValue
        mutableRequest.setValue("image/jpg", forHTTPHeaderField: "Content-Type")
        mutableRequest.setValue("BlockBlob", forHTTPHeaderField: "x-ms-blob-type")
        return mutableRequest
    }

    AlamofireManager.upload(URLRequest, data: imageData)
    :
    :
Oliver Apel
  • 1,808
  • 3
  • 19
  • 31
  • Alamofire sends the headers exactly as expected. You need to create your own session configuration and add the headers before creating a URL session, otherwise iOS 9 will not append the headers. – cnoon Oct 04 '15 at 20:24