使用Alamofire在Swift中上传多张图片

17
我使用以下代码将单个图像上传到服务器:
private static func urlRequestWithComponents(urlString:String, parameters:Dictionary<String, String>, imageData:NSData?, imageName: String) -> (URLRequestConvertible , NSData) {

    // create url request to send
    let mutableURLRequest = NSMutableURLRequest(URL: NSURL(string: urlString)!)
    mutableURLRequest.HTTPMethod = Alamofire.Method.POST.rawValue
    let boundaryConstant = "myRandomBoundary12345";
    let contentType = "multipart/form-data;boundary="+boundaryConstant
    mutableURLRequest.setValue(contentType, forHTTPHeaderField: "Content-Type")


    // create upload data to send
    let uploadData = NSMutableData()
    if(imageData != nil && imageData?.length != 0) {
        // add image
        uploadData.appendData("\r\n--\(boundaryConstant)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
        uploadData.appendData("Content-Disposition: form-data; name=\"\(imageName)\"; filename=\"\(StringHelper.sharedInstance.randomString(5)).png\"\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
        uploadData.appendData("Content-Type: image/png\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
        uploadData.appendData(imageData!)
    }
    // add parameters
    for (key, value) in parameters {
        uploadData.appendData("\r\n--\(boundaryConstant)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
        uploadData.appendData("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n\(value)".dataUsingEncoding(NSUTF8StringEncoding)!)
    }
    uploadData.appendData("\r\n--\(boundaryConstant)--\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
    print("upload",parameters)
    // return URLRequestConvertible and NSData
    return (Alamofire.ParameterEncoding.URL.encode(mutableURLRequest, parameters: nil).0, uploadData)
}

如何通过编辑此代码来在单个参数中上传多个图像?


如何在单个参数中上传多个图像数组 - Arun sharma
1
你可以创建一个结构体,将所有的函数参数放入其中,然后创建一个函数,该函数接受一个包含这些结构体的数组,在函数中,你可以遍历该数组,然后返回一个请求数组。如果你想一次性完成所有上传操作,因为你需要在所有上传完成时执行某些操作,那么请查看Operation queue或Dispatch Group。 - JustinM
请参考以下链接:http://stackoverflow.com/questions/28448837/uploading-multiple-image-files-with-swift,https://dev59.com/e5zha4cB1Zd3GeqPEGBy - Ramkrishna Sharma
4个回答

47

Swift 3 只需使用"[]"与图像上传参数,即可将其变为图像数组。

Alamofire.upload(multipartFormData: { multipartFormData in
            // import image to request
            for imageData in imagesData {
                multipartFormData.append(imageData, withName: "\(imageParamName)[]", fileName: "\(Date().timeIntervalSince1970).jpeg", mimeType: "image/jpeg")
            }
            for (key, value) in parameters {
                multipartFormData.append(value.data(using: String.Encoding.utf8)!, withName: key)
            }
        }, to: urlString,

            encodingCompletion: { encodingResult in
                switch encodingResult {
                case .success(let upload, _, _):
                    upload.responseJSON { response in

                    }
                case .failure(let error):
                    print(error)
                }

        })

1
上传多张图片的简短而简单的方法,谢谢。 - Arun sharma
2
以上代码是为了上传多张图片集合,根据代码,您有图像数据(Foundation.Data)在“imagesData”数组中。问题是,在迭代创建mutipartFormData时,它会覆盖先前的图像数据值。但是,通过在参数名称末尾添加[]方括号,它能够将数据加载到数组中。就这样。在Postman应用程序中,您也可以看到上传图像数组的相同操作。谢谢。如果可以,请点赞。 - Gurjit Singh
1
请问上面代码中的 withName: "(imageParamName)[]" 是什么意思? - Saurabh
@RizwanAhmed 是的 - Gurjit Singh
@Anees,请告诉我您的需求和一些代码。 - Gurjit Singh
显示剩余4条评论

5

这是我的解决方案,它将百分之百有效,没有任何错误。

        Alamofire.upload(multipartFormData: { (multipartFormData : MultipartFormData) in

            let count = imageToUpload.count

            for i in 0..<count{
                multipartFormData.append(imageToUpload[i], withName: "morephoto[\(i)]", fileName: "photo\(i).jpeg" , mimeType: "image/jpeg")

            }
            for (key, value) in parameterrs {

                    multipartFormData.append((value as AnyObject).data(using: String.Encoding.utf8.rawValue)!, withName: key)
            }
            print(multipartFormData)
        }, to: url!) { (result) in

                switch result {
                case .success(let upload, _ , _):

                    upload.uploadProgress(closure: { (progress) in

                        print("uploding: \(progress.fractionCompleted)")
                    })

                    upload.responseJSON { response in

                    print(response.result.value!)
                    let resp = response.result.value! as! NSDictionary
                    if resp["status"] as! String == "success"{
                        print(response.result.value!)
                        let alert = UIAlertController(title: "Alert", message: "Image Upload Successful", preferredStyle: UIAlertControllerStyle.alert)
                        alert.addAction(UIAlertAction(title: "Okay", style: UIAlertActionStyle.default, handler: nil))
                        self.present(alert, animated: true, completion: nil)


                    }
                    else{

                    }


                }

            case .failure(let encodingError):
                print("failed")
                print(encodingError)

            }
        }

在这里,imagetoupload数组是我之前制作的图像数据数组。

5

这个对我有帮助:

private func urlRequestWithComponentsForUploadMultipleImages(urlString:String, parameters:Dictionary<String, String>, imagesData:[Data], imageName: String) -> (URLRequestConvertible , Data) {

    // create url request to send
    var mutableURLRequest = URLRequest(url: NSURL(string: urlString)! as URL)

    mutableURLRequest.httpMethod = Alamofire.HTTPMethod.post.rawValue
    let boundaryConstant = "myRandomBoundary12345";
    let contentType = "multipart/form-data;boundary="+boundaryConstant
    mutableURLRequest.setValue(contentType, forHTTPHeaderField: "Content-Type")


    // create upload data to send
    var uploadData = Data()
    // add image
    for data in imagesData {
        uploadData.append("\r\n--\(boundaryConstant)\r\n".data(using: String.Encoding.utf8)!)
        uploadData.append("Content-Disposition: form-data; name=\"\(imageName)\"; filename=\"\(Date().timeIntervalSince1970).jpeg\"\r\n".data(using: String.Encoding.utf8)!)
        uploadData.append("Content-Type: image/jpeg\r\n\r\n".data(using: String.Encoding.utf8)!)
        uploadData.append(data)
    }
    // add parameters
    for (key, value) in parameters {
        uploadData.append("\r\n--\(boundaryConstant)\r\n".data(using: String.Encoding.utf8)!)
        uploadData.append("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n\(value)".data(using: String.Encoding.utf8)!)
    }
    uploadData.append("\r\n--\(boundaryConstant)--\r\n".data(using: String.Encoding.utf8)!)
    print("upload",parameters)
    return (mutableURLRequest , uploadData)
}

2

看起来这个问题已经在SO上得到了回答,可能有多个地方。这是我找到的一个链接:

如何使用Alamofire上传多个图像?

为了方便,我将粘贴他们的解决方案,但他们说它适用于Swift 3.x:

//MARK: - upload multiple photos

func uploadImagesAndData(params:[String : AnyObject]?,image1: UIImage,image2: UIImage,image3: UIImage,image4: UIImage,headers : [String : String]?, completionHandler:@escaping CompletionHandler) -> Void {

    let imageData1 = UIImageJPEGRepresentation(image1, 0.5)!
    let imageData2 = UIImageJPEGRepresentation(image2, 0.5)!

    let imageData3 = UIImageJPEGRepresentation(image3, 0.5)!

    let imageData4 = UIImageJPEGRepresentation(image4, 0.5)!


    Alamofire.upload(multipartFormData: { multipartFormData in

            for (key, value) in params! {
                if let data = value.data(using: String.Encoding.utf8.rawValue) {
                    multipartFormData.append(data, withName: key)
                }
            }

            multipartFormData.append(imageData1, withName: "file", fileName: "image.jpg", mimeType: "image/jpeg")
            multipartFormData.append(imageData2, withName: "file", fileName: "image.jpg", mimeType: "image/jpeg")
            multipartFormData.append(imageData3, withName: "file", fileName: "image.jpg", mimeType: "image/jpeg")
            multipartFormData.append(imageData4, withName: "file", fileName: "image.jpg", mimeType: "image/jpeg")

    },
        to: K_BASEURL + K_API_LOGINDATA, encodingCompletion: { encodingResult in
            switch encodingResult {
            case .success(let upload, _, _):
                upload
                    .validate()
                    .responseJSON { response in
                        switch response.result {
                        case .success(let value):
                            print("responseObject: \(value)")
                        case .failure(let responseError):
                            print("responseError: \(responseError)")
                        }
                }
            case .failure(let encodingError):
                print("encodingError: \(encodingError)")
            }
    })

该解决方案似乎基于Alamofire文档中推荐的方法,详情请参见此处:https://github.com/Alamofire/Alamofire#uploading-multipartformdata
Alamofire.upload(
multipartFormData: { multipartFormData in
    multipartFormData.append(unicornImageURL, withName: "unicorn")
    multipartFormData.append(rainbowImageURL, withName: "rainbow")
},
to: "https://httpbin.org/post",
encodingCompletion: { encodingResult in
    switch encodingResult {
    case .success(let upload, _, _):
        upload.responseJSON { response in
            debugPrint(response)
        }
    case .failure(let encodingError):
        print(encodingError)
    }
})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接