convert NSDictionary's key into an NSNumber - objective-c

How can i convert the key to an NSNumber? this code gives me the error:
no matter how i try it, i always end up with the error: Incompatible integer to pointer conversion assigning to 'NSNumber' from 'NSIntegar' (aka 'int').
for (id key in consultants)
{
consultantData = [[ConsultantData alloc] init];
consultantData.name = [consultants objectForKey:key];
consultantData.conID = [[NSNumber numberWithInteger:key] integerValue];
NSLog(#"name: %# ID: %#", consultantData.name, consultantData.conID);
[consultantList addObject:consultantData];
[consultantData release];
}
here is my object ConsultantData:
#import <Foundation/Foundation.h>
#interface ConsultantData : NSObject
{
NSString *name;
NSNumber *conID;
}
#property (nonatomic, retain) NSString *name;
#property (nonatomic, retain) NSNumber *conID;
#end
#import "ConsultantData.h"
#implementation ConsultantData
#synthesize name;
#synthesize conID;
-(void) dealloc
{
[name release];
[conID release];
[super dealloc];
}
#end
if i try isMemberOfClass, it never returns true. if i try isKindOfClass, it tells me its a NSString.
consultants is a dictionary i receive from my sever that passes thru an XMLRPC function (server is PHP). from what i've seen, everything is a string in the server dictionary returns.

could be that you have the order wrong.
consultantData.conID = [[NSNumber numberWithInteger:key] integerValue];
means
NSNumber *foo = [NSNumber numberWithInteger:key];
NSInteger bar = [foo integerValue];
consultantData.conID = bar;
you probably want
consultantData.conID = [NSNumber numberWithInteger:[key integerValue]];
which is in verbose form:
NSInteger foo = [key integerValue];
NSNumber *bar = [NSNumber numberWithInteger:foo];
consultantData.conID = bar;

consultantData.conID = [[NSNumber numberWithInteger:key] integerValue];
The above line should be:
consultantData.conID = [NSNumber numberWithInteger:[key integerValue]];

Assuming your key is an NSString, you can't pass the key to [NSNumber numberWithInteger:key] because it is not an integer! Use the intValue method on the key to get an integer, then convert the integer to a NSNumber like so:
consultantData.conID = [NSNumber numberWithInteger:[key intValue]];

integerValue returns an NSInteger, which is not an NSNumber. You should pass the NSNumber directly:
consultantData.conID = [NSNumber numberWithInteger:[key integerValue]];

Related

objective-c. How to work with immutable Dictionary and return a copy?

I'm new in objective-c
The idea is that I'm passing a Dictionary to a method that return an altered Dictionary back.
I have a human "breath" method that expects as argument "air" Dictionary and returns another "air" dictionary.
test
-(void)testBreathIsConsumingTheRightAmountOfOxygen {
NSDictionary *oldAir = [[Environment alloc] init].air;
NSDictionary *newAir = [self.hummy breath:oldAir];
XCTAssertEqual([[newAir valueForKey:#"O2"] intValue], 995);
}
-(void)testBreathIsProducingTheRightAmountOfDioxide {
NSDictionary *oldAir = [[Environment alloc] init].air;
NSDictionary *newAir = [self.hummy breath:oldAir];
XCTAssertEqual([[newAir valueForKey:#"CO2"] intValue], 5);
}
code (my pour solution, I don't like it)
- (NSDictionary *) breath: (NSDictionary *) air {
int breathingStep = 5;
int oxygenOut = [[air valueForKey:#"O2"] intValue] - breathingStep;
int dyoxideOut = [[air valueForKey:#"CO2"] intValue] + breathingStep;
NSMutableDictionary *newAir = [NSMutableDictionary dictionaryWithDictionary:air];
[newAir setValue:[NSNumber numberWithInt:oxygenOut] forKey:#"O2"];
[newAir setValue:[NSNumber numberWithInt:dyoxideOut] forKey:#"CO2"];
return [NSDictionary dictionaryWithDictionary: newAir];
}
The *air Dictionary looks like this
[NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithInt:1000], #"O2", [NSNumber numberWithInt:0], #"CO2", nil ]
As a side note you should really be using the modern Objective-C syntax when dealing with NSDictionary and NSNumber.
I think you're looking for the mutableCopy method which returns a mutable version of the current dictionary.
- (NSDictionary *)breath:(NSDictionary *)air {
int breathingStep = 5;
NSMutableDictionary *newAir = [air mutableCopy];
newAir[#"O2"] = #([air[#"O2"] intValue] - breathingStep);
newAir[#"CO2"] = #([air[#"CO2"] intValue] + breathingStep);
return [NSDictionary dictionaryWithDictionary:newAir];
}
To make this better the keys (O2 and CO2) should be constant, for example:
NSString *const kBreathO2Key = #"O2";
NSString *const kBreathCO2Key = #"CO2";
Usage would be:
newAir[kBreathO2Key] = #([air[kBreathO2Key] intValue] - breathingStep);
To make this even better again it may be more appropriate to create a class to hold these values rather than a dictionary. Then you wouldn't need to convert between NSNumber and int.
#interface ASAir : NSObject
#property (nonatomic, assign) NSInteger O2;
#property (nonatomic, assign) NSInteger CO2;
#end
#implementation
#end
Then the breath: method could be improved as follows:
- (ASAir *)breath:(ASAir *)air {
int breathingStep = 5;
ASAir *newAir = [[ASAir alloc] init];
newAir.O2 = air.O2 - breathingStep;
newAir.CO2 = air.CO2 + breathingStep;
return newAir;
}

Default list in Objective C?

I want to store data at run time, I can have a linked list and add at runtime, however as I am new to IOS and objective C, do we have any default list in which we can add our datas, (Datas are two stings and an integer).
Cocoa provides NSArray and NSMutableArray, a pair of ordered containers similar to Java's ArrayList and C#'s List. You can add values to NSMutableArray, and it will grow as you add more elements; NSArray is read-only.
You can use .plist files to store your data.
Read more 'Loading data from .plist files', 'How to use plist in iphone?' or google it like 'load data from .plist'. However you can create NSArray or something like this at run time. If you want dive deeper you must read ObjC Collections Programming Topics
Make a class for your data with default properties and make sure it inherits NSObject then use NSMUtableArray to add/remove elements to the list.
// in the .h file of your object
#interface MyObject : NSObject {
NSString* strAttribute1;
// add more attributes as you want
}
#property (nonatomic, retain) NSString* strAttribute1;
#end
// then in the .m file
// do not forget the #import ""
#implement MyObject
#synthesize strAttribute1;
// override the dealloc to release the retained objects
#end
then in your code where you want to make a list of this object
NSMutableArray* myArray = [[NSMutableArray alloc] init];
// add elements and iterate through them
// do not forgot to free the memory if you are not using ARC
[myArray release];
You can use NSArray or NSMutableArray or NSDictionary or NSMutableDictionary depending on your needs.
NSArray:
NSArray *myArray;
NSDate *aDate = [NSDate distantFuture];
NSValue *aValue = [NSNumber numberWithInt:5];
NSString *aString = #"a string";
myArray = [NSArray arrayWithObjects:aDate, aValue, aString, nil];
NSMutableArray:
NSMutableArray *myArray = [[NSMutableArray alloc] init];
NSDate *aDate = [NSDate distantFuture];
NSValue *aValue = [NSNumber numberWithInt:5];
NSString *aString = #"a string";
[myArray addObject:aDate];
[myArray addObject:aValue];
[myArray addObject:aString];
NSDictionary:
NSDictionary * myDict = [NSDictionary dictionaryWithObjects:aDate, aValue, aString forKeys:firstDate, firstValue, firstString];
NSMutableDictionary:
NSString *aString = #"a string";
NSDate *aDate = [NSDate distantFuture];
NSValue *aValue = [NSNumber numberWithInt:5];
myDict = [[NSMutableDictionary alloc] init];
[myDict setObject:aString forKey:firstString];
[myDict setObject:aDate forKey:firstDate];
[myDict setObject:aValue forKey:firstValue];

Can't release object

I can't release this object and I don't know why:
SchedVO *tmpSched;
tmpSched = [SchedVO alloc];
NSString *timeStr;
timeStr = [[node attributeForName:#"timestamp"] stringValue];
tmpSched.date = [NSDate dateWithTimeIntervalSince1970:timeStr.intValue];
tmpSched.uid = [node stringValue];
[playListArr addObject:tmpSched];
[tmpSched release];
sched:
#interface SchedVO : NSObject
{
NSDate *date;
NSString *uid;
}
#property (nonatomic,retain) NSDate *date;
#property (nonatomic,retain) NSString *uid;
#end
I think its somehow the nsdate part. Can someone help me out?
I believe you're missing an init. tmpSched = [[SchedVO alloc] init]; Init increments the Retain count to 1. You can't release something that hasn't been initialized.

Get an integer from a plist for Objective-C iPhone dev

I have the following DataAll.plist:
<array>
<dict>
<key>ID</key>
<integer>1</integer>
<key>Name</key>
<string>Inigo Montoya</string>
</dict>
....
</array>
I want to get the ID value from it. My code gets the Name correctly, but the ID is a weird value. Here's what I'm doing:
NSBundle *bundle = [NSBundle mainBundle];
NSString *plistPath = [bundle pathForResource:#"DataAll" ofType:#"plist"];
NSArray *array = [[NSArray alloc] initWithContentsOfFile:plistPath];
self.allData = array;
[array release];
NSDictionary *first = [[NSDictionary alloc]
initWithDictionary:[self.allData objectAtIndex:0]];
Data *firstData = [[Data alloc] init];
[firstData setData:first];
labelName.text = [firstData EXName];
labelID.text = [NSString stringWithFormat:#"%d",[[firstData EXID]];
[firstData release];
Here's my Data.h
#interface Data : NSObject {
NSNumber *EXID;
NSString *EXName;
}
#property (readwrite, retain) NSNumber *EXID;
#property (nonatomic, retain) NSString *EXName;
And Data.m
#implementation Data
#synthesize EXID;
#synthesize EXName;
- (void) setData: (NSDictionary *) dictionary {
self.EXName = [dictionary objectForKey:#"Name"];
NSNumber *ID = [dictionary objectForKey:#"ID"];
self.EXID = ID;
}
Many thanks in advance! This is my first post, so I apologize if formatting isn't correct.
The problem is in
[NSString stringWithFormat:#"%d",[[firstData EXID]];
EXID is an NSNumber* object and not an int so %d isn't what you want. You need to either replace %d with %# or unwrap the integer from the NSNumber by calling [EXID integerValue] or [EXID intValue]. Which return NSInteger and int respectively.
Just because your data is in the plist as an integer doesn't mean it is retrieved as one. At least not when you retrieve with [dict objectForKey:]. Furthermore, NSNumber and integer are not the same data type.
My guess is the latter is throwing you off. That is to say the implicit conversion to NSNumber. Add the following before you call setData and update your OP with the output.
NSLog(#"plist entry: %#", first);

How to convert NSNumber to NSString

So I have an NSArray "myArray" with NSNumbers and NSStrings. I need them in another UIView so i go like this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
DetailViewController *details = [[DetailViewController alloc] initWithNibName:#"DetailView" bundle:nil];
details.subjectText = [[myArray objectAtIndex:indexPath.row] objectForKey:#"subject"];
The subjectText works.
But how can I get the NSNumbers out of it? (I actually need them as strings...)
I would convert a NSString out of a NSNumber like this:
NSString *blah = [NSNumber intValue]. But I don't know how to set it up in the code above...
Try:
NSString *myString = [NSNumber stringValue];
You can do it with:
NSNumber *myNumber = #15;
NSString *myNumberInString = [myNumber stringValue];
//An example of implementation :
// we set the score of one player to a value
[Game getCurrent].scorePlayer1 = [NSNumber numberWithInteger:1];
// We copy the value in a NSNumber
NSNumber *aNumber = [Game getCurrent].scorePlayer1;
// Conversion of the NSNumber aNumber to a String with stringValue
NSString *StringScorePlayer1 = [aNumber stringValue];
or try NSString *string = [NSString stringWithFormat:#"%d", [NSNumber intValue], nil];
The funny thing is that NSNumber converts to string automatically if it becomes a part of a string. I don't think it is documented.
Try these:
NSLog(#"My integer NSNumber:%#",[NSNumber numberWithInt:184]);
NSLog(#"My float NSNumber:%#",[NSNumber numberWithFloat:12.23f]);
NSLog(#"My bool(YES) NSNumber:%#",[NSNumber numberWithBool:YES]);
NSLog(#"My bool(NO) NSNumber:%#",[NSNumber numberWithBool:NO]);
NSString *myStringWithNumbers = [NSString stringWithFormat:#"Int:%#, Float:%# Bool:%#",[NSNumber numberWithInt:132],[NSNumber numberWithFloat:-4.823f],[NSNumber numberWithBool:YES]];
NSLog(#"%#",myStringWithNumbers);
It will print:
My integer NSNumber:184
My float NSNumber:12.23
My bool(YES) NSNumber:1
My bool(NO) NSNumber:0
Int:132, Float:-4.823 Bool:1
Works on both Mac and iOS
This one does not work:
NSString *myNSNumber2 = [NSNumber numberWithFloat:-34512.23f];
In Swift you can do like this
let number : NSNumber = 95
let str : String = number.stringValue
In Swift 3.0
let number:NSNumber = 25
let strValue = String(describing: number as NSNumber)
print("As String => \(strValue)")
We can get the number value in String.