[WARNUNG]
Wie ich, dass diese Frage bin sehen wird immer bemerkt mehr, als es sollte, ich möchte Ihnen sagen, nicht von der verwenden folgender Code
Zu der Zeit, als ich die Frage stellte, hatte Swift weniger als ein Jahr, bewegte sich schnell, die meisten Bibliotheken waren nicht Swift-freundlich und instabil. Ich empfehle dringend, dass Sie versuchen, Alamofire oder eine andere Bibliothek für diese Art von Aufgabe zu verwenden. Aber tu es nicht selbst.
[/ WARNUNG]ein Bild und Parameter mit multipart/form-data in Swift Hochladen
ich ein Bild auf einen Drupal Endpunkt hochladen möchten.
Das Problem, das ich habe, ist, dass ich eine HTTP 200 OK-Antwort mit Text/HTML-Inhaltstyp erhalte. In der HTML-Antwort gibt es eine klare Nachricht, dass der Knoten korrekt erstellt wurde. Aber auf der Serverseite ist das Bild nicht mit dem Knoten verknüpft.
Ich erwarte auch nicht text/html, sondern application/json, wie ich es im Accept-Header angeben.
Es funktioniert bereits in der Android App mit Android Rest Template. Hier ist der Code als Referenz:
String url = getUrl("node/{info_id}/attach_file");
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
if (user.isLoggedIn()) {
headers.add(user.getSessionName(), user.getSessionId());
headers.add("X-CSRF-Token", user.getToken());
headers.add("Cookie", user.getSessionName() + "=" + user.getSessionId());
}
MultiValueMap<String, Object> parts = new LinkedMultiValueMap<>();
parts.add("files[field_mobileinfo_image]",
new FileSystemResource(info.getImageUri()));
parts.add("field_name", "field_mobileinfo_image");
HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<>(parts, headers);
return getRestTemplate().exchange(url, HttpMethod.POST, request, Void.class, info.getId()).getBody();
Ich weiß, ich habe nicht die Antwort in Android überprüfen (Void.class
), aber alles funktioniert und das Bild wird mit dem Knoten auf der Serverseite angebracht.
Jetzt auf iOS in Swift habe ich mehrere Dinge ausprobiert.
Mit AFNetworking:
func upload(mobileInfo: MobileInfo) {
let user = userService.load()
let url = Config.buildUrl("")
let manager = AFHTTPRequestOperationManager(baseURL: NSURL(string:url)!)
let serializer = AFHTTPRequestSerializer()
serializer.setValue(user.sessionId, forHTTPHeaderField: user.sessionName)
serializer.setValue(user.token, forHTTPHeaderField: "X-CSRF-Token")
serializer.setValue("\(user.sessionName)=\(user.sessionId)", forHTTPHeaderField: "Cookie")
manager.requestSerializer = serializer
manager.responseSerializer.acceptableContentTypes.removeAll(keepCapacity: false)
manager.responseSerializer.acceptableContentTypes.insert("application/json")
let imageData = UIImageJPEGRepresentation(mobileInfo.image, 0.3)
manager.POST("/node/\(mobileInfo.id)/attach_file", parameters: nil, constructingBodyWithBlock: { (formData) -> Void in
formData.appendPartWithFileData(
imageData,
name: "files[field_mobileinfo_image]",
fileName: "field_mobileinfo_image",
mimeType: "image/jpeg")
formData.appendPartWithFormData("field_mobileinfo_image".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true), name: "field_name")
},
success: { (operation, data) -> Void in
println(data)
}) { (operation, error) -> Void in
println(error)
}
}
manuell mit Informationen aus anderen Stackoverflow Fragen packte:
func upload2(mobileInfo: MobileInfo) {
let user = userService.load()
let imageData = UIImageJPEGRepresentation(mobileInfo.image, 0.3)
let url = NSURL(string:Config.buildUrl("/node/\(mobileInfo.id)/attach_file"))!
println(url)
var request = NSMutableURLRequest(URL: url)
var session = NSURLSession.sharedSession()
request.HTTPMethod = "POST"
var boundary = "---------------------------14737809831466499882746641449"
var contentType = "multipart/form-data; boundary=\(boundary)"
println(contentType)
request.addValue(contentType, forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.addValue("\(user.sessionName)=\(user.sessionId)", forHTTPHeaderField: "Cookie")
request.addValue(user.sessionId, forHTTPHeaderField: user.sessionName)
request.addValue(user.token, forHTTPHeaderField: "X-CSRF-Token")
println(request.allHTTPHeaderFields)
var body = NSMutableData()
body.appendData("\r\n--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("Content-Disposition: form-data; name=\"field_name\"\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("field_mobileinfo_image".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!)
body.appendData("\r\n--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("Content-Disposition: form-data; name=\"files[field_mobileinfo_image]\"; filename=\"img.jpg\"\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("Content-Type: application/octet-stream\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData(imageData)
body.appendData("\r\n--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
var returnData = NSURLConnection.sendSynchronousRequest(request, returningResponse: nil, error: nil)
var returnString = NSString(data: returnData!, encoding: NSUTF8StringEncoding)
println("returnString \(returnString)")
}
Mit SRWebClient:
func upload3(mobileInfo: MobileInfo) {
let user = userService.load()
let imageData:NSData = NSData(data: UIImageJPEGRepresentation(mobileInfo.image, 0.3))
SRWebClient.POST("http://master.test.lesfrontaliers.lu/node/\(mobileInfo.id)/attach_file")
.headers(["Accept": "application/json",
user.sessionName: user.sessionId,
"X-CSRF-Token": user.token,
"Cookie": "\(user.sessionName)=\(user.sessionId)"])
.data(imageData, fieldName:"files[field_mobileinfo_image]", data:["field_name":"field_mobileinfo_image"])
.send({ (response: AnyObject!, status: Int) -> Void in
println(status)
println(response)
},failure:{(error:NSError!) -> Void in
println(error)
})
}
Bitte rette mich! ;-) Ich habe so viele Dinge ausprobiert, dass es funktioniert, dass ich nicht mehr sehen kann, wenn ich etwas falsch mache. Es scheint in Ordnung für mich. Der einzige Unterschied, den ich sehen kann, ist, dass ich das Bild nicht auf dem Dateisystem ablege, sondern direkt die binären Daten sende, die am Ende dasselbe sind.Hier
ist ein Bild des Antrags in Postman erstellt (Arbeits- und Empfangen von json)
[EDIT] Wenn es kann hier jemand helfen den richtigen Code des falschen Teil der ist über manuelle Anfrage:
var body = NSMutableData()
body.appendData("--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("Content-Disposition: form-data; name=\"field_name\"\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("field_mobileinfo_image\r\n".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!)
body.appendData("--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("Content-Disposition: form-data; name=\"files[field_mobileinfo_image]\"; filename=\"img.jpg\"\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("Content-Type: image/jpeg\r\n\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData(imageData)
body.appendData("\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData("--\(boundary)--\r\n".dataUsingEncoding(NSUTF8StringEncoding)!)
request.HTTPBody = body
wie ist das getan, wenn ich Post-Parameter auch senden muss? http://stackoverflow.com/questions/30006290/uploading-image-in-swift-with-multiple-parameters – Tyler
Warum geben Sie 'image.jpeg' an, wenn Ihre Datei die Erweiterung' png' hat? –
Ich frage mich auch immer, was die zwei zusätzlichen, führenden Bindestriche vor dem Grenzstring ('--') sind. –