简体   繁体   English

如何使用Moya Swift使用多部分请求上传图像?

[英]How to upload image using multipart request with Moya Swift?

I'm using Moya 10.0.1 and I'm having a problem when I'm trying to upload an image to the server. 我正在使用Moya 10.0.1,当我尝试将图像上传到服务器时,我遇到了问题。

I did follow the Multipart Upload example and this is my setup code: 我确实按照分段上传示例进行操作 ,这是我的设置代码:

typealias UpdateUserAvatarParameters = (userId: Int, image: UIImage)

enum APITarget {
    case updateUserAvatar(parameters: UpdateUserAvatarParameters)
}

extension APITarget: TargetType {

    public var baseURL: URL { return URL(string: "http://domain/api")! }

    public var path: String {
        switch self {
        case .updateUserAvatar: return "/postuserimage"
        }
    }

    public var method: Moya.Method {
        switch self {
        default: return .post
        }
    }

    public var task: Task {
        switch self {
        case .updateUserAvatar(let parameters):
            let imageData = UIImagePNGRepresentation(parameters.image) ?? Data()
            let userIdData = parameters.userId.string.data(using: String.Encoding.utf8) ?? Data()

            let imageMultipartFormData = MultipartFormData(provider: .data(imageData), name: "img", fileName: "user_avatar.jpeg", mimeType: "image/jpeg")
            let userIdMultipartFormData = MultipartFormData(provider: .data(userIdData), name: "cusId")

            return .uploadMultipart([imageMultipartFormData, userIdMultipartFormData])
        }
    }

    public var sampleData: Data {
        return Data()
    }

    public var headers: [String : String]? {
        switch self {
        case .updateUserAvatar: return ["Content-type" : "multipart/form-data"]
        default: return ["Content-type" : "application/json"]
        }
    }
}

However, when I make a request, I got an MoyaError: 但是,当我提出请求时,我得到了一个MoyaError:

let parameters = UpdateUserAvatarParameters(userId: 1, image: pickedImage)

provider.request(.updateUserAvatar(parameters: parameters), completion: { result in
    switch result {
    case .success(let response):
        do {
            try _ = response.filterSuccessfulStatusCodes()
            print("200 - 299: \(response.data)")
        } catch {
            print(error)  // This code will run because the statusCode is 500
        }

    case .failure(let error):
        print("Failure: \(error)")
    }
})

在此输入图像描述

I have no idea about what I did wrong, I also don't know what is statusCode 500? 我不知道我做错了什么,我也不知道什么是statusCode 500? Does anyone know why? 有谁知道为什么?

Addition, when I make a request with Alamofire with the same setup (url, parameters...), everything works normally: 另外,当我使用相同的设置(url,参数......)向Alamofire提出请求时,一切正常:

Alamofire.upload(multipartFormData: { multipartFormData in
    let imageData = UIImagePNGRepresentation(pickedImage) ?? Data()
    let userIdData = userId.string.data(using: String.Encoding.utf8) ?? Data()

    multipartFormData.append(imageData, withName: "img", fileName: "user_avatar.jpeg", mimeType: "image/jpeg")
    multipartFormData.append(userIdData, withName: "cusId")
}, to: "http://domain/api/postuserimage", encodingCompletion: { result in
    switch result {
    case .success(let upload, _, _):
        upload.uploadProgress(closure: { progress in
            print("Upload Progress: \(progress.fractionCompleted)")
        })

        upload.responseJSON(completionHandler: { response in
            print(response.result.value)
        })

    case .failure(let encodingError):
        print(encodingError)
    }
})
    var task: Task {
    switch self {
    case .updateProfilePic(let memberID, let image):
        let imageData = UIImageJPEGRepresentation(image, 1.0)
        let memberIdData = memberID.data(using: String.Encoding.utf8) ?? Data()
        var formData: [Moya.MultipartFormData] = [Moya.MultipartFormData(provider: .data(imageData!), name: "user_img", fileName: "user.jpeg", mimeType: "image/jpeg")]
        formData.append(Moya.MultipartFormData(provider: .data(memberIdData), name: "member_id"))
        return .uploadMultipart(formData)
    }

In Moya multipart request we have to pass parameter as multipartdata form along with it's key name. 在Moya多部分请求中,我们必须将参数作为multipartdata形式及其密钥名称传递。

complete detail of uploading image using multipart request with Moya Swift. 使用Moya Swift使用多部分请求上传图像的完整细节。 setp 1 setp 1

 import Foundation
import Moya

enum ImageService {
    case updateUserAvatar(user_id: Int, cover_image: UIImage)
}
extension ImageService: TargetType {
    public var baseURL: URL { return URL(string: "https://api.shoclef.com/api")! }
    public var path: String {
        switch self {
        case .updateUserAvatar(_,_): return "/updatecoverimage"
        }
    }
    public var method: Moya.Method {
        switch self {
        case .updateUserAvatar(_, _):
            return .post
        }
    }
    var task: Task {
        switch self {

    case .updateUserAvatar(let user_id, let cover_image):
        let imageData = UIImageJPEGRepresentation(cover_image, 1.0)
        let memberIdData = "\(user_id)".data(using: String.Encoding.utf8) ?? Data()
        var formData: [Moya.MultipartFormData] = [Moya.MultipartFormData(provider: .data(imageData!), name: "cover_image", fileName: "asdas.png", mimeType: "image/jpeg")]
        formData.append(Moya.MultipartFormData(provider: .data(memberIdData), name: "user_id"))
        return .uploadMultipart(formData)
    }
}
public var sampleData: Data {
    return Data()
}
public var headers: [String : String]? {
    switch self {
    case .updateUserAvatar: return ["Content-type" : "application/json"]

    }}}

step 2 第2步

@IBOutlet weak var myImage: UIImageView!
    var provider = MoyaProvider<ImageService>()
 @IBAction func uploadImage(_ sender: UIButton) {
        provider.request(ImageService.updateUserAvatar(user_id: 1163, cover_image: myImage.image!)) { result in
            switch result {
            case .success(let response):
                do {

                    let image = try JSONDecoder().decode(Updatecoverimage.self, from: response.data)
                    print(image.data)
                } catch {
                    print(error)  // This code will run because the statusCode is 500
                }

            case .failure(let error):
                print("Failure: \(error)")
            }
        }

    }

}



struct Updatecoverimage: Codable {
    let status, data: String
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM