MYSQL和Swift - 上传图片和文件||使用Alamofire会更好吗? [英] MYSQL and Swift - Upload image and FILE || Would it be better to use Alamofire?

查看:86
本文介绍了MYSQL和Swift - 上传图片和文件||使用Alamofire会更好吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试上传图片和文本文件(将其上传为数据)。

I am trying to upload an image, and a text file(uploading it as Data).

到目前为止,我可以正确上传图片,还可以上传文本文件数据单独成功上传为.txt。

So far I can upload the image alone correctly, and also upload the text file data uploading it as a .txt successfully alone.

现在我需要同时上传图像和.txt文件......

Now I need to upload both image and .txt file together...

我不确定如何在我的IOS应用程序中设置Paramaters ....

到目前为止,这是我上传.txt文件的方式(基本上与我上传图片的方式相同,但我更改了文件名和mimetype)

So far this is how I upload the .txt file (basically the same way I upload the image but I change the "filename" and "mimetype")

func createBodyWithParameters(parameters: [String : Any]?, filePathKey: String?,filePathKey1: String?, imageDataKey: NSData,imageDataKey1: NSData, boundary: String) -> NSData {

        let body = NSMutableData();

        if parameters != nil {
            for (key, value) in parameters! {
                body.appendString("--\(boundary)\r\n")
                body.appendString("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
                body.appendString("\(value)\r\n")
            }
        }

        let filename = "post-\(uuid).txt"
        let mimetype = "image/txt"

        body.appendString("--\(boundary)\r\n")
        body.appendString("Content-Disposition: form-data; name=\"\(filePathKey!)\"; filename=\"\(filename)\"\r\n")
        body.appendString("Content-Type: \(mimetype)\r\n\r\n")


        body.append(imageDataKey as Data)

        body.appendString("\r\n")
        body.appendString("--\(boundary)--\r\n")

        return body
    }

没有w我不知道如何使用该参数保存图像和.txt文件。

Now I am not sure how to save both image and .txt file with that paramater.

然而,这是我上传的其他快速代码:

This however is the rest of my swift code for uploading it:

 let param = [
            "id" : id,
            "uuid" : uuid,
            "Text" : Text,
            "Title" : Title
           ] as [String : Any]

        let boundary = "Boundary-\(NSUUID().uuidString)"
        request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")

        let data: Data = NSKeyedArchiver.archivedData(withRootObject: blogattributedText)


        var imageData = NSData()
        let image = CoverImage
        let width = CGSize(width: self.view.frame.width, height: image.size.height * (self.view.frame.width / image.size.width))
        imageData = UIImageJPEGRepresentation(imageWithImage(image, scaledToSize: width), 0.5)! as NSData

   // ... body
    request.httpBody = createBodyWithParameters(parameters: param, filePathKey: "file",filePathKey1: "file1", imageDataKey: data as NSData,imageDataKey1: imageData as NSData, boundary: boundary) as Data

如果有人需要查看我的代码或不理解我的问题,请告诉我们!

If anyone needs to see anymore of my code or doesn't understand my question please let me know!

提前感谢任何可以提供帮助的人!!

Thanks in advance to anyone that can help!!

推荐答案

如果你不想要在创造复杂请求的杂草中迷失了方向,像 Alamofire 这样的第三方图书馆会很聪明。它与AFNetworking的作者相同,但它是一个原生的Swift库。

If you don't want to get lost in the weeds of creating complex requests, a third party library like Alamofire would be smart. It's by the same author as AFNetworking, but it's a native Swift library.

因此,Alamofire的实现可能如下所示:

So, an Alamofire implementation might look like:

func performRequest(urlString: String, id: String, uuid: String, text: String, title: String, blogAttributedText: NSAttributedString, image: UIImage) {

    let parameters = [
        "id" : id,
        "uuid" : uuid,
        "Text" : text,
        "Title" : title
    ]

    let imageData = UIImageJPEGRepresentation(image, 0.5)!

    let blogData = NSKeyedArchiver.archivedData(withRootObject: blogAttributedText)

    Alamofire.upload(
        multipartFormData: { multipartFormData in
            for (key, value) in parameters {
                if let data = value.data(using: .utf8) {
                    multipartFormData.append(data, withName: key)
                }
            }
            multipartFormData.append(imageData, withName: "image", fileName: "image.jpg", mimeType: "image/jpeg")
            multipartFormData.append(blogData, withName: "blog", fileName: "blog.archive", mimeType: "application/octet-stream")
    },
    to: urlString,
    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)")
        }
    })
}






如果你是我自己建立这个请求,我建议一些事情。首先,由于您要发送不同类型的文件,您可能需要一些好的类型来封装它:


If you're going to build this request yourself, I'd suggest a few things. First, since you're sending files of different types, you might want some nice type to encapsulate this:

struct FilePayload {
    let fieldname: String
    let filename: String
    let mimetype: String
    let payload: Data
}

我也不确定如何制作 image / txt mime类型。我可能会使用 application / octet-stream 来存档。

I'm also not sure what to make of the image/txt mime type. I'd probably use application/octet-stream for the archive.

无论如何,构建请求可以如下:

Anyway, the building of the request could be as follows:

/// Create request.
///
/// - Parameters:
///   - url:                The URL to where the post will be sent.
///   - id:                 The identifier of the entry
///   - uuid:               The UUID of the entry
///   - text:               The text.
///   - title:              The title.
///   - blogAttributedText: The attributed text of the blog entry.
///   - image:              The `UIImage` of the image to be included.
///
/// - Returns: The `URLRequest` that was created

func createRequest(url: URL, id: String, uuid: String, text: String, title: String, blogAttributedText: NSAttributedString, image: UIImage) -> URLRequest {
    let parameters = [
        "id" : id,
        "uuid" : uuid,
        "Text" : text,     // I find it curious to see uppercase field names (I'd use lowercase for consistency's sake, but use whatever your PHP is looking for)
        "Title" : title
    ]

    let boundary = "Boundary-\(NSUUID().uuidString)"

    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
    request.setValue("application/json", forHTTPHeaderField: "Accept")  // adjust if your response is not JSON

    // use whatever field name your PHP is looking for the image; I used `image`

    let imageData = UIImageJPEGRepresentation(image, 0.5)!
    let imagePayload = FilePayload(fieldname: "image", filename: "image.jpg", mimetype: "image/jpeg", payload: imageData)

    // again, use whatever field name your PHP is looking for the image; I used `blog`

    let blogData = NSKeyedArchiver.archivedData(withRootObject: blogAttributedText)
    let blogPayload = FilePayload(fieldname: "blog", filename: "blog.archive", mimetype: "application/octet-stream", payload: blogData)

    request.httpBody = createBody(with: parameters, files: [imagePayload, blogPayload], boundary: boundary)

    return request
}

/// Create body of the multipart/form-data request.
///
/// - Parameters:
///   - parameters: The optional dictionary containing keys and values to be passed to web service.
///   - files:      The list of files to be included in the request.
///   - boundary:   The `multipart/form-data` boundary
///
/// - Returns: The `Data` of the body of the request.

private func createBody(with parameters: [String: String]?, files: [FilePayload], boundary: String) -> Data {
    var body = Data()

    if parameters != nil {
        for (key, value) in parameters! {
            body.append("--\(boundary)\r\n")
            body.append("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
            body.append("\(value)\r\n")
        }
    }

    for file in files {
        body.append("--\(boundary)\r\n")
        body.append("Content-Disposition: form-data; name=\"\(file.fieldname)\"; filename=\"\(file.filename)\"\r\n")
        body.append("Content-Type: \(file.mimetype)\r\n\r\n")
        body.append(file.payload)
        body.append("\r\n")
    }

    body.append("--\(boundary)--\r\n")
    return body
}

/// Create boundary string for multipart/form-data request
///
/// - returns:            The boundary string that consists of "Boundary-" followed by a UUID string.

private func generateBoundaryString() -> String {
    return "Boundary-\(NSUUID().uuidString)"
}

其中

extension Data {

    /// Append string to Data
    ///
    /// Rather than littering my code with calls to `dataUsingEncoding` to convert strings to `Data`, and then add that data to the `Data`, this wraps it in a nice convenient little `Data` extension. This converts using UTF-8.
    ///
    /// - parameter string:       The string to be added to the mutable `Data`.

    mutating func append(_ string: String) {
        if let data = string.data(using: .utf8) {
            append(data)
        }
    }
}

显然这是Swift 3代码,所以我删除了 NSMutableData reference。

Clearly this was Swift 3 code, so I excised the NSMutableData reference.

这篇关于MYSQL和Swift - 上传图片和文件||使用Alamofire会更好吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆