ios nsurlsessionn ios6 会怎样

ios - Send POST request using NSURLSession - Stack Overflow
to customize your list.
Stack Overflow is a community of 4.7 million programmers, just like you, helping each other.
J it only takes a minute:
Join the Stack Overflow community to:
Ask programming questions
Answer and help your peers
Get recognized for your expertise
Update: Solution found. You can read it at the end of the post.
I'm trying to perform a POST request to a remote REST API using NSURLSession. The idea is to make a request with two parameters: deviceId and textContent.
The problem is that those parameters are not recognized by the server. The server part works correctly because I've sent a POST using POSTMAN for Google Chrome and it worked perfectly.
This is the code I'm using right now:
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];
I've tried the same procedure with a 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];
Any ideas?
The problem with my approach was that I was sending the incorrect Content-Type header with all my requests. So the only change needed for the code to work correctly is to remove the Content-Type = application/json HTTP header. So the correct code would be this:
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];
Sending images along with other parameters
If you need to post images along with other parameters using NSURLSession here you have an example:
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- 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- 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- 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",
: @"application/json",
@"Content-Type"
: [NSString stringWithFormat:@"multipart/form- 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 =
NSURLSessionDataTask *uploadTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
// Process the response
[uploadTask resume];
2,38741720
You could try using a NSDictionary for the params. The following will send the parameters correctly to a JSON server.
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
NSURL *url = [NSURL URLWithString:@"[JSON SERVER"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
[request addValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request addValue:@"application/json" forHTTPHeaderField:@"Accept"];
[request setHTTPMethod:@"POST"];
NSDictionary *mapData = [[NSDictionary alloc] initWithObjectsAndKeys: @"TEST IOS", @"name",
@"IOS TYPE", @"typemap",
NSData *postData = [NSJSONSerialization dataWithJSONObject:mapData options:0 error:&error];
[request setHTTPBody:postData];
NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
[postDataTask resume];
Hope this helps (I'm trying to sort a CSRF authenticity issue with the above - but it does send the params in the NSDictionary).
2,95421724
You can use
id config = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:someID];
id session = [NSURLSession sessionWithConfiguration:config delegate:someObject delegateQueue:[NSOperationQueue new]];
OMGMultipartFormData *multipartFormData = [OMGMultipartFormData new];
[multipartFormData addFile:data1 parameterName:@"file1" filename:@"myimage1.png" contentType:@"image/png"];
NSURLRequest *rq = [OMGHTTPURLRQ POST:url:multipartFormData];
id path = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"upload.NSData"];
[rq.HTTPBody writeToFile:path atomically:YES];
[[session uploadTaskWithRequest:rq fromFile:[NSURL fileURLWithPath:path]] resume];
12.5k65881
Sometimes you have been getting some errors when you want to pass HTTPBody serialized to NSData from NSDictionary, and YES I don't know why. I tried out another solution which worked perfectly:
//Init the NSURLSession with a configuration
NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration: defaultConfigObject delegate: nil delegateQueue: [NSOperationQueue mainQueue]];
//Create an URLRequest
NSURL *url = [NSURL URLWithString:@"yourURL"];
NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url];
//Create POST Params and add it to HTTPBody
NSString *params = @"api_key=APIKEY&email=&password=password";
[urlRequest setHTTPMethod:@"POST"];
[urlRequest setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]];
//Create task
NSURLSessionDataTask *dataTask = [defaultSession dataTaskWithRequest:urlRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
//Handle your response here
[dataTask resume];
Hope it helps someone who is facing trouble with the NSDictionary issue
6,56242651
If you are using Swift, the
library does this for you. Example from it's readme file:
talk to registration end point
Just.post(
"http://justiceleauge.org/member/register",
data: ["username": "barryallen", "password":"ReverseF1ashSucks"],
files: ["profile_photo": .URL(fileURLWithPath:"flash.jpeg", nil)]
if (r.ok) { /* success! */ }
1,15711323
Swift 2.0 solution is here:
let urlStr = “http://url_to_manage_post_requests”
let url = NSURL(string: urlStr)
let request: NSMutableURLRequest =
NSMutableURLRequest(URL: url!) request.HTTPMethod = "POST"
request.setValue(“application/json” forHTTPHeaderField:”Content-Type”)
request.timeoutInterval = 60.0
//additional headers
request.setValue(“deviceIDValue”, forHTTPHeaderField:”DeviceId”)
let bodyStr = “string or data to add to body of request”
let bodyData = bodyStr.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true) request.HTTPBody = bodyData
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(request){
(data: NSData?, response: NSURLResponse?, error: NSError?) -& Void in
if let httpResponse = response as? NSHTTPURLResponse {
print("responseCode \(httpResponse.statusCode)")
if error != nil {
// You can handle error response here
print("\(error)")
//Converting response to collection formate (array or dictionary)
let jsonResult: AnyObject = (try NSJSONSerialization.JSONObjectWithData(data!, options:
NSJSONReadingOptions.MutableContainers))
//success code
//failure code
task.resume()
Your Answer
Sign up or
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Post as a guest
By posting your answer, you agree to the
Not the answer you're looking for?
Browse other questions tagged
Stack Overflow works best with JavaScript enabled[ios]异步上载与 NSURLSession 将无法工作,但不会同步 NSURLConnection
注意事项: 本文中文内容可能为机器翻译,如要查看英文原文请点击上面连接.
编辑: 我要上传的文件以异步方式从 iPhone 到 Python 的服务器端进程。我想请求以异步方式这样做,它工作的时候可以显示一个繁忙的动画。
该请求需要包括用户名、 密码和文件作为多部分/窗体-数据。
可以拿工作同步使用的代码看起来像这 NSURLConnection::
-(void) uploadDatabase{
Database *databasePath = [[Database alloc] init];
NSString *targetPath = [databasePath getPathToDatabaseInDirectory];
NSData *dbData = [NSData dataWithContentsOfFile:targetPath];
NSString *url = @"/api/upload/";
//NSString *username = [[NSUserDefaults standardUserDefaults] stringForKey:USERNAME];
NSString *username = @"user";
NSString *password = @"pass";
NSMutableURLRequest *request = [self createRequestForUrl:url withUsername:username andPassword:password andData:dbData];
NSURLResponse *
NSData *result = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSString *stringResult = [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding];
NSLog(@"**server info %@", stringResult);}
/ / 请求建设
-(NSMutableURLRequest*) createRequestForUrl: (NSString*)urlString withUsername:(NSString*)username andPassword:(NSString*)password andData:(NSData*)dbData
{NSURL *url = [NSURL URLWithString:urlString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:60.0];
[request setHTTPMethod:@"POST"];
NSString *boundary = @"BOUNDARY_STRING";
NSString *contentType = [NSString stringWithFormat:@"multipart/form- boundary=%@", boundary];
[request addValue:contentType forHTTPHeaderField:@"Content-Type"];
NSMutableData *body = [NSMutableData data];
if(dbData != NULL)
//only send these methods when transferring data as well as username and password
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form- name=\"file\"; filename=\"dbfile\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[NSData dataWithData:dbData]];
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form- name=\"username\"\r\n\r\n%@", username] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form- name=\"password\"\r\n\r\n%@", password] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPBody:body];
然而,当我尝试以异步方式使用 NSURLSession 执行此操作时它似乎能正常工作。带有 NSURLSession 的代码如下所示:
-(void)uploadDatabase{
Database *databasePath = [[Database alloc] init];
NSString *targetPath = [databasePath getPathToDatabaseInDirectory];
NSURL *phonedbURL = [NSURL URLWithString:targetPath];
NSString *url = @"/api/upload/";
NSString *username = @"user";
NSString *password = @"pass";
NSMutableURLRequest *request = [self createRequestForUrl:url withUsername:username andPassword:password andData:NULL];
NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
self.uploadSession = [NSURLSession sessionWithConfiguration:defaultConfigObject delegate:self delegateQueue:Nil];
NSLog(@"the url = %@",url);
NSURLSessionUploadTask *uploadTask = [self.uploadSession uploadTaskWithRequest:request fromFile:phonedbURL];
[uploadTask resume];}
我竭力要看什么以不同的方式在做虽然看起来这应该工作。
在使用 NSURLSession 做异步请求的正确方法吗?我是新到 NSURLSession 所以我要改变我的 NSURLSession 请求的 NSURLMutableRequest,而不是 NSURLConnection 吗?
提前感谢任何帮助 !
解决方法 1:
如果你只是想要让您的请求异步,您可能会考虑使用 NSURLConnection 方法 sendAsynchronousRequest ,而不是 sendSynchronousRequest 因为 (a) 这是容易过渡与您现有的代码 ; 和 (b) NSURLSession 是只可用在 iOS 7 及更高版本,所以你可能会想要呆在一起 NSURLConnection 如果您需要支持对于较早的 iOS 版本。
话虽如此,一旦你开始使用 NSURLSession ,您可能会发现自己绘制它。例如,你可以使用 [NSURLSessionConfiguration backgroundSessionConfiguration:] ,然后有上传进度,即使在 app 已经进入背景后。(您必须编写委托的几种方法,因此,为方便起见,我还是使用了下面的简单前景上载.)这只是问题您的业务需求,抵消了新的 NSURLSession 功能与 iOS 7 + 限制它需要。
顺便说一句,任何有关网络请求在 iOS/MacOS 的谈话是没有的引用可能不完整。它极大地简化了创建这些多部分请求和绝对值得调查。他们有 NSURLSession 支持,太 (但我没有使用它们的会话包装,所以不能跟它说)。但 AFNetworking 是无疑值得您考虑。您可以享受丰富的委托基地 API 的一些 (例如进度更新,可取消请求,操作等之间的依赖关系),将远远更大的控制,可提供与方便的方法 (像 sendSynchronousRequest ),但无需拖动您通过委托方法本身的杂草。
无论如何,如果你真的感兴趣怎么办上载与 NSURLSession ,见下文。
如果你想要通过上传 NSURLSession ,它是轻微转变思路,即分离请求 (和其标头) 的配置在 NSMutableURLRequest 从创建请求的正文 (你现在在的实例化过程中指定的 NSURLSessionUploadTask )。现在您指定如上载任务的一部分可以是请求的正文 NSData 、 一个文件,或流 (我使用 NSData 下面,因为我们正在建立一个多部分请求):
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:@"POST"];
NSString *boundary = [self boundaryString];
[request addValue:[NSString stringWithFormat:@"multipart/form- boundary=%@", boundary] forHTTPHeaderField:@"Content-Type"];
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];
NSData *fileData = [NSData dataWithContentsOfFile:path];
NSData *data = [self createBodyWithBoundary:boundary username:@"rob" password:@"password" data:fileData filename:[path lastPathComponent]];
NSURLSessionUploadTask *task = [session uploadTaskWithRequest:request fromData:data completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSAssert(!error, @"%s: uploadTaskWithRequest error: %@", __FUNCTION__, error);
// parse and interpret the response `NSData` however is appropriate for your app
[task resume];
创造 NSData 正在发送非常类似于您现有的代码:
- (NSData *) createBodyWithBoundary:(NSString *)boundary username:(NSString*)username password:(NSString*)password data:(NSData*)data filename:(NSString *)filename
NSMutableData *body = [NSMutableData data];
if (data) {
//only send these methods when transferring data as well as username and password
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form- name=\"file\"; filename=\"%@\"\r\n", filename] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n\r\n", [self mimeTypeForPath:filename]] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:data];
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form- name=\"username\"\r\n\r\n%@", username] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form- name=\"password\"\r\n\r\n%@", password] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
你硬编码的边界和 mime 类型,这很好,但上述情况发生,请使用下列方法:
- (NSString *)boundaryString
// generate boundary string
// adapted from /library/ios/#samplecode/SimpleURLConnections
uuid = CFUUIDCreate(NULL);
assert(uuid != NULL);
uuidStr = CFBridgingRelease(CFUUIDCreateString(NULL, uuid));
assert(uuidStr != NULL);
CFRelease(uuid);
return [NSString stringWithFormat:@"Boundary-%@", uuidStr];
- (NSString *)mimeTypeForPath:(NSString *)path
// get a mime type for an extension using MobileCoreServices.framework
CFStringRef extension = (__bridge CFStringRef)[path pathExtension];
CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, extension, NULL);
assert(UTI != NULL);
NSString *mimetype = CFBridgingRelease(UTTypeCopyPreferredTagWithClass(UTI, kUTTagClassMIMEType));
assert(mimetype != NULL);
CFRelease(UTI);}

我要回帖

更多关于 nsurlsession https 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信