Update: Lösung gefunden. Sie können es am Ende des Beitrags lesen.
Ich versuche, eine POST-Anforderung an eine Remote-REST-API mit auszuführen NSURLSession
. Die Idee ist, eine Anfrage mit zwei Parametern zu stellen: deviceId
und textContent
.
Das Problem ist, dass diese Parameter vom Server nicht erkannt werden. Der Serverteil funktioniert ordnungsgemäß, da ich einen POST mit POSTMAN für Google Chrome gesendet habe und er einwandfrei funktioniert hat.
Dies ist der Code, den ich gerade verwende:
NSString *deviceID = [[NSUserDefaults standardUserDefaults] objectForKey:@"deviceID"];
NSString *textContent = @"New note";
NSString *noteDataString = [NSString stringWithFormat:@"deviceId=%@&textContent=%@", deviceID, textContent];
NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
sessionConfiguration.HTTPAdditionalHeaders = @{
@"api-key" : @"API_KEY",
@"Content-Type" : @"application/json"
};
NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration];
NSURL *url = [NSURL URLWithString:@"http://url_to_manage_post_requests"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPBody = [noteDataString dataUsingEncoding:NSUTF8StringEncoding];
request.HTTPMethod = @"POST";
NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
// The server answers with an error because it doesn't receive the params
}];
[postDataTask resume];
Ich habe das gleiche Verfahren mit einem versucht NSURLSessionUploadTask
:
// ...
NSURL *url = [NSURL URLWithString:@"http://url_to_manage_post_requests"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request fromData:[noteDataString dataUsingEncoding:NSUTF8StringEncoding] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
// The server answers with an error because it doesn't receive the params
}];
[uploadTask resume];
Irgendwelche Ideen?
Lösung
Das Problem bei meinem Ansatz war, dass ich Content-Type
mit all meinen Anfragen den falschen Header gesendet habe. Die einzige Änderung, die erforderlich ist, damit der Code ordnungsgemäß funktioniert, ist das Entfernen des Content-Type = application/json
HTTP-Headers. Der richtige Code wäre also:
NSString *deviceID = [[NSUserDefaults standardUserDefaults] objectForKey:@"deviceID"];
NSString *textContent = @"New note";
NSString *noteDataString = [NSString stringWithFormat:@"deviceId=%@&textContent=%@", deviceID, textContent];
NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
sessionConfiguration.HTTPAdditionalHeaders = @{
@"api-key" : @"API_KEY"
};
NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration];
NSURL *url = [NSURL URLWithString:@"http://url_to_manage_post_requests"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPBody = [noteDataString dataUsingEncoding:NSUTF8StringEncoding];
request.HTTPMethod = @"POST";
NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
// The server answers with an error because it doesn't receive the params
}];
[postDataTask resume];
Senden von Bildern zusammen mit anderen Parametern
Wenn Sie hier Bilder zusammen mit anderen Parametern veröffentlichen müssen, NSURLSession
haben Sie ein Beispiel:
NSString *deviceID = [[NSUserDefaults standardUserDefaults] objectForKey:@"deviceID"];
NSString *textContent = @"This is a new note";
// Build the request body
NSString *boundary = @"SportuondoFormBoundary";
NSMutableData *body = [NSMutableData data];
// Body part for "deviceId" parameter. This is a string.
[body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", @"deviceId"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"%@\r\n", deviceID] dataUsingEncoding:NSUTF8StringEncoding]];
// Body part for "textContent" parameter. This is a string.
[body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", @"textContent"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"%@\r\n", textContent] dataUsingEncoding:NSUTF8StringEncoding]];
// Body part for the attachament. This is an image.
NSData *imageData = UIImageJPEGRepresentation([UIImage imageNamed:@"ranking"], 0.6);
if (imageData) {
[body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"image.jpg\"\r\n", @"image"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"Content-Type: image/jpeg\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:imageData];
[body appendData:[[NSString stringWithFormat:@"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
}
[body appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
// Setup the session
NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
sessionConfiguration.HTTPAdditionalHeaders = @{
@"api-key" : @"55e76dc4bbae25b066cb",
@"Accept" : @"application/json",
@"Content-Type" : [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary]
};
// Create the session
// We can use the delegate to track upload progress
NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration delegate:self delegateQueue:nil];
// Data uploading task. We could use NSURLSessionUploadTask instead of NSURLSessionDataTask if we needed to support uploads in the background
NSURL *url = [NSURL URLWithString:@"URL_TO_UPLOAD_TO"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
request.HTTPBody = body;
NSURLSessionDataTask *uploadTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
// Process the response
}];
[uploadTask resume];
quelle
NSURLSessionUploadTask
, werden tangential Rohdaten auf Ihrem Server veröffentlicht. Mit denen Sie noch arbeiten können - zum Beispiel überfile_get_contents('php://input') in PHP
-, aber Sie müssen andere Daten in die Header aufnehmen.Content-Type
war alles, was ich brauchte, um die Dinge herauszufinden. Vielen Dank!Antworten:
Sie können versuchen, ein NSDictionary für die Parameter zu verwenden. Im Folgenden werden die Parameter korrekt an einen JSON-Server gesendet.
Hoffe, das hilft (ich versuche, ein CSRF-Authentizitätsproblem mit dem oben genannten zu lösen - aber es sendet die Parameter im NSDictionary).
quelle
NSJSONSerialization
ich muss mich nicht damit anlegen ) und den Code hinzugefügt, um Bilder zusammen mit anderen Parametern zu veröffentlichen. Ich habe den ursprünglichen Beitrag aktualisiert. Vielen Dank für Ihre Hilfe :-)Motivation
Manchmal habe ich immer einige Fehler , wenn Sie übergeben mögen httpBody serialisiert
Data
ausDictionary
, die auf den meisten Fällen sind wegen der falschen Codierung oder fehlerhafte Daten aufgrund nicht NSCoding konformen Objekte in derDictionary
.Lösung
Abhängig von Ihren Anforderungen besteht eine einfache Lösung darin, eine
String
anstelle von zu erstellenDictionary
und diese zu konvertierenData
. Sie haben die folgenden Codebeispiele aufObjective-C
und geschriebenSwift 3.0
.Ziel c
Schnell
quelle
url
, dannmethod
dannbody
so muss es wandelbar sein? Und wenn dies der Fall ist, wo müsste es dann jemals verwendet werdenNSURLRequest
?Sie können https://github.com/mxcl/OMGHTTPURLRQ verwenden
quelle
Die Swift 2.0-Lösung ist da:
quelle
Wenn Sie Swift verwenden, erledigt die Just- Bibliothek dies für Sie. Beispiel aus der Readme-Datei:
quelle
Der Code von Teja Kumar Bethina wurde für Swift 3 geändert:
quelle
quelle
-[NSUserDefaults synchronize]
. Aus der Apple-Dokumentation geht hervor, dass diese Methode nicht erforderlich ist und nicht verwendet werden sollte.