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)};
Related
Dict is coming from notification, taking out the NSData from dict and adding it to NSMutableArray is crashing the application.
Once in a while this crash is happening not always.
NSData *data=[dict objectForKey:#"obj"];
[self.RFTagData addObject:data];
You can directly add data object by doing this.Instead of converting to string.
Don't type cast NSData to NSString when adding objects into array.You should first convert NSData into NSString then add it to array.So
better way to use this NSData into NSString and add NSString into array.
NSData *data=[dict objectForKey:#"obj"];
NSString *strData = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
if(data != nil self.RFTagData != nil)
{
[self.RFTagData addObject:strData];
.....
}
Example for Converting Data into String
You can directly get the data to array there is no need to cast.
if(self.RFTagData != nil){
self.RFTagData = [dict objectForKey:#"obj"];
}
NSLog(#"array %#", RFTagData);
This will add all data to array under the obj key.
Update:
As user rmaddy & danh suggested, so here needs to take concern over this point regarding use of valueForKey and objectForKey methods and nil check on the array.
objectForKey: This is an NSDictionary method. An NSDictionary is a collection class similar to an NSArray (collections), except instead of using indexes like NSArray, it uses keys to differentiate between items. A key is an arbitrary string you provide. No two objects can have the same key (just as no two objects in an NSArray can have the same index).
valueForKey: This is a KVC method. It works with ANY class. valueForKey: allows you to access a property using a string for its name.
Here both returns the value associated with a given key, so here using valueForKey method provides workaround solution to you. But using objectForKey is the more preferred way to use in such cases.
To check for the null values inside array which are identically appears like literals #"<null>" rather then NSNull objects typically used to represent nils in Cocoa collections. You can filter them out by using NSArray's filteredArrayUsingPredicate method:
NSPredicate *pred = [NSPredicate predicateWithBlock:^BOOL(id value, NSDictionary *unused) {
return ![str isEqualToString:#"<null>"];
}];
NSArray *filteredAry = [self.RFTagData filteredArrayUsingPredicate:pred];
NSLog(#"array with non null vals %#", filteredAry);
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.
I have NSString representation of NSDictionary
I created the string like that:
NSString * insertionStr = [dictionary description];
Now I want to convert it back to NSDictionary
Is it possible ?
To save a dictionary to a file (or other medium) and be able to restore it later, you should use either JSON or the plist format.
For JSON your data must be limited to a combination of dictionaries, arrays, strings, and NSNumbers. For a plist it must be one of those or NSDate, or NSData.
For JSON you'd use the methods of NSJSONSerialization to convert to NSData, then save the data to a file. To restore, load the file into NSData and run back through NSJSONSerialization.
For plist format use the NSDictionary writeToFile and dictionaryWithContentsOfFile methods.
Do note that by default the objects you get back are immutable. If you want mutable objects from JSON there is an option on JSONObjectWithData called NSJSONReadingMutableContainers. With plists I believe you need to use the more complex plist interfaces (vs using the simple NSDictionary interfaces) that allow you to specify a similar option.
From the NSUserDefaults documentation for setObject:forKey
The value parameter can be only property list objects: NSData, NSString, NSNumber, NSDate, NSArray, or NSDictionary. For NSArray and NSDictionary objects, their contents must be property list objects.
If your dictionary contains contains non-property list objects you can archive and store it to file if all objects in the dictionary implement NSCoding.
Based on the Question and comments i will say ...NO ...Don't do it like that.
NSUserDefaults has the capability to store object values and its perfectly fine to store NSDictionary
[[NSUserDefaults standardUserDefaults] setObject: dictionary forKey:#"DetailDict"];
[[NSUserDefaults standardUserDefaults] synchronize];
and retrive it use
NSDictionary *retrievedDictionary = [[NSUserDefaults standardUserDefaults] dictionaryForKey:#"DetailDict"];
OR
If you think you think of saving it as a string have a look at this question and when retrieving the value just convert back the string to Object
A dictionary is represented as key/value pairs. You can create a dictionary with a single value like this:
NSDictionary *dictionary = #{#"name": #"Mike"};
You can also store multiple key/value pairs:
NSDictionary *newDictionary = #{
#"firstName": #"Mike",
#"lastName": #"Smith"
};
Later if you want to get the value back out of the dictionary you use the key to get the value back out of it:
NSString *first = newDictionary[#"firstName"];
NSString *last = newDictionary[#"lastName"];
// first will now be #"Mike" and last will be #"Smith"
Think of a dictionary like an array, but instead of using indexes (numbers) to reference the value you use keys (strings).
Based on a comment made, if you also want to store an array of dictionaries you can do that no problem like this:
NSDictionary *firstDictionary = #{#"key": #"value"};
NSDictionary *secondDictionary = #{#"anotherKey": #"anotherValue"};
NSArray *array = #[firstDictionary, secondDictionary];
I call an URL that returns me JSON (I use JSONKit). I convert it to a NSString that is this way:
[{"name":"aaaaaa","id":41},{"name":"as","id":23},...
And so on. I want to fill an UIPickerView with only the "name" part of the JSON. But, when the user selects a name, i need the "id" parameter, so i've thought to fill a NSDictionary with the JSON (setValue:id for key:name), so i can get the value picked by the user, and get the id from the dictionary. how could I fill an array with only the "name" of the JSON?
Im a bit lost with the JSONKit library, any guidance? Thank you.
First of all I don't think that its a good idea to have name as key in a dictionary, since you can have many identical names. I would go for id as key.
Now, what you could do is:
NSString *myJson; //Suppose that this is the json you have fetched from the url
id jsonObject = [myJson objectFromJSONString];
// Now you have an array of dictionaries
// each one having 2 key/value pairs (name/id)
NSArray *names = [jsonObject valueForKeyPath:#"name"];
NSArray *ids = [jsonObject valueForKeyPath:#"id"];
// Now you have two parallel arrays with names / ids
Or you could just iterate your json object and handle the data yourself:
for (id obj in jsonObject)
{
NSString *name = [obj valueForKey:#"name"];
NSNumber *id = [obj valueForKey:#"id"];
// Do whatever you like with these
}
I am trying to utilize incase-sensitive case for JSON response on NSDictionary as sometimes my response keys type varies, some are camel case, some are lowercase or other mixed combination. Is there any built in functionality to check for in-sensitivity case for this case?
Thanks.
Lately I've shared two classes that might suit your needs. They provide case-insensitive operations (named after NSDictionary and NSMutableDictionary methods) while keeping the originally inserted keys.
Give it a try:
https://github.com/keeshux/ios-components/tree/master/Components/Utils/KSCIDictionary
The best way would be to set the key for the NSDictionary to be either all lowercase or all uppercase;
For example lets say I have a NSArray of strings. I could get the keyName before I use it and convert it by using the lowercaseString or the uppercaseString
NSString *itemName = #"lastName";
itemName = [itemName lowercaseString];
this will change the string to lastname or if I used uppercaseString it would be LASTNAME
or you can also change the key name when adding to dictionary like so:
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setObject:objectToAdd forKey:[key uppercaseString]];
- (NSString *)lowercaseString
It's a default NSString method, just do [key lowercaseString] when adding to, or reading from the NSMutableDictionary.
In my case, I didn't need all of the Dictionary methods or properties. I just needed case-insensitive subscript access. I made a custom class (not a superclass of NSMutableDictionary) and implemented the methods to allow subscripted access and made those case insensitive:
- (id) objectForKeyedSubscript: (NSString *) key {
NSMutableDictionary *theData = self->data;
return theData[[key lowercaseString]];
}
- (void) setObject: (id) newValue forKeyedSubscript: (NSString *) key {
NSMutableDictionary *theData = self->data;
theData[[key lowercaseString]] = newValue;
}
See also:
http://clang.llvm.org/docs/ObjectiveCLiterals.html