Trying to remove a decimal from NSString - objective-c

This is bizarre.
Developing for the iPhone I have an NSString:
distanceFromTargetString = #"6178266.000000"
// this is not actually code, but a value taken from elsewhere. It is a proper NSString though.
When I use this
NSArray *listItems = [distanceFromTargetString componentsSeparatedByString:#"."];
distanceFromTargetString = [listItems objectAtIndex:0];
or this
[distanceFromTarget setText: distanceFromTargetString];
I get something like this
-[NSDecimalNumber isEqualToString:]: unrecognized selector sent to instance 0x1cac40
2011-07-21 14:29:24.226 AssassinBeta[7230:707] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSDecimalNumber isEqualToString:]: unrecognized selector sent to instance 0x1cac40'
Any ideas?

At some point you are assigning an NSDecimalNumber to distanceFromTargetString rather than an NSString. There is no run-time type checking of assignments in Objective C, so this is totally "legal":
NSDecimalNumber *number = [NSDecimalNumber ....];
[array addObject:number];
NSString *string = [array lastObject];
The above will generate no errors or warnings until you try to send NSString methods to string, at which point you will get an exception (crash) like you show above.
Do an audit of everywhere you assign distanceFromTargetString, and everywhere you use NSDecimalNumber. Somewhere you're crossing the streams.

You could try :
NSInteger i = [distanceFromTargetString integerValue];
NSString s = [NSString stringWithFormat:#"%d", i];
// you got your string

You are somewhere calling isEqualToString with a NSDecimalNumber as the receiver. What is distanceFromTarget? Is this an NSDecimalNumber?
The first thing should work.

You could try to set a breakpoint at the line
[distanceFromTarget setText: distanceFromTargetString];
and see if distanceFromTargetString is actually an NSString.
As mentioned above, somehow an NSNumber has sneaked in somewhere.

Related

Converting __block NSString to NSString (and eventually to std::string)

+(std::string)somefunc{
__block NSString *vals = nil;
[[Something somecall] completion:^(some params){vals=#"yay"}];
return std::string([vals UTF8String]);
}
This function call throws an error "-[__NSMallocBlock__ UTF8String]: unrecognized selector sent to instance 0x------"
Based on the way I've converted NSStrings in the past, I'm assuming this is something to do with my need to declare the NSString as a __block to modify it inside the []. But I could not find an answer anywhere.
What is the "best" way to convert it?

How to set the value of UILabel in iphone?

I'm doing this to set the value in UILabel:
NSMutableDictionary *responseDict = [responseString objectFromJSONString];
self.pkrLbl.text= [responseDict objectForKey:#"amount"];
and I'm getting this error:
[__NSCFNumber isEqualToString:]: unrecognized selector sent to instance 0x9440310
2013-05-16 15:23:34.281 EasyLoadPakistan[20341:19a03] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFNumber isEqualToString:]: unrecognized selector sent to instance 0x9440310'
Please help me how can I set value in UIlabel
A UILabel expects a string (specifically NSString or one of its subclasses), and you are passing it a number (an NSNumber instance).
Convert the number to a string first, then set the label to that string:
NSNumber *n = [responseDict objectForKey:#"amount"];
NSString *stringVersion = [n stringValue];
self.pkrLbl.text = stringVersion;
If you prefer to have it all on one line, you can omit the variables and just chain the stringValue call. The approach shown above tends to facilitate debugging, though (you can for instance set a breakpoint and have a look at your variables).

NSDictionary objectForKey throws Exception NSCFString

This is my code:
NSError *error = nil;
SBJsonParser *parserJson = [[SBJsonParser alloc] init];
NSDictionary *jsonObject = [parserJson objectWithString:webServiceResponse error:&error];
[parserJson release], parserJson = nil;
//Test to see if response is different from nil, if is so the parsing is ok
if(jsonObject != nil){
//Get user object
NSDictionary *userJson = [jsonObject objectForKey:#"LoginPOST2Result"];
if(userJson != nil){
self.utente = [[User alloc] init];
self.utente.userId = [userJson objectForKey:#"ID"];
}
While Json string webServiceResponse is:
{"LoginPOST2Result":
"{\"ID\":1,
\"Username\":\"Pippo\",
\"Password\":\"Pippo\",
\"Cognome\":\"Cognome1\",
\"Nome\":\"Nome1\",
\"Telefono\":\"012345678\",
\"Email\":null,
\"BackOffice\":true,
\"BordoMacchina\":false,
\"Annullato\":false,
\"Badge\":1234}"
}
The problem arise when is execute this line:
self.utente.userId = (NSInteger *) [userJson objectForKey:#"ID"];
and the error is:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSCFString objectForKey:]: unrecognized selector sent to instance 0x6861520'
The error seems to be due to the fact that the object userJson is not an NSDictionary but rather NSCFString type and therefore does not respond to the message objectForKey:.
Where am I doing wrong?
The problem is that whilst the value in the json response for the key "LoginPOST2Result" looks like a dictionary, it is actually a string as it is enclosed in quotes.
So you are sending the objectForKey: message to an NSString and not an NSDictionary. NSString does not respond to objectForKey:.
It looks like the webServiceResponse is being generated incorrectly or parsed incorrectly.
You need to better understand what is a pointer and what no in the Cocoa Framework.
Infact you are defining userJson to NSDictionary and not NSDictionary *. Consider that all objects in Cocoa are pointers. Infact check that [NSDictionary objectForKey:] returns an "id" and then you must use NSDictionary *. Using simply NSDictionary you will refer to the class.
Similar mistake is done later in the cast to (NSInteger *) but NSInteger (NSInteger is not an object, it's a basic type hesitated from long or int (depends on the platform architecture) as you can see from its definition:
#if __LP64__ || TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64
typedef long NSInteger;
#else
typedef int NSInteger;
#endif
And also it seems from the object definition above that the key you are trying to get is dumped as a string and you are trying to fetch a dictionary. Please check the original json which probably is not in the format you expect.
So at the end you have at least 3 errors that will make your app crash.

Why am I getting this: _cfurl: unrecognized selector

My init starts like this:
- (id) init {
[super init];
sounds = makeDictFromArrayOfURLs(getNoiseFileURLs());
[sounds retain];
NSURL *theFirstNoise = [[sounds allKeys] objectAtIndex:0];
CFURLRef uref = (CFURLRef)theFirstNoise;
OSStatus ret = AudioServicesCreateSystemSoundID(uref, &chosenNoise);
When we get to that last line, it throws this:
2011-06-09 23:19:18.744 SuperTimer[94516:207] -[NSPathStore2 _cfurl]: unrecognized selector sent to instance 0x940cfb0
2011-06-09 23:19:18.746 SuperTimer[94516:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSPathStore2 _cfurl]: unrecognized selector sent to instance 0x940cfb0'
Yeah, it's a bit uncompact for debugging.
Just before I get the dump, theFirstNoise contains the expected (sort of) data. (It's description method prints a weird form, but I am informed that's normal.)
Off the top of my head, it looks like theFirstNoise is actually an NSPathStore2 (a private subclass of NSString) instead of an NSURL.
Edit: NSPathStore2 objects will contain file paths. If you need to turn these into NSURLs, you can simply pass them to +[NSURL fileURLWithPath:].
This line:
NSURL *theFirstNoise = [[sounds allKeys] objectAtIndex:0];
is the problem: [sounds allKeys] returns an NSArray of keys, and objectAtIndex: therefore is returning an NSString, and not the URL. I wish the compiler would have been a little more helpful.

Terminating the app due to uncaught exception in Objective-C for iPhone app

i've written a for loop in Objective-C, This is how my code looks like
NSString *string = [NSString stringWithContentsOfFile=#"/Users/Home/myFile.doc"];
NSString *seperator=#"\n";
NSArray *mainarray = [string componentsSeparatedByString:seperator];
// Since i want to parse each element of mainarray
for(NSString *s in mainarray)
{
//again parising the string using a new separator
NSString newseparator = #"=";
NSArray *subarray = [s componentsSeparatedByString : newseparator];
//Copying the elements of array into key and object string variables
NSString *key = [subarray objectAtIndex:0];
NSLog(#"%#",key);
NSString *class_name= [subarray objectAtIndex:1];
NSLog(#"%#",class_name);
// create an instance for the class_name
//dont knw how it ll take the value from file and ???
//Putting the key and objects values into hashtable
NSMutableDictionary = [NSDictionary dictinaryWithObject:class_name forKey:key];
}
Whenever i execute this code this crashes my program saying as, Terminating the app due to uncaught exception NSRangeException
How to know the range of array and how to specify the terminating condition in the for loop???and plz let me knw how to handle this exception???
I'm surprised that code even compiles. If I remember correctly, it can't compile unless you have gone to great lengths to turn off a whole bunch of compiler warnings.
NSString newseparator = #";";
That should give an error write there in that you don't have the *.
NSString *key = [subarray objectAtIndex[0]];
NSString *object = [subarray objectAtIndex[1]];
Neither of these lines of code make any sense.
It would appear that you haven't posted the actual code?
Now, getting back to the exception. A range exception will be tossed if you try to access an item at an index that is outside of the range of indexes available in the array. Thus, if componentsSeparatedByString: returned an array of 0 or 1 elements, then [subarray objectAtIndex: 1]; will cause a range exception to be raised.
What you don't want to do is to try and handle the exception using an #catch block. In Cocoa (and iPhone development), exceptions are treated as non-recoverable errors.
So, instead, use the -count method on NSArray to verify that the array actually contains the # of elements you were expecting. Since you are writing a casual parser, this is probably a good idea as a minimal check of input validity.