app crashes because of null values, swift 2 - crash

I'm trying to get data using JSON ad there is a null value causes crash.
let jsonData:NSDictionary = try NSJSONSerialization.JSONObjectWithData(urlData!, options:NSJSONReadingOptions.MutableContainers ) as! NSDictionary
let success:NSInteger = jsonData.valueForKey("success") as! NSInteger
//code error bad instruction
NSLog("Success: %ld", success);
how can I turn null to zero?

let success = (jsonData["success"] as? NSInteger) ?? 0
step by step:
get the value jsonData["success"] (please, don't use valueForKey, it does something completely different)
as? NSInteger - try to cast it to NSInteger or return nil if it's not a number (in this case, it's a NSNull instance)
?? 0 - if nil, use a default value of zero

Related

Comparison between pointer and int (id to int) - Object wrapping still doesn't work [duplicate]

So my problem is this:
I am receiving a JSON string from across the network. When decoded (using SBJSON libraries), it becomes an NSDictionary that SHOULD contain a number of some sort for the key 'userid'. I say 'should' because when I compare the value to an int, or an NSINTEGER, or NSNumber, it never evaluates correctly.
Here is the comparison in code:
NSDictionary *userDictionary = [userInfo objectAtIndex:indexPath.row];
if ([userDictionary objectForKey:#"userid"] == -1) {
//Do stuff
}
The value inside the dictionary I am testing with is -1. When I print it out to console using NSLog it even shows it is -1. Yet when I compare it to -1 in the 'if' statement, it evaluates to false when it should be true. I've even tried comparing to [NSNumber numberWithInt: -1], and it still evaluates to false.
What am I doing wrong? Thanks in advance for your help!
You are comparing a pointer to an object, not an integer itself. You must first convert the object into an integer:
if ([[userDictionary objectForKey:#"userid"] integerValue] == -1)
{
//Do stuff
}

Detect if NSNumber is zero, nil or 0

I have a variable in core data. I want to detect for the cases where it is nil zero, null or otherwise does not have a nice value such as 222 or 333.
This should be trivial but I am getting caught up in Objective-C's syntax.
Following code is not working:
if (_item.id!=nil && _item.id!=0) {
//do something
}
Of note id should be an NSNumber.
It is defined as
#property (nonatomic, retain) NSNumber * id;
I should clarify that it is not working when the value logs to console as 0.
Given the way variable types and core data work, I cannot tell you what causes the variable to log to console as '0' but something is causing it to do so. Basically, I want to exclude cases where the value is anything other than a non-zero integer (in mathematical, not computer science terms).
To check the numeric value stored in an NSNumber, you have to call one of the methods which give you a primitive type.
e.g. integerValue, unsignedLongLongValue, doubleValue
To correctly check for nil and a value of 0, you need the following:
if (_item.id != nil && [_item.id intValue] != 0) {
// code here
}
Because sending a message to a nil reference returns 0, you can take a shortcut:
if ([_item.id intValue] != 0) ...
This works because _item.id has to be non-nil to return a non-zero value from intValue.
As this NSManagedObject is of type NSNumber, simply check the intValue.
if (!_item.id.intValue){
//Method will stop in here if the id is nil/0 etc.
}
However, it is not recommended to name a variable id, I suggest you rename it to itemId
In the same way you shouldn't name something 'string', or 'new' etc as these conflict with Apple's own native naming policies
To check the numeric value stored in an NSNumber, you have to call one of the methods which give you a primitive type.
e.g. integerValue, unsignedLongLongValue, doubleValue
To correctly check for nil and a value of 0, you need the following:
if (_item.id != nil && [_item.id intValue] != 0) {
// code here
}
Because sending a message to a nil reference returns 0, you can take a shortcut:
if ([_item.id intValue] != 0)

Convert Objective C to Swift

So i started learning swift directly and i'm trying to convert this objective C to swift but not sure exactly what it means, can someone explain it?
Side1 = ([[[ValueArray objectAtIndex:Counter-1] objectAtIndex:2] intValue] == 1)?-1:1;
where, Side = 0,ValueArray = [] and Counter = 0
Edit: Its in loop so counter++
Thanks
if ([[[ValueArray objectAtIndex:Counter-1] objectAtIndex:2] intValue] == 1) {
Side1 = -1
} else {
Side1 = 1
}
What is inside of ValueArray? Also, if Counter == 0 then getting objectAtIndex -1 will crash. But basically the swift version would be:
(ValueArray[Counter-1][2] as! NSString).intValue == 1
This makes a couple of assumptions, mainly that you're returning a String which we can force downcast to an NSString to take advantage of intValue.
This is shorthand for if-else. It can be used like so:
my_variable = (some_condition ? some_value : some_other_value)
This is equivalent to
if some_condition
my_variable = some_value
else
my_variable = some_other_value
It seems your code checks the integer value of an object in an array inside another array. It can be converted to Swift like so:
Side1 = (ValueArray[Counter - 1][2] as! Int == 1 ? -1 : 1)
As mentioned in a comment, this will crash if Counter is 0. I'm also assuming that ValueArray only contains objects that can be casted to Int. Swift is usually very picky about these things.
EDIT
If ValueArray contains strings, they can't be casted to Int. Cast to NSString first:
ValueArray[Counter - 1][2] as! NSString
and therefore the if shorthand becomes
Side1 = ((ValueArray[Counter - 1][2] as! NSString).intValue == 1 ? -1 : 1)
This does not always do the best job, but it can definitely help! It is a Objective-C to Swift converter.
Link https://objectivec2swift.com/#/converter/code

Does using compare on a nil NSNumber always return NSOrderedSame?

NSNumber *badNum = 0;
NSNumber *goodNum = #42;
if ([badNum compare:goodNum] == NSOrderedAscending)
// ...
Given the above snippet, where badNum is effectively nil, is the if statement guaranteed to never be entered?
Essentially, I want to know if I must do a nil check every time I use -[NSNumber compare:], so another question is will I need to use the following code to make sure compare always works as it appears?
if (badNum && goodNum && [badNum compare:goodNum] == NSOrderedAscending)
// ...
Yes, it is guaranteed, as long as Apple does not change NSOrderedSame, which is currently defined as zero:
enum {
NSOrderedAscending = -1,
NSOrderedSame, // == 0
NSOrderedDescending // == 1
};
The reason you appear to get NSOrderedSame when sending compare: message to nil is that Objective-C supplies the default value for the return type when the target is nil. Since NSOrderedSame is 0, the default value, you are guaranteed to get it when badNum is nil.

Objective-C: Result of casting id to BOOL?

Does the following function return YES if object != nil?
- (BOOL)boolForObject:(id)object {
return (BOOL)object;
}
I've tested with object = [[NSObject alloc] init] but got mixed results.
A pointer is larger than a BOOL, so when you cast it will truncate and take only the 8 least significant bits of the pointer and make it a BOOL. If those bits all happen to be zero then that is equivalent to NO.
So to answer your question, no it does not (well sometimes it will depending on the pointer value)
Here's an example with using Xcode 5.1.1 on 32 bit architecture:
void* p = (void*)0xfeeeff00;
BOOL b = (BOOL)p;
NSLog(#"p=%08x (%lu), b=%08x (%lu)", (uint32_t)p, sizeof p, (uint32_t)b, sizeof b);
It prints out:
p=feeeff00 (4), b=00000000 (1)
What is the actual purpose of your method?
If it's just to check whether an object is nil or not, why not do it like this:
- (BOOL)boolForObject:(id)object
{
return (object != nil);
}
It's more obvious what the result will be.
You could also do:
return !!object;
I don't think so, but
return object != nil;
will.