使用 Swift 5.0 将 UIImage 上传到 REST API
Uploading an UIImage to REST API with Swift 5.0
我可以使用 Postman 将图片发送(上传)到 REST API。但是我无法将带有 Swift
代码的图片发送(上传)到 REST API.
首先分享一下使用Postman的原始数据:
POST http://testwlbyp.abc.com/ebys-servis-rest/ebys
200
583 ms
POST /ebys-servis-rest/ebys HTTP/1.1
Content-Type: application/x-www-form-urlencoded
User-Agent: PostmanRuntime/7.25.0
Accept: */*
Cache-Control: no-cache
Postman-Token: 888b7a05-e796-447f-9f6f-f3265bc38f3d
Host: testwlbyp.abc.com
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Cookie: JSESSIONID=tZXqTQrm8CHDiALd42cIWIiyVctFPSCJMKh-nxIyfqnVLu4CXChe!-1356762059
Content-Length: 11450
----------------------------postman
Content-Disposition: form-data; name="p_type"
LOAD_DOC
----------------------------postman
Content-Disposition: form-data; name="doc_no"
20200006966
----------------------------postman
Content-Disposition: form-data; name="token"
4268260b012c51fe8b2d41fe4c48e289
----------------------------postman
Content-Disposition: form-data; name="theme_no"
63
----------------------------postman
Content-Disposition: form-data; name="all_parameters"
FILE_NAME='myTest.jpg'
----------------------------postman
Content-Disposition: form-data; name="profile_no"
A-S
----------------------------postman
Content-Disposition: form-data; name="ss_no"
M1997069
----------------------------postman
Content-Disposition: form-data; name="user_agent"
----------------------------postman
Content-Disposition: form-data; name="file"; filename="testpic.jpg"
<myTest.jpg>
----------------------------postman--
这是回复:
HTTP/1.1 200 OK
Date: Thu, 25 Jun 2020 08:00:15 GMT
Content-Length: 169
Content-Type: application/json
{
"LOGID": 282659,
"RESULTID": "20200006966",
"FILESIZE": -1,
"OPNAME": "LOAD_DOC",
"ERRORCODE": 0,
"ERRORMESSAGE": "success"
}
这里是 Swift 代码;
func uploadPicture(paramaterImage: UIImage, parameterDocNo: String, parameterToken: String, parameterSSNo: String)
{
print("LOG 01") // I SEE THIS LOG
let fileName = "testImageName.jpg"
let oall_param : String = "FILE?_NAME='\(fileName+".jpg")'"
let url = URL(string: "http://testwlbyp.abc.com/ebys-servis-rest/ebys")
var urlRequest = URLRequest(url: url!)
urlRequest.httpMethod = "POST"
print("LOG 02") // I SEE THIS LOG
let image = paramaterImage
let data = image.jpegData(compressionQuality: 0.7)!
let qstr = String(decoding: data, as: UTF8.self)
// 1
urlRequest.addValue("LOAD_DOC", forHTTPHeaderField: "p_type")
// 2
urlRequest.addValue(parameterDocNo, forHTTPHeaderField: "doc_no")
// 3
urlRequest.addValue(parameterToken, forHTTPHeaderField: "token")
// 4
urlRequest.addValue("63123", forHTTPHeaderField: "theme_no")
// 5
urlRequest.addValue(oall_param, forHTTPHeaderField: "all_parameters")
// 6
urlRequest.addValue("A-S", forHTTPHeaderField: "profile_no")
// 7
urlRequest.addValue(parameterSSNo, forHTTPHeaderField: "ss_no")
// 8
urlRequest.addValue("", forHTTPHeaderField: "user_agent")
// 9
urlRequest.addValue(qstr, forHTTPHeaderField: "file")
let boundary = "Boundary-\(UUID().uuidString)"
urlRequest.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
print("LOG 03") // I SEE THIS LOG
//create body
let body = NSMutableData()
//append first line
let line1_boundryPrefix = "--\(boundary)\r\n"
body.append(line1_boundryPrefix.data(
using: String.Encoding.utf8,
allowLossyConversion: false)!)
//append second line
let line2_parameter = "Content-Disposition: form-data; name=\"source\"; filename=\"" + fileName + "\"\r\n"
body.append(line2_parameter.data(
using: String.Encoding.utf8,
allowLossyConversion: false)!)
//append third line (mime type)
let mimeType = "image/jpg"
let line3_contentType = "Content-Type: \(mimeType)\r\n\r\n"
body.append(line3_contentType.data(
using: String.Encoding.utf8,
allowLossyConversion: false)!)
//append image data
//line4
body.append(data)
let line5 = "\r\n"
body.append(line5.data(
using: String.Encoding.utf8,
allowLossyConversion: false)!)
let line6 = "--" + boundary + "--\r\n"
body.append(line6.data(
using: String.Encoding.utf8,
allowLossyConversion: false)!)
urlRequest.httpBody = body as Data
urlRequest.setValue(String(body.length), forHTTPHeaderField: "Content-Length")
URLSession.shared.dataTask(with: urlRequest) { (data, urlResponse, error) in
//handle callback
print("LOG 04, urlResponse: \(urlResponse)") // I DON'T SEE THIS LOG
}
print("LOG END") // I SEE THIS LOG
}
这是 Xcode 输出的结果 window:
LOG 01
LOG 02
LOG 03
LOG END
我没看到LOG04
我正在将 UIImage
参数(paramaterImage: UIImage)从下面的结构发送到 uploadPicture
方法:
import UIKit
struct MyMedia {
let key: String
let filename: String
let data: Data?
let mimeType: String
init?(withImage image: UIImage, forKey key: String) {
self.key = key
self.mimeType = "image/jpeg"
self.filename = "temppicname.jpg"
self.data = image.jpegData(compressionQuality: 1)
}
}
您必须对该任务调用 resume()
,否则它不会启动:
let task = URLSession.shared.dataTask(with: urlRequest) { (data, urlResponse, error) in
//handle callback
print("LOG 04, urlResponse: \(urlResponse)") // I DON'T SEE THIS LOG
}
task.resume()
之后,您需要确保按照与邮递员相同的方式格式化请求,否则服务器将拒绝它。
我建议您使用 Charles 代理之类的东西来比较您的应用程序发送的内容与您在 Postman 中发送的内容。
乍一看,您似乎是在根据请求 headers 发送 p_type
等,但在 Postman 的示例中,这些值是表单的一部分。
我可以使用 Postman 将图片发送(上传)到 REST API。但是我无法将带有 Swift
代码的图片发送(上传)到 REST API.
首先分享一下使用Postman的原始数据:
POST http://testwlbyp.abc.com/ebys-servis-rest/ebys
200
583 ms
POST /ebys-servis-rest/ebys HTTP/1.1
Content-Type: application/x-www-form-urlencoded
User-Agent: PostmanRuntime/7.25.0
Accept: */*
Cache-Control: no-cache
Postman-Token: 888b7a05-e796-447f-9f6f-f3265bc38f3d
Host: testwlbyp.abc.com
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Cookie: JSESSIONID=tZXqTQrm8CHDiALd42cIWIiyVctFPSCJMKh-nxIyfqnVLu4CXChe!-1356762059
Content-Length: 11450
----------------------------postman
Content-Disposition: form-data; name="p_type"
LOAD_DOC
----------------------------postman
Content-Disposition: form-data; name="doc_no"
20200006966
----------------------------postman
Content-Disposition: form-data; name="token"
4268260b012c51fe8b2d41fe4c48e289
----------------------------postman
Content-Disposition: form-data; name="theme_no"
63
----------------------------postman
Content-Disposition: form-data; name="all_parameters"
FILE_NAME='myTest.jpg'
----------------------------postman
Content-Disposition: form-data; name="profile_no"
A-S
----------------------------postman
Content-Disposition: form-data; name="ss_no"
M1997069
----------------------------postman
Content-Disposition: form-data; name="user_agent"
----------------------------postman
Content-Disposition: form-data; name="file"; filename="testpic.jpg"
<myTest.jpg>
----------------------------postman--
这是回复:
HTTP/1.1 200 OK
Date: Thu, 25 Jun 2020 08:00:15 GMT
Content-Length: 169
Content-Type: application/json
{
"LOGID": 282659,
"RESULTID": "20200006966",
"FILESIZE": -1,
"OPNAME": "LOAD_DOC",
"ERRORCODE": 0,
"ERRORMESSAGE": "success"
}
这里是 Swift 代码;
func uploadPicture(paramaterImage: UIImage, parameterDocNo: String, parameterToken: String, parameterSSNo: String)
{
print("LOG 01") // I SEE THIS LOG
let fileName = "testImageName.jpg"
let oall_param : String = "FILE?_NAME='\(fileName+".jpg")'"
let url = URL(string: "http://testwlbyp.abc.com/ebys-servis-rest/ebys")
var urlRequest = URLRequest(url: url!)
urlRequest.httpMethod = "POST"
print("LOG 02") // I SEE THIS LOG
let image = paramaterImage
let data = image.jpegData(compressionQuality: 0.7)!
let qstr = String(decoding: data, as: UTF8.self)
// 1
urlRequest.addValue("LOAD_DOC", forHTTPHeaderField: "p_type")
// 2
urlRequest.addValue(parameterDocNo, forHTTPHeaderField: "doc_no")
// 3
urlRequest.addValue(parameterToken, forHTTPHeaderField: "token")
// 4
urlRequest.addValue("63123", forHTTPHeaderField: "theme_no")
// 5
urlRequest.addValue(oall_param, forHTTPHeaderField: "all_parameters")
// 6
urlRequest.addValue("A-S", forHTTPHeaderField: "profile_no")
// 7
urlRequest.addValue(parameterSSNo, forHTTPHeaderField: "ss_no")
// 8
urlRequest.addValue("", forHTTPHeaderField: "user_agent")
// 9
urlRequest.addValue(qstr, forHTTPHeaderField: "file")
let boundary = "Boundary-\(UUID().uuidString)"
urlRequest.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
print("LOG 03") // I SEE THIS LOG
//create body
let body = NSMutableData()
//append first line
let line1_boundryPrefix = "--\(boundary)\r\n"
body.append(line1_boundryPrefix.data(
using: String.Encoding.utf8,
allowLossyConversion: false)!)
//append second line
let line2_parameter = "Content-Disposition: form-data; name=\"source\"; filename=\"" + fileName + "\"\r\n"
body.append(line2_parameter.data(
using: String.Encoding.utf8,
allowLossyConversion: false)!)
//append third line (mime type)
let mimeType = "image/jpg"
let line3_contentType = "Content-Type: \(mimeType)\r\n\r\n"
body.append(line3_contentType.data(
using: String.Encoding.utf8,
allowLossyConversion: false)!)
//append image data
//line4
body.append(data)
let line5 = "\r\n"
body.append(line5.data(
using: String.Encoding.utf8,
allowLossyConversion: false)!)
let line6 = "--" + boundary + "--\r\n"
body.append(line6.data(
using: String.Encoding.utf8,
allowLossyConversion: false)!)
urlRequest.httpBody = body as Data
urlRequest.setValue(String(body.length), forHTTPHeaderField: "Content-Length")
URLSession.shared.dataTask(with: urlRequest) { (data, urlResponse, error) in
//handle callback
print("LOG 04, urlResponse: \(urlResponse)") // I DON'T SEE THIS LOG
}
print("LOG END") // I SEE THIS LOG
}
这是 Xcode 输出的结果 window:
LOG 01
LOG 02
LOG 03
LOG END
我没看到LOG04
我正在将 UIImage
参数(paramaterImage: UIImage)从下面的结构发送到 uploadPicture
方法:
import UIKit
struct MyMedia {
let key: String
let filename: String
let data: Data?
let mimeType: String
init?(withImage image: UIImage, forKey key: String) {
self.key = key
self.mimeType = "image/jpeg"
self.filename = "temppicname.jpg"
self.data = image.jpegData(compressionQuality: 1)
}
}
您必须对该任务调用 resume()
,否则它不会启动:
let task = URLSession.shared.dataTask(with: urlRequest) { (data, urlResponse, error) in
//handle callback
print("LOG 04, urlResponse: \(urlResponse)") // I DON'T SEE THIS LOG
}
task.resume()
之后,您需要确保按照与邮递员相同的方式格式化请求,否则服务器将拒绝它。
我建议您使用 Charles 代理之类的东西来比较您的应用程序发送的内容与您在 Postman 中发送的内容。
乍一看,您似乎是在根据请求 headers 发送 p_type
等,但在 Postman 的示例中,这些值是表单的一部分。