AFNETWORKING 3.0 Data Parameter Nil Error - ios

I am getting the JSON back that I need, then I segue to another view controller to populate the data into a table view. The data populates, but the app crashes 2 minutes later with a data parameter is nil error.
Is there a way for me to stop the session from running after it completes? It appears to keep running non stop.
My header and implementation file code on pasteBin: https://pastebin.com/M11EF7Yp
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
NSDictionary *body = #{#"search": self.searchBar.text};
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:body options:0 error:&error];
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSString *url = #"https://iosdevfitbody.herokuapp.com/fitbodylocations/search.json";
NSMutableURLRequest *request = [[AFJSONRequestSerializer serializer] requestWithMethod:#"POST" URLString:url parameters:nil error:nil];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:[jsonString dataUsingEncoding:NSUTF8StringEncoding]];
[[manager dataTaskWithRequest:request completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) {
if (!error) {
if ([responseObject isKindOfClass:[NSDictionary class]]) {
self.results = [[NSMutableArray alloc] initWithArray:[responseObject objectForKey: #"message"]];
}
} else {
NSLog(#"Error: %#, %#, %#", error, response, responseObject);
}
}]resume];

Related

How to add Dictionary as a Request Parameter For HTTPBody in NSJSONSerialization?

I am creating one demo Web Services Code without using AFNetworking Framework.
My HTTP Request Parameter in Dictionary.
How can I set it on HTTPBody?
MY Code is as follow
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:aUrl];
[request setHTTPMethod:#"POST"];
NSString *postString = "Request Parameter";
[request setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding]];
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
[[session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSString *requestReply = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
// NSLog(#"requestReply: %#", requestReply);
NSError *jsonError;
NSData *objectData = [requestReply dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:objectData
options:NSJSONReadingMutableContainers
error:&jsonError];
NSLog(#"requestReply: %#", json);
}] resume];
You Can Do like that With AFnetworking and Without Af Networking.
NSString *stringUrl = #"xxx";
NSURLSessionConfiguration *myConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFHTTPSessionManager *myManager = [[AFHTTPSessionManager alloc]initWithSessionConfiguration:myConfiguration];
AFHTTPResponseSerializer *mySerilizer = [[AFHTTPResponseSerializer alloc]init];
[myManager setResponseSerializer:mySerilizer];
NSDictionary *param = [[NSDictionary alloc]initWithObjectsAndKeys:#"value==",#"Token", nil];
NSData *data = [NSJSONSerialization dataWithJSONObject:param options:NSJSONWritingPrettyPrinted error:nil];
NSString *string = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
NSDictionary *requestParameter = [NSDictionary dictionaryWithObject:string forKey:#"request"];
[manager POST:stringUrl parameters:requestParameter progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSError *error;
if(!error)
{
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:responseObject options:kNilOptions error:&error];
NSLog(#"%#",dict);
}
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
}];
Without Dictionary
NSString *urlString = #"xxxx";
// Do any additional setup after loading the view, typically from a nib.
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc]initWithSessionConfiguration:configuration];
AFHTTPResponseSerializer *serilizer = [[AFHTTPResponseSerializer alloc]init];
[manager setResponseSerializer:serilizer];
NSDictionary *dict = [[NSDictionary alloc]initWithObjectsAndKeys:#"value",#"key", nil];
[manager POST:urlString parameters:dict progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSError *error;
if(!error)
{
NSDictionary *finalData = [NSJSONSerialization JSONObjectWithData:responseObject options:kNilOptions error:&error];
NSLog(#"Final Data is %#",finalData);
}
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
}];
Without AFNetworking
NSString *MyUrlString = #"xxxx";
NSURL *url = [NSURL URLWithString:MyUrlString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
NSString *postString = #"key=value";
[request setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding]];
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
[[session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSError *jsonError;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingMutableContainers
error:&jsonError];
NSLog(#"requestReply: %#", json);
}] resume];
Note:-Do not forget to put resume
Thank you
Check your condition with my working code,
NSMutableURLRequest *_request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:URL]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:50.0];
[_request addValue:#"application/json" forHTTPHeaderField:#"Content-Type"]; // Interact your backend developer for header
[_request addValue:#"application/json" forHTTPHeaderField:#"Accept"];// Interact your backend developer for header
[_request setHTTPMethod:#"POST"];
NSError *error;
NSData *_inputData = [NSJSONSerialization dataWithJSONObject:inputDictionary options:0 error:&error];
[_request setHTTPBody:_inputData];
NSURLSessionDataTask *_fetchData = [[[self class] session] dataTaskWithRequest:_request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if(!error) {
NSError* error;
completionBlock(data,error,1);
} else {
completionBlock(data,error,0);
}
}];
[_fetchData resume];
Got The Data
NSURL *stringwithUrl = [NSURL URLWithString:#"XXXX"];
NSMutableURLRequest *requestUrl = [NSMutableURLRequest requestWithURL:stringwithUrl];
[requestUrl setHTTPMethod:#"POST"];
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:#"Value==",#"Key", nil];
NSData *data = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:nil];
NSString *mainString = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
NSString *requestString = #"request=";
NSString *finalString = [requestString stringByAppendingString:mainString];
[requestUrl setHTTPBody:[finalString dataUsingEncoding:NSUTF8StringEncoding]];
NSURLSession *sesion = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
[[sesion dataTaskWithRequest:requestUrl completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
NSLog(#"%#",dict);
}]resume];

AFNetworking 3 - objective c - send data without key [duplicate]

I am trying to make an HTTP PUT request using AFNetworking to create an attachment in a CouchDB server. The server expects a base64 encoded string in the HTTP body. How can I make this request without sending the HTTP body as a key/value pair using AFNetworking?
I began by looking at this method:
- (void)putPath:(NSString *)path
parameters:(NSDictionary *)parameters
success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure;
But here the parameters are to be of type: NSDictionary. I just want to send a base64 encoded string in the HTTP body but not associated with a key. Can someone point me to the appropriate method to use? Thanks!
Hejazi's answer is simple and should work great.
If, for some reason, you need to be very specific for one request - for example, if you need to override headers, etc. - you can also consider building your own NSURLRequest.
Here's some (untested) sample code:
// Make a request...
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:myURL];
// Generate an NSData from your NSString (see below for link to more info)
NSData *postBody = [NSData base64DataFromString:yourBase64EncodedString];
// Add Content-Length header if your server needs it
unsigned long long postLength = postBody.length;
NSString *contentLength = [NSString stringWithFormat:#"%llu", postLength];
[request addValue:contentLength forHTTPHeaderField:#"Content-Length"];
// This should all look familiar...
[request setHTTPMethod:#"POST"];
[request setHTTPBody:postBody];
AFHTTPRequestOperation *operation = [client HTTPRequestOperationWithRequest:request success:success failure:failure];
[client enqueueHTTPRequestOperation:operation];
The NSData category method base64DataFromString is available here.
You can use multipartFormRequestWithMethod method as following:
NSURLRequest *request = [self multipartFormRequestWithMethod:#"PUT" path:path parameters:parameters constructingBodyWithBlock:^(id <AFMultipartFormData> formData) {
[formData appendString:<yourBase64EncodedString>]
}];
AFHTTPRequestOperation *operation = [client HTTPRequestOperationWithRequest:request success:success failure:failure];
[client enqueueHTTPRequestOperation:operation];
Here you have an example sending a raw json:
NSDictionary *dict = ...
NSError *error;
NSData *dataFromDict = [NSJSONSerialization dataWithJSONObject:dict
options:NSJSONWritingPrettyPrinted
error:&error];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
NSMutableURLRequest *req = [[AFJSONRequestSerializer serializer] requestWithMethod:#"POST" URLString:YOUR_URL parameters:nil error:nil];
req.timeoutInterval = 30;
[req setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[req setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[req setValue:IF_NEEDED forHTTPHeaderField:#"Authorization"];
[req setHTTPBody:dataFromDict];
[[manager dataTaskWithRequest:req completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) {
if (!error) {
NSLog(#"%#", responseObject);
} else {
NSLog(#"Error: %#, %#, %#", error, response, responseObject);
}
}] resume];
NSData *data = someData;
NSMutableURLRequest *requeust = [NSMutableURLRequest requestWithURL:
[NSURL URLWithString:[self getURLWith:urlService]]];
[reqeust setHTTPMethod:#"PUT"];
[reqeust setHTTPBody:data];
[reqeust setValue:#"application/raw" forHTTPHeaderField:#"Content-Type"];
NSURLSessionDataTask *task = [manager uploadTaskWithRequest:requeust fromData:nil progress:^(NSProgress * _Nonnull uploadProgress) {
} completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) {
}];
[task resume];
I'm using AFNetworking 2.5.3 and create new POST method for AFHTTPRequestOperationManager.
extension AFHTTPRequestOperationManager {
func POST(URLString: String!, rawBody: NSData!, success: ((AFHTTPRequestOperation!, AnyObject!) -> Void)!, failure: ((AFHTTPRequestOperation!, NSError!) -> Void)!) {
let request = NSMutableURLRequest(URL: NSURL(string: URLString, relativeToURL: baseURL)!)
request.HTTPMethod = "POST"
request.HTTPBody = rawBody
let operation = HTTPRequestOperationWithRequest(request, success: success, failure: failure)
operationQueue.addOperation(operation)
}
}
Please use below method.
+(void)callPostWithRawData:(NSDictionary *)dict withURL:(NSString
*)strUrl withToken:(NSString *)strToken withBlock:(dictionary)block
{
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dict options:0 error:&error];
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
Please use below method.
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
NSMutableURLRequest *req = [[AFJSONRequestSerializer serializer] requestWithMethod:#"POST" URLString:[NSString stringWithFormat:#"%#/%#",WebserviceUrl,strUrl] parameters:nil error:nil];
req.timeoutInterval= [[[NSUserDefaults standardUserDefaults] valueForKey:#"timeoutInterval"] longValue];
[req setValue:strToken forHTTPHeaderField:#"Authorization"];
[req setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[req setValue:#"application/json" forHTTPHeaderField:#"Accept"];
[req setHTTPBody:[jsonString dataUsingEncoding:NSUTF8StringEncoding]];
[[manager dataTaskWithRequest:req completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) {
if (!error) {
if ([responseObject isKindOfClass:[NSData class]]) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
if ((long)[httpResponse statusCode]==201) {
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setObject:#"201" forKey:#"Code"];
if ([httpResponse respondsToSelector:#selector(allHeaderFields)]) {
NSDictionary *dictionary = [httpResponse allHeaderFields];
NSLog(#"%#",[dictionary objectForKey:#"Location"]);
[dict setObject:[NSString stringWithFormat:#"%#",[dictionary objectForKey:#"Location"]] forKey:#"Id"];
block(dict);
}
}
else if ((long)[httpResponse statusCode]==200) {
//Leave Hours Calculate
NSDictionary *serializedData = [NSJSONSerialization JSONObjectWithData:responseObject options:kNilOptions error:nil];
block(serializedData);
}
else{
}
}
else if ([responseObject isKindOfClass:[NSDictionary class]]) {
block(responseObject);
}
} else {
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setObject:ServerResponceError forKey:#"error"];
block(dict);
}
}] resume];
}

Flickr Search Photo objective-c nothing return

I have a problem with Flickr API.
I have created URLString
+ (NSString *)URLForSearchString:(NSString *)searchString {
NSString *APIKey = #"*****";
NSString *search = [searchString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
return [NSString stringWithFormat:#"https://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=%#&tags=%#&per_page=25&format=json&nojsoncallback=1", APIKey, search];}
And then, When I touched search button I called the request with NSURLSession.
- (void)searchFlickrPhotos:(NSString *)text {
NSString *urlString = [FlickrHelper URLForSearchString:#"Nature"];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString: urlString]];
[request setHTTPMethod:#"GET"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setValue:[UIDevice currentDevice].name forHTTPHeaderField:#"device"];
[request setTimeoutInterval:15];
NSURLSession *session;
session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
NSURLSessionDataTask * sessionDataTask = [session dataTaskWithRequest: request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSDictionary *temp = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
dispatch_async(dispatch_get_main_queue(), ^{
//For UI updates in main thread
});
}];
[sessionDataTask resume];}
I can't get the response from the server. My temp dictionary is always nil...
Would you write some detail solution?
I would be very grateful for the help!
In order to solve this, first
Check whether data is nil.
If it's not nil, then use the following LOC to see the output on the console
NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"RESPONSE: %#", str);
Now, you should be able to get another insight on what's actually happening.

Fetch data using Post method in Objective-c

I am fetching data using POST method. And I have successfully retrieved all the data.It's taking too long to display it in UI but I can print it immediately on console, my code is
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:#"http://www.xxxyyy.com/v1/api/client/authorize"]];
[request setHTTPMethod:#"POST"];
[request setValue:#"ABCD" forHTTPHeaderField:#"Authkey"];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
[[session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
{
NSString *requestReply = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
[request setValue:#"application/json;charset=UTF-8" forHTTPHeaderField:#"Authkey"];
NSData* data1 = [requestReply dataUsingEncoding:NSUTF8StringEncoding];
jsonReturnArray = [NSJSONSerialization JSONObjectWithData:data1 options:NSJSONReadingAllowFragments error:&error];
NSArray *array = [jsonReturnArray copy];
[self rec:array];
NSString *phoneNumber=[NSString stringWithFormat:#"%#",[jsonReturnArray valueForKey:#"phone"]];
lblPhoneNumber.text = phoneNumber;
NSString *Address=[NSString stringWithFormat:#"%# %# %#,CA %#",[jsonReturnArray valueForKey:#"street1"],[jsonReturnArray valueForKey:#"street2"],[jsonReturnArray valueForKey:#"city"],[jsonReturnArray valueForKey:#"postalcode"]];
lblAddress.text=Address;//takes long time to display
NSLog(#"%#",Address);//immeaditely print
strlatitude=[jsonReturnArray valueForKey:#"latitude"];
strlongitude=[jsonReturnArray valueForKey:#"longitude"];
[self Map:(MKMapView *)mapLocation didUpdateUserLocation:(MKUserLocation *)nil];//method call
}] resume];
This is take too time to print data, but if you use NSURLConnection class it may be help you.This is my Class method it may be helpful.
+ (void)postRequestData:(NSDictionary *)postVars
Action:(APIMode)action
WithCompletionHandlar:(void (^) (id result, BOOL status))completionBlock
{
NSURL *url = [NSURL URLWithString:API_URL([self getAPINameForType:action])];
NSLog(#"Request URL %#",[NSString stringWithFormat:#"%#",url]);
NSString *contentType = #"application/json";
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
[request addValue:contentType forHTTPHeaderField: #"Content-Type"];
NSError *err = nil;
NSMutableDictionary *params=[[NSMutableDictionary alloc] initWithDictionary:postVars];
// [params setObject:[self getAPINameForType:action] forKey:#"mode"];
NSLog(#"Paramater %#",params);
NSData *body = [NSJSONSerialization dataWithJSONObject:params options:NSJSONWritingPrettyPrinted error:&err];
[request setHTTPBody:body];
[request addValue:[NSString stringWithFormat:#"%lu", (unsigned long)body.length] forHTTPHeaderField: #"Content-Length"];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError)
{
if(!connectionError)
{
NSError *error = nil;
NSDictionary *dictResponse = [NSDictionary dictionaryWithDictionary:[NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingAllowFragments error:&error]];
dispatch_async(dispatch_get_main_queue(), ^{
completionBlock(dictResponse,(error == nil));
});
NSLog(#"%#",dictResponse);
}
else
{
dispatch_async(dispatch_get_main_queue(), ^{
completionBlock(connectionError.localizedDescription,NO);
});
}
}];
}
Use this method instead of it.It is executed fast because NSURLConnection Class execute in background.
Try to fetch your data using NSURLConnection class(manual code) or simply use AFNetworking class(less code). AFNetworking internally uses NSURLConnection class itself.

Send UIImage POST to server from UIImagePickerController?

I am trying to send a UIImage take with the UIImagePickerController to a server POST along with other pertinent values. But I get at the line that tries to set the dictionary value #"image" to UIImageJPEGRepresentation(image, 1.0):
-(void)sendImageToServer:(UIImage *)image
{
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = 4;
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration ephemeralSessionConfiguration] delegate:nil delegateQueue:queue];
NSURL *uploadURL = [NSURL URLWithString:#"http://...."];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:uploadURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:30.0];
[request addValue:#"application/json" forHTTPHeaderField:#"Accept"];
[request setHTTPMethod:#"POST"];
NSData *postData = [[NSData alloc] init];
[postData setValue:UIImageJPEGRepresentation(image, 1.0) forKey:#"image"];
[postData setValue:#"1" forKey:#"categories[0]"];
[postData setValue:#"4" forKey:#"categories[1]"];
NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request
fromData:postData
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (!error) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
if (httpResponse.statusCode == 200) {
dispatch_async(dispatch_get_main_queue(), ^{
NSError *err;
NSDictionary *JSONDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&err];
NSLog(#"HTTP 200 response: %#", JSONDict);
});
} else {
NSLog(#"HTTP %ld status!", (long)httpResponse.statusCode);
}
} else {
NSLog(#"HTTP post image error: %#", error);
}
}];
[uploadTask resume];
}
JSON serialization does not work here, because images are not valid JSON values. If on the other hand I try:
...
NSMutableData *postData = [[NSMutableData alloc] init];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:postData];
[archiver encodeObject:UIImageJPEGRepresentation(image, 1.0) forKey:#"image"];
[archiver encodeObject:#"1" forKey:#"categories[0]"];
[archiver encodeObject:#"4" forKey:#"categories[1]"];
[archiver finishEncoding];
//NSData *postData = [NSJSONSerialization dataWithJSONObject:dataDict options:NSJSONWritingPrettyPrinted error:&jsonError];
//Now you can post the json data
NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request
fromData:postData
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {...
The key:value pairs archived do not seem to get to the server as such. This must be a routinely iOS coding task.
Even if I just try:
NSError *jsonError;
NSData *postData = [NSJSONSerialization dataWithJSONObject:#{#"image":#"123",#"categories[0]":#"1",#"categories[1]":#"4"} options:NSJSONWritingPrettyPrinted error:&jsonError];
The server does not get any keys at all...
That's not the proper usage of NSData. It's crashing right now because NSData does not have key named image (..or the other two after that). What you need to do is create an NSDictionary and then convert that to NSData.
Do something like this instead:
NSDictionary *dictionary = [NSDictionary alloc]initWithObjectsAndKeys:image,#"image",#(1),#"categories[0]",#(4),#"categories[1]", nil];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:dictionary]; //Not currently using NSJSONSerialization since you want to post a Dictionary with an invalid NSJSONSerialization type in it.
//Now you can post the json data
Give a try with AFNetworking, it have a great way to make uploads, you can find the samples here: https://github.com/AFNetworking/AFNetworking#creating-an-upload-task
I personally recommend everyone to use it, since I started to use I didn't have any trouble to communicate my apps with webservers.
Use AFNetworking and the multi-part form post. Here is a rough example (note I am passing in a block so your implementation will vary):
AFHTTPRequestOperation *operation = [self POST:FullURLString parameters:Params constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFileData:fileData name:fileName fileName:fileName mimeType:mimeType];
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSData *responseData = [operation responseData];
id retObj;
NSError *error = nil;
if (responseData) {
retObj = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:&error];
}
// Pass back the serialized object (either an NSArray of type NSDictionaries or an NSArray of type customClass)
block(retObj);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Failed with error = [Error]: %#", error);
block(nil);
}];

Resources