Setting NSMutableArray to NSDictionary - Objective C - ios

I have a NSMutableArray that is set based on selections the user makes. I am than trying to pass that to a NSDictionary that is set to my parameter to be sent to my server. I want to than grab those values placed inside the parameters.
Heres what I am doing:
NSMutableArray: is being set by the following: [_selectedCells addObject:label.text];
NSDictionary *dictionary = #{ #"title": _titlefor.text,
#"description": _description.text,
#"time_limit": _timeLimit.date, #"toWho": #""};
toWho is where I want to send the values the user selected.
I've tried something like,[dictionary setValue:self.viewControllers.selectedCells forKey:#"toWho"]; But this does not work correctly.
I think I will have to use a NSMutableDictionary but can I send this to parameters to be sent to my server?
Heres how I am adding parameters:
NSMutableURLRequest *request = [httpClient multipartFormRequestWithMethod:#"POST" path:#"downloadFileChallange.php" parameters:dictionary constructingBodyWithBlock:^(id <AFMultipartFormData>formData)
{
[formData appendPartWithFileData:webData name:#"file" fileName:newUsername mimeType:#"video/quicktime" ];
}];
Suggestions, thoughts?

Yes you can use a dictionary as the parameters of a HTTP request.
I would not give it a mutable dictionary however. Make a copy of it instead, so change the line to:
... parameters:dictionary.copy ...
Have a quick look at the documentation for copy, you'll see that making a "copy" of a mutable object always returns an immutable version of the object. So it will be an NSDictionary, which is what NSMutableURLRequest expects to receive.
The copy returned is immutable if the consideration “immutable vs. mutable” applies to the receiving object; otherwise the exact nature of the copy is determined by the class.

Related

NSMutableData to NSDictionary returning null

I'm writing a program that uses the Instagram API and I'm running into some issues with NSMutableData and NSDictionary.
Since I have to make multiple calls to the API, I decided to create a NSMutableData object, append smaller NSData objects to it and then turn the whole thing into an NSDictionary.
However, after I make a second call to NSMutableData appendData NSData, when I turn NSMutableData into an NSDictionary, the dictionary returns null.
Here's some of my code.
NSMutableData *userData = [[NSMutableData alloc]init]
NSData *feed = [NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:#"https://api.instagram.com/v1/users/17636367/media/recent?access_token=%#",accessToken]]];
[userData appendData:feed];
NSData *moarData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:#"https://api.instagram.com/v1/users/17636367/media/recent?access_token=%#&max_id=%#",accessToken, maxID]]];
[userData appendData:moarData];
NSDictionary *dictTwo = [NSJSONSerialization JSONObjectWithData:userData options:NSJSONReadingMutableContainers error:nil];
NSLog(#"%#",dictTwo);
dictTwo returns null. However, when I make only one call to appendData, the dictionary isn't empty.
Thanks.
When you append two separate JSON responses they will not form a JSON.
You can test the final result to see if it is JSON or not with the following link:
JSON validator
You need to parse each query response separately and then apply manipulation on that data: (Ex NSMutableDictionary, NSMutableArray etc).
The first call will return an array or dictionary. Assuming it is a dictionary you would get something like:
{"some":"data"}
This can be parsed correctly. When you make two calls you get:
{"some":"data"}{"other":"data"}
This is not valid JSON. You need to parse each item separately.

How to pass NSUInteger into NSDictionary

I am trying to send an integer into an NSDictionary as a parameter. For some reason, I am unable to send an NSString containing the value of the integer since a string can't be compared to an integer (this is in my other code). As a result, I am forced to send in (instead of an NSString) an NSUInteger or NSInteger into the NSDictionary.
This leads me to my problem, since an NS(U)Integer is NOT an object, and cannot be inserted into an NSDictionary. So, my code is as follows:
NSDictionary *parameters = #{#"index":indexPath.row]};
Now, my question is... how should I format this NS(U)Integer into an object?
The marked duplicate question DOES NOT answer my question in the way that I want.
There is one more way using objective c 2.0 style
NSDictionary *parameters = #{#"index":#(indexPath.row)]};
this will create object as NSNumber internally!
You can use NSNumber class for doing the same:
NSDictionary *parameters = #{#"index":[NSNumber numberWithUnsignedInteger:indexPath.row]};
Or in Modern Objective C:
NSDictionary *parameters = #{#"index":#(indexPath.row)};

Sending JSON object ios

I'm new to iOS and looking for a little help. I am connecting to my socket server but having trouble emitting.
Heres how to emit:
if (self.socketIsConnected)
{
[self.socket emit:(NSString HERE) args:#[(NSArray HERE)]];
}
Heres what I tried:
if (self.socketIsConnected)
{
NSDictionary *deviceDic = #{#"username": #"drew", #"chatHash":#"FJHE8"};
[self.socket emit:#"adduser" args:#[[NSString stringWithFormat: #"%#", deviceDic]]];
}
The "args" param asks for a NSArray, but I need to send a JSON object that looks like this:
{"username": "drew", "chatHash":"FJHE8"}
How can I create this? And how do I put this object in the NSArray.
Update:
I tried this now
NSArray *keys = [NSArray arrayWithObjects:#"username", #"chatHash", nil];
NSArray *objects = [NSArray arrayWithObjects:#"drew", #"value2", nil];
NSDictionary *dictionary = [NSDictionary dictionaryWithObjects:objects
forKeys:keys];
[self.socket emit:#"adduser" args:dictionary];
and I looked on the server. It crashes my server with a throw exception. and the only data it receives is:
username
It appears that you're using SIOSocket. The documentation isn't very clear but looking at the source for the emit function (https://github.com/MegaBits/SIOSocket/blob/master/SocketIO/Source/SIOSocket.m), all you need to do is pass an NSArray with the first parameter being an NSDictionary. The dictionary will be serialized as a JSON object by the framework.
You can have multiple arguments in the emit call. The type of each parameter in argument depends on the types of objects in the array you pass. If you pass a dictionary, it'll convert it to a JSON object, an array to an array, numbers as numbers, strings as strings.
You can use
NSDictionary *subArgs = #{#"state" : #true};
[self.socket emit:#"adduser" args:#[subArgs]];
This will solve the problem.

IOS Sort NSDictionary [duplicate]

This question already has answers here:
NSDictionary with ordered keys
(9 answers)
Closed 9 years ago.
to start, this is my code :
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL
URLWithString:url]];
NSData *response = [NSURLConnection sendSynchronousRequest:request
returningResponse:nil error:nil];
NSDictionary *publicTimeline = [NSJSONSerialization JSONObjectWithData:response options:0 error:&jsonParsingError];
for (NSObject* key in publicTimeline) {
id value = [publicTimeline objectForKey:key];
NSLog(#"%#", key);
}
I take few news on a webservice, and i show it in a tableView.
My problem is that these news aren't show in order.
In my webservice, the news are in order, for example i have :
{"0":{"title":"News1"}}
{"1":{"title":"News2"}}
{"2":{"title":"News3"}}
etc..
but in the loop, i "loose" this order :/ And i want to have my news in this order, first the news with the index "0" after "1" etc...
(the NSDictionary seems to loose this order, for example, after my code, i have in my tableview, the news : "2", "0", "1", and not my news "0", "1", "2". )
(i tried some answers, but none seems to work in my case :( )
SOmeone to help me ? thx,
This is what I used last time to sort the keys of my dictionary. Hope it will be easier for you to implement it :)
NSMutableArray *sortedArray = [NSMutableArray arrayWithArray:publicTimeline.allKeys];
[sortedArray sortUsingSelector:#selector(localizedStandardCompare:)];
And you should have your sorted keys in sortedArray
You can work with that :
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:publicTimeline];
[dict keysSortedByValueUsingComparator:^(id obj1, id obj2) {
return (NSComparisonResult)[obj1 compare:obj2];
}];
And then USE dict instead of publicTimeline.
Hope that will help.
Dictionaries don't have an order. Just because the server generates your JSON in a particular order doesn't mean that it is / can be maintained when you deserialise with NSJSONSerialization.
If you need to maintain the order, either:
A. Get all of the keys from the dictionary and sort them. Then, any time you need to access in order (by index), get the key from the array and use that (don't iterate the dictionary).
B. Use a different method to deserialise the JSON which can keep / provide data about the order in which things were processed (RestKit can do that for you).

AFNetworking - How to specify multiple values for one key

I am trying to pass multiple values for one parameter key to an HTTP request using the AFHTTPClient method "postPath". However, the parameters variable is an NSDictionary so I can not set multiple values for my key "email". I've tried sending the e-mail values as a comma separated string but that does not work as my server returns an error saying I have not specified any e-mail value.
I did read in the documentation about using multipartFormRequestWithMethod method but I could not completely figure out how to make this work. Can anyone provide an example of using this method with multiple values for a single key?
Thanks
Rich
Combining the multi query values for one key.
If you use NSDictionary + NSSet you get query url without [] from NSArray.
NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:
[NSSet setWithObjects:#"value1", #"value2", nil], #"myKey", nil];
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url];
NSURLRequest *request = [httpClient requestWithMethod:#"GET" path:#"/path" parameters:params];
PS: Better late than never...
Combining the multi values for the one key.
using NSDictionary + NSArray
For example:
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url];
NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys: #"value1", #"param1", #"value2", #"param2", [NSArray arrayWithObjects:#"value3",#"value4",#"value5",nil], #"param3", nil];
NSMutableURLRequest *request = [httpClient requestWithMethod:#"POST" path:#"/yourhostpath" parameters:params];
you need to replace "url" and "yourhostpath" to your own, please reference AFHttpClient demo code of AFNetworking for this.
You cannot define multiple values for a single key. However, you can define a key to have an array, which itself contains multiple values.
That said, it doesn't seem like email would be a field that should have multiple definitions. If you do want to accept multiple values, you should probably rename that parameter to emails.

Resources