Search code examples
iosswiftnetwork-programmingalamofirepromisekit

How to check if the multipart upload was successful with alamofire image


I am making a network call to upload an image to a backend server. Right now I am using the following to code. This code works perfectly in conditions where the internet is online.

// MARK: - PUT

    static func PUT(URL: String,
                    data: Data,
                    mimeType: String,
                    headers: [String: String]?) -> Promise<Void>
    {
        return Promise { fulfill, reject in

            let URL = try! URLRequest(url: URL, method: .put, headers: headers)

            Alamofire.upload(
                multipartFormData: { multipartFormData in

                    multipartFormData.append(InputStream.init(data: data), withLength: UInt64(data.count), name: "image", fileName: "file.png", mimeType: mimeType)
            },
            with: URL,
            encodingCompletion: { encodingResult in
                switch encodingResult {
                    case .success(let upload, _, _):
                    upload.responseJSON { response in

                        if response.result.value == nil {
                            fulfill()
                        }else {
                            reject(response.result.error!)
                        }
                    }
                    case .failure( _):
                    break
                }
            })
        }
    }
}

In case I put it on offline mode. It'll still execute the function and still fullfills() the promise. Even tho the network is offline. I think this is because it's checking if the encodingResult is succesful or not. NOt for the network call itself.

How am I able to check if the network call was successful or not? It's returning Void.

Import notes:

  • Server returns nill if we receive 200 code which means that have uploaded the image.

Solution

  • If you're going to use status codes to determine success or failure, you should add validate:

    For example:

    static func PUT(URL: String,
                    data: Data,
                    mimeType: String,
                    headers: [String: String]?) -> Promise<Void> {
        return Promise { fulfill, reject in
    
            let URL = try! URLRequest(url: URL, method: .put, headers: headers)
    
            Alamofire.upload(
                multipartFormData: { multipartFormData in
                    multipartFormData.append(data, withName: "image", fileName: "file.png", mimeType: mimeType)
            }, with: URL) { encodingResult in
                switch encodingResult {
                case .success(let upload, _, _):
                    upload
                        .validate(statusCode: 200 ..< 300)
                        .responseJSON { response in
                            switch response.result {
                            case .success:
                                fulfill()
                            case .failure(let error):
                                reject(error)
                            }
                    }
                case .failure(let error):
                    reject(error)
                }
            }
        }
    }
    

    The above assumes that upon successful response, you'll also get JSON response. You might want to do some additional checking of value.

    If you're not returning JSON upon success, then just use response, not responseJSON:

    static func PUT(URL: String,
                    data: Data,
                    mimeType: String,
                    headers: [String: String]?) -> Promise<Void> {
        return Promise { fulfill, reject in
            let URL = try! URLRequest(url: URL, method: .put, headers: headers)
    
            Alamofire.upload(
                multipartFormData: { multipartFormData in
                    multipartFormData.append(data, withName: "image", fileName: "file.png", mimeType: mimeType)
            }, with: URL) { encodingResult in
                switch encodingResult {
                case .success(let upload, _, _):
                    upload
                        .validate(statusCode: 200 ..< 300)
                        .response { response in
                            if let error = response.error {
                                reject(error)
                            } else {
                                fulfill()
                            }
                    }
                case .failure(let error):
                    reject(error)
                }
            }
        }
    }