Alamofire 文件上传出现错误“JSON 文本未以数组或对象开头,并且允许未设置片段的选项”
Posted
技术标签:
【中文标题】Alamofire 文件上传出现错误“JSON 文本未以数组或对象开头,并且允许未设置片段的选项”【英文标题】:Alamofire file upload getting error "JSON text did not start with array or object and option to allow fragments not set" 【发布时间】:2018-01-12 06:36:05 【问题描述】:下面是我的代码引用this question answer
func createRequest(ResumeID: String, CandidateID: String, MediaName: String, FileExtension : String, MediaType : String) throws -> URLRequest
let parameters = NSDictionary(objects: [ResumeID, CandidateID, MediaName, FileExtension,MediaType], forKeys: ["ResumeID" as NSCopying, "CandidateID" as NSCopying, "MediaName" as NSCopying, "FileExtension" as NSCopying, "MediaType" as NSCopying])
let boundary = generateBoundaryString()
let url = URL(string: "http://192.168.1.29/ColorsKit_New_Svr/WTCSvr.svc/WTCService?Id=6&SPName=Usp_RTN_IU_CandidateSubmissionResume")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
let path1 = Bundle.main.path(forResource: "dummy-pdf_2", ofType: "pdf")!
request.httpBody = try createBody(with: parameters as? [String : String], filePathKey: "MediaContent", paths: [path1], boundary: boundary)
return request
private func createBody(with parameters: [String: String]?, filePathKey: String, paths: [String], boundary: String) throws -> 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 path in paths
let url = URL(fileURLWithPath: path)
let filename = url.lastPathComponent
let data = try Data(contentsOf: url)
let mimetype = mimeType(for: path)
body.append("--\(boundary)\r\n")
body.append("Content-Disposition: form-data; name=\"\(filePathKey)\"; filename=\"\(filename)\"\r\n")
body.append("Content-Type: \(mimetype)\r\n\r\n")
body.append(data)
body.append("\r\n")
body.append("--\(boundary)--\r\n")
return body
func sendMultipartRequest()
let request: URLRequest
do
request = try createRequest(ResumeID: "1", CandidateID: "1241124", MediaName: "dummy-pdf", FileExtension: "pdf", MediaType: "pdf")
catch
print(error)
return
let task = URLSession.shared.dataTask(with: request) data, response, error in
guard error == nil else
// handle error here
print(error!)
return
// if response was JSON, then parse it
do
let responseDictionary = try JSONSerialization.jsonObject(with: data!)
print("success == \(responseDictionary)")
// note, if you want to update the UI, make sure to dispatch that to the main queue, e.g.:
//
// DispatchQueue.main.async
// // update your UI and model objects here
//
catch
print(error)
let responseString = String(data: data!, encoding: .utf8)
print("responseString = \(String(describing: responseString))")
task.resume()
我得到的回应是:
Error Domain=NSCocoaErrorDomain Code=3840 "JSON 文本没有开始 带有数组或对象以及允许未设置片段的选项。” UserInfo=NSDebugDescription=JSON 文本不是以数组开头或 允许未设置片段的对象和选项。 responseString = 可选(“未找到记录”)
这很奇怪,因为 Postman 给出了正确的响应。意味着仅代码中缺少某些内容:(
【问题讨论】:
在你的后端检查一次,它是一个有效的 JSON 这应该是有效的,因为我通过“邮递员”得到了完美的回应 post Man 给出正确答案,根据我们的编码级别,它会出现错误, 是的,我只是在说 顺便说一句,您的问题标题和标签说 Alamofire,但您是手动构建它(这比 Alamofire 工作量更大)。你要不要使用 Alamofire? 【参考方案1】:使用 Alamofire
let upload_url = "your url"
let fieldName = "UploadedFile"
let mimeType = "plain/text"
Alamofire.upload(multipartFormData: multipartFormData in
//you can add multiple file
multipartFormData.append(fileData as Data, withName: fieldName, fileName: fileName, mimeType: mimeType)
, to: upload_url, method: .post, headers: ["Authorization": "auth_token"],
encodingCompletion: encodingResult in
switch encodingResult
case .success(let upload, _, _):
upload.response [weak self] response in
guard let _ = self else
return
debugPrint(response)
case .failure(let encodingError):
debugPrint("uploaderService error:\(encodingError)")
)
【讨论】:
【参考方案2】:如下使用 JSONSerialization
if let responseDictionary = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? String
...
【讨论】:
以上是关于Alamofire 文件上传出现错误“JSON 文本未以数组或对象开头,并且允许未设置片段的选项”的主要内容,如果未能解决你的问题,请参考以下文章
Alamofire(Swift 3):对成员“上传(..”)的模糊引用