Pembaruan: Solusi ditemukan. Anda dapat membacanya di akhir posting.
Saya mencoba melakukan permintaan POST ke API REST jarak jauh menggunakan NSURLSession
. Idenya adalah membuat permintaan dengan dua parameter: deviceId
dan textContent
.
Masalahnya adalah bahwa parameter tersebut tidak dikenali oleh server. Bagian server berfungsi dengan benar karena saya telah mengirim POST menggunakan POSTMAN untuk Google Chrome dan berfungsi dengan baik.
Ini adalah kode yang saya gunakan sekarang:
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];
Saya sudah mencoba prosedur yang sama dengan 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];
Ada ide?
Larutan
Masalah dengan pendekatan saya adalah bahwa saya mengirim Content-Type
header yang salah dengan semua permintaan saya. Jadi satu-satunya perubahan yang diperlukan agar kode berfungsi dengan benar adalah menghapus Content-Type = application/json
tajuk HTTP. Jadi kode yang benar adalah ini:
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];
Mengirim gambar bersama dengan parameter lainnya
Jika Anda perlu memposting gambar bersama dengan parameter lain menggunakan di NSURLSession
sini Anda memiliki contoh:
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];
sumber
NSURLSessionUploadTask
, itu memposting data mentah ke server Anda. Anda masih dapat bekerja dengan - misalnya, melaluifile_get_contents('php://input') in PHP
- tetapi Anda harus memasukkan data lain di header.Content-Type
semua yang saya butuhkan untuk mencari tahu. Terima kasih!Jawaban:
Anda dapat mencoba menggunakan NSDictionary untuk params. Berikut ini akan mengirim parameter dengan benar ke server JSON.
Semoga ini bisa membantu (Saya mencoba mengurutkan masalah keaslian CSRF dengan yang di atas - tetapi mengirimkan params di NSDictionary).
sumber
NSJSONSerialization
) dan saya telah menambahkan kode untuk mengirim gambar bersama dengan parameter lainnya. Saya telah memperbarui pos aslinya. Terima kasih atas bantuan Anda :-)Motivasi
Kadang - kadang saya telah mendapatkan beberapa kesalahan ketika Anda ingin melewatkan httpBody serial ke
Data
dariDictionary
, yang pada kebanyakan kasus adalah karena salah pengkodean atau salah data karena objek yang tidak sesuai NSCoding di InternetDictionary
.Larutan
Bergantung pada kebutuhan Anda, satu solusi mudah adalah membuat
String
alih - alihDictionary
dan mengubahnya menjadiData
. Anda memiliki contoh kode di bawah ini yang ditulis padaObjective-C
danSwift 3.0
.Objektif-C
Cepat
sumber
url
, lalumethod
makabody
harus bisa berubah? Dan jika itu yang terjadi maka di mana akan perlu digunakanNSURLRequest
?Anda dapat menggunakan https://github.com/mxcl/OMGHTTPURLRQ
sumber
Solusi Swift 2.0 ada di sini:
sumber
Jika Anda menggunakan Swift, perpustakaan Just melakukan ini untuk Anda. Contoh dari file readme itu:
sumber
Kode Teja Kumar Bethina berubah untuk Swift 3:
sumber
sumber
-[NSUserDefaults synchronize]
. Dari dokumentasi Apple "metode ini tidak perlu dan tidak boleh digunakan."