MYSQL和Swift – 上传图像和FILE || 使用Alamofire会更好吗?
我正在尝试上传图片和文本文件(将其上传为数据)。
到目前为止,我可以正确地单独上载图像,也可以单独成功上传文本文件数据作为.txt文件。
现在我需要将图像和.txt文件一起上传…
我不知道如何设置在我的IOS应用程序的参数为这….
到目前为止,这是我如何上传.txt文件(基本上是我上传图像的方式,但我更改“文件名”和“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 }
现在我不知道如何保存图像和.txt文件的参数。
然而,这是我的上传代码的其余部分:
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
如果有人需要看我的代码或不明白我的问题,请让我知道!
预先感谢任何人可以帮助!
如果你不想迷失在创造复杂请求的杂草中,像Alamofire这样的第三方图书馆将是聪明的。 它是AFNetworking的作者,但它是一个本地的Swift库。
所以,Alamofire实现可能如下所示:
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)") } }) }
如果你打算自己build立这个请求,我会提出一些build议。 首先,由于您正在发送不同types的文件,因此您可能需要一些很好的types来封装它:
struct FilePayload { let fieldname: String let filename: String let mimetype: String let payload: Data }
我也不知道该怎么做的image/txt
MIMEtypes。 我可能会使用application/octet-stream
来存档。
无论如何,请求的构build可能如下:
/// 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
引用。
或者,您可以制作JSON rest API。
- 在Base64编码的string中转换记事本文件的内容。
- 以Base64编码的string转换您的图像文件。
- 在请求参数中传递Base64编码的string。
- 一旦在函数参数中获得API文件上的Base64编码string。
- 再次解码Base64string并将其存储在内容文件夹中。
https://github.com/AFNetworking/AFNetworking/wiki/Getting-Started-with-AFNetworking
使用AFNetworking在swift上传图片
使用AFNetworking 2.0上传图像
注 – 在iOS应用程序上显示图像,您可以使绝对URL和使用图像caching类,您可以显示图像。