What's wrong with this method? - iphone

I'm getting a warning: "Return makes pointer from integer without a cast" for this method...
+(BOOL *)getBoolFromString:(NSString *)boolStr
{
if(boolStr == #"true" || boolStr == #"1"){
return YES;
}
return NO;
}

BOOL is not a class or object, so returning a pointer to a BOOL is not the same as returning a BOOL.
You should remove the * in +(BOOL *) and everything will be ok.

Besides what #Jasarien and #jlehr have said, you have a problem with this:
(boolStr == #"true" || boolStr == #"1")
That's doing pointer comparison, not object equality. You want:
([boolStr isEqualToString:#"true"] || [boolStr isEqualToString:#"1"])

To get a BOOL from an NSString, all you need to do is send a -boolValue message, like so:
NSString *myString = #"true"; // or #"YES", etc.
BOOL bool = [myString boolValue];

Related

Condition always fails though the comparative values seems correct in iOS

When I check the value of number in nslog it shows '0'
NSMutableDictionary *data = [[NSMutableDictionary alloc] initWithContentsOfFile: path];
NSNumber *number=[data objectForKey:#"serial"];
NSLog(#"%#",number);
if(number ==0 )
{
imgButton.hidden=YES;
}
But the condition always fails , I also changed the code like this
NSString *number=[data objectForKey:#"serial"]
NSLog(#"%#",number);
if(number == #"0" )
{
imgButton.hidden=YES;
}
But here too the condition fail ,What is the issue with this?
In the first code you are checking a NSNumber, object, against an int.
The correct check is:
if([number intValue] == 0) {
imgButton.hidden = YES;
}
In the second code you are checking two NSString, but you have to use the "isEqualToString" method and not "==". The correct code is:
if([number isEqualToString:#"0"]) {
imgButton.hidden = YES;
}
NSNumber is an object, 0 is an integer (a primitive type). They will never be equal. But you can change the comparison like this [number intValue] == 0 and this will work when the value of your NSNumber is 0.
On the string comparison, you should use the method
isEqualToString:NSString *)string
for the comparison.
For NSNumbers its
isEqualToNumber:(NSNumber *)number
Because otherwise you arent comparing if they have the same value, but if they are stored in identical memory space.

String isNullOrEmpty as a category

I'm trying to create a method which checks for a null/nil/empty string, and I'm trying to get it working as a category but having no luck.
I'm using this code, based on answers in this topic:
#implementation NSString (NSStringExtension)
- (BOOL)isNullOrEmpty {
return self == nil ||
self == (id)[NSNull null] ||
[#"" isEqualToString:self] ||
[[self stringByReplacingOccurrencesOfString:#" " withString:#""] length] == 0||
[self isEqualToString:#"(null)"]
|| ([self respondsToSelector:#selector(length)] && [(NSData *) self length] == 0)
|| ([self respondsToSelector:#selector(count)] && [(NSArray *) self count] == 0)
|| [[self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] == 0;
}
#end
Yet when I try to use this this is what I get:
NSLog([#"" isNullOrEmpty] ? #"1":#"0"); // prints 1
NSString *s1 = nil;
NSLog([s1 isNullOrEmpty] ? #"1":#"0"); // prints 0
NSLog([args.itemName isNullOrEmpty] ? #"1":#"0"); // prints 0
NSLog([(NSString*)nil isNullOrEmpty] ? #"1":#"0"); // prints 0
This is baffling me, and I can only assume that some combination of iOS5/ARC is causing the nil object to be coerced to a blank string/pointer. The debugger shows the string as 0x0, yet when I use my isNullOrEmpty method, I get false.
return self == nil
This can never happen. If you try to send isNullOrEmpty (or any other message) to nil, nothing happens (objc_msgSend(), the function responsible for message dispatch, checks for a nil reciever as one of the first things it does and aborts).
self == (id)[NSNull null]
This will also never happen. If you send isNullOrEmpty to an object that's an instance of NSNull, your method here, which is a method on NSString, will not be called. Instead, NSNull's version (which probably doesn't exist) will be.
Likewise, ([self respondsToSelector:#selector(count)] && [(NSArray *) self count]) is never going to happen. If the object is an NSArray, then isNullOrEmpty will never run, because, again, it's a method of NSString.
Correspondingly, [(NSData *) self length] doesn't do what you think it does. NSString instances do respond to length, but casting the object to NSData doesn't use the NSData version of the method -- it still ends up as the NSString version of length, because the object actually is an NSString (casting only happens at compile-time; it can't change anything at run-time).
[self isEqualToString:#"(null)"]
Here you appear to be checking for nil again, but you are being misled by the representation that NSLog chooses when it prints nil:
NSLog(#"%#", nil);
This displays (null) in the console, but that doesn't mean that the object itself is a string with those characters. NSLog just chooses that string to display for nil.*
Several of the things you are doing would require this to be in a category on NSObject, so that the method would in fact be called even if the object was not an NSString.
To check for a string consisting only of whitespace, all you need is the comparison to the empty string #"" after trimming whitespace:
NSString * trimmedSelf = [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
// Then either:
[trimmedSelf isEqualToString:#""];
// Or:
([trimmedSelf length] == 0);
*And even better, doing NSLog(#"%#", [NSNull null]); displays <null> (angle brackets instead of parentheses), wonderfully confusing the first few times you encounter NSNull.
Another approach can be to define a simple macro.
#define NSStringIsNullOrEmpty(str) ((str==nil) || [(str) isEqualToString:#""])
It's simple and effective. If you do not like macros you can always convert it to a function call without affecting the rest of your code.
-- Update:
#Bryan has raised a good point. An inline function is a great way to go. Here is an updated macro that will evaluate str only once.
#define NSStringIsNullOrEmpty(str) ({ NSString *_str=(str); ((tmp==nil) || [tmp isEqualToString:#""]);})
In Objective-C, sending a message to nil will always return 0 (or NO, a zeroed-out struct, NULL, etc., depending on the declared return type). The isNullOrEmpty method that you wrote won't actually be invoked when you send isNullOrEmpty to nil. See the accepted answer to Sending a message to nil? for more information.
Perhaps you could change your method to be isNotNullOrEmpty. Then a return value of 0 when sending isNotNullOrEmpty to nil will make sense.
You aren't calling your method, but sending a message to nil.
This is expected behavior. You are sending a message to nil after all. So it is returning either nil (or some other 0 value). Which short circuits to false so that '0' is printed in the cases shown below:
NSLog([s1 isNullOrEmpty] ? #"1":#"0"); // prints 0
NSLog([(NSString*)nil isNullOrEmpty] ? #"1":#"0"); // prints 0
You can even confirm your message is not being called for those cases by setting a breakpoint in your new category method.
Like others have said, calling [nil isNullOrEmpty]; will not actually run your method. The nil object is just that : empty itself.
As a solution, I'd like to say that it's not because you're in an Object-Oriented language that you must never use functions.
BOOL IsStringNilOrEmpty(NSString*)str
{
return str == nil ||
str == null ||
[#"" isEqualToString:str] ||
[[str stringByReplacingOccurrencesOfString:#" " withString:#""] length] == 0||
[str isEqualToString:#"(null)"]
|| ([str respondsToSelector:#selector(length)] && [(NSData *) str length] == 0)
|| ([str respondsToSelector:#selector(count)] && [(NSArray *) str count] == 0)
|| [[str stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] == 0;
}
actually I just fixed this problem by turning it around like so
-(BOOL) isNotNullOrWhiteSpace
{
return [self length] != 0 && [[self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] != 0;
}
so instead of isNullOrWhiteSpace it's isNotNullOrWhiteSpace.
Here's my method of checking null/empty
-(NSString*)NULLInputinitWithString:(NSString*)InputString
{
if( (InputString == nil) ||(InputString ==(NSString*)[NSNull null])||([InputString isEqual:nil])||([InputString length] == 0)||([InputString isEqualToString:#""])||([InputString isEqualToString:#"(NULL)"])||([InputString isEqualToString:#"<NULL>"])||([InputString isEqualToString:#"<null>"]||([InputString isEqualToString:#"(null)"])||([InputString isEqualToString:#"NULL"]) ||([InputString isEqualToString:#"null"])))
return #"";
else
return InputString ;
}
Have you thought about creating a class method on a category that extends NSString?
NSString+NSStringExtensions.h
#import <Foundation/Foundation.h>
#interface NSString(NSStringExtensions)
+(BOOL)isNilOrEmpty:(NSString*)string;
#end
NSString+NSStringExtensions.m
#import "NSString+NSStringExtensions.h"
#implementation NSString(NSStringExtensions)
+(BOOL)isNilOrEmpty:(NSString*)string
{
if (nil == string)
{
return YES;
}
if (string.length == 0)
{
return YES;
}
return NO;
}
#end
Then you use it like this:
#import "NSString+NSStringExtensions.h"
...
NSLog([NSString isNilOrEmpty:#""] ? #"1":#"0");

Condition for checking NOT <null> value for NSString in Objective C

Code:
NSString *tempPhone = [NSString stringWithFormat:#"%#", [personDict objectForKey:kPhoneKey]];
NSLog(#"NSString *tempPhone = %#",tempPhone);
Output:
NSString *tempPhone = <null>
Now I want to add if condition, for not null; I tried followings:
if (tempEmail != NULL)
if (tempPhone != Nil)
if (tempPhone != nil)
if (![tempPhone compare:#"<null>"])
if (tempPhone != (NSString*)[NSNull null])
I also Checked this Post.
None of them is working for me. Where I am going wrong??
Try the following code
id phoneNo = [personDict objectForKey:kPhoneKey];
if( phoneNo && ![phoneNo isKindOfClass:[NSNull class]] )
{
NSString *tempPhone = [NSString stringWithFormat:#"%#", [personDict objectForKey:kPhoneKey]];
NSLog(#"NSString *tempPhone = %#",tempPhone);
}
else
{
NSLog(#"NSString *tempPhone is null");
}
I think your personDict does not have an object for the key kPhoneKey, so it is returning nil. When you format nil using %#, you get the string "(null)".
id object = [personDict objectForKey:kPhoneKey];
if (object) {
NSString *tempPhone = [NSString stringWithFormat:#"%#", object];
NSLog(#"NSString *tempPhone = %#",tempPhone);
} else {
// object is nil
}
if (tempPhone != nil || [tempPhone isEqualToString:#"(null)"])
Works for me.
It's like this :
if (![tempPhone isKindOfClass:[NSNull class]] && tempPhone != nil)
if ([str_name isKindOfClass:[NSNull class]])
works for me...
I Checked the webResponse (JSON, in my case).
It was returning me the string with value:
<null>
So, The following condition worked for me:
if (![tempPhone isEqualToString:#"<null>"])
Thanks for all your time. Thanks.
Because compare method returns type NSComparisonResult which is defined as
enum _NSComparisonResult {NSOrderedAscending = -1, NSOrderedSame, NSOrderedDescending};
typedef NSInteger NSComparisonResult;
If the string is the same, it will return NSOrderedSame which have a NSInteger value of 0.
Thus, the following line actually means...
if (![tempPhone compare:#"<null>"]) // `tempPhone` is equals to `#"<null>"`
or in a more understandable explanation, if tempPhone value is equal to #"<null>".
You should write it as
if ([tempPhone compare:#"<null>"] != NSOrderedSame)
or
if (![tempPhone isEqualString:#"<null>"])
In case the string is having a null value. Example in NSLog.. Implement this way..
if ([StringName isKindOfClass:[NSNULL Class]]) {
}
else {
}
First we need to check string length.
if (tempPhone.length == 0)
`
{
//Your String is having empty value (E.x, (null))
}
else
{
// You having some values in this string
}`

NSString is empty

How do you test if an NSString is empty? or all whitespace or nil? with a single method call?
You can try something like this:
#implementation NSString (JRAdditions)
+ (BOOL)isStringEmpty:(NSString *)string {
if([string length] == 0) { //string is empty or nil
return YES;
}
if(![[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length]) {
//string is all whitespace
return YES;
}
return NO;
}
#end
Check out the NSString reference on ADC.
This is what I use, an Extension to NSString:
+ (BOOL)isEmptyString:(NSString *)string;
// Returns YES if the string is nil or equal to #""
{
// Note that [string length] == 0 can be false when [string isEqualToString:#""] is true, because these are Unicode strings.
if (((NSNull *) string == [NSNull null]) || (string == nil) ) {
return YES;
}
string = [string stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
if ([string isEqualToString:#""]) {
return YES;
}
return NO;
}
I use,
+ (BOOL ) stringIsEmpty:(NSString *) aString {
if ((NSNull *) aString == [NSNull null]) {
return YES;
}
if (aString == nil) {
return YES;
} else if ([aString length] == 0) {
return YES;
} else {
aString = [aString stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
if ([aString length] == 0) {
return YES;
}
}
return NO;
}
+ (BOOL ) stringIsEmpty:(NSString *) aString shouldCleanWhiteSpace:(BOOL)cleanWhileSpace {
if ((NSNull *) aString == [NSNull null]) {
return YES;
}
if (aString == nil) {
return YES;
} else if ([aString length] == 0) {
return YES;
}
if (cleanWhileSpace) {
aString = [aString stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
if ([aString length] == 0) {
return YES;
}
}
return NO;
}
I hate to throw another log on this exceptionally old fire, but I'm leery about editing someone else's answer - especially when it's the selected answer.
Jacob asked a follow up question: How can I do this with a single method call?
The answer is, by creating a category - which basically extends the functionality of a base Objective-C class - and writing a "shorthand" method for all the other code.
However, technically, a string with white space characters is not empty - it just doesn't contain any visible glyphs (for the last couple of years I've been using a method called isEmptyString: and converted today after reading this question, answer, and comment set).
To create a category go to Option+Click -> New File... (or File -> New -> File... or just command+n) -> choose Objective-C Category. Pick a name for the category (this will help namespace it and reduce possible future conflicts) - choose NSString from the "Category on" drop down - save the file somewhere. (Note: The file will automatically be named NSString+YourCategoryName.h and .m.)
I personally appreciate the self-documenting nature of Objective-C; therefore, I have created the following category method on NSString modifying my original isEmptyString: method and opting for a more aptly declared method (I trust the compiler to compress the code later - maybe a little too much).
Header (.h):
#import <Foundation/Foundation.h>
#interface NSString (YourCategoryName)
/*! Strips the string of white space characters (inlcuding new line characters).
#param string NSString object to be tested - if passed nil or #"" return will
be negative
#return BOOL if modified string length is greater than 0, returns YES;
otherwise, returns NO */
+ (BOOL)visibleGlyphsExistInString:(NSString *)string;
#end
Implementation (.m):
#implementation NSString (YourCategoryName)
+ (BOOL)visibleGlyphsExistInString:(NSString *)string
{
// copying string should ensure retain count does not increase
// it was a recommendation I saw somewhere (I think on stack),
// made sense, but not sure if still necessary/recommended with ARC
NSString *copy = [string copy];
// assume the string has visible glyphs
BOOL visibleGlyphsExist = YES;
if (
copy == nil
|| copy.length == 0
|| [[copy stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] == 0
) {
// if the string is nil, no visible characters would exist
// if the string length is 0, no visible characters would exist
// and, of course, if the length after stripping the white space
// is 0, the string contains no visible glyphs
visibleGlyphsExist = NO;
}
return visibleGlyphsExist;
}
#end
To call the method be sure to #import the NSString+MyCategoryName.h file into the .h or .m (I prefer the .m for categories) class where you are running this sort of validation and do the following:
NSString* myString = #""; // or nil, or tabs, or spaces, or something else
BOOL hasGlyphs = [NSString visibleGlyphsExistInString:myString];
Hopefully that covers all the bases. I remember when I first started developing for Objective-C the category thing was one of those "huh?" ordeals for me - but now I use them quite a bit to increase reusability.
Edit: And I suppose, technically, if we're stripping characters, this:
[[copy stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] == 0
Is really all that is needed (it should do everything that category method does, including the copy), but I could be wrong on that score.
I'm using this define as it works with nil strings as well as empty strings:
#define STR_EMPTY(str) \
str.length == 0
Actually now its like this:
#define STR_EMPTY(str) \
(![str isKindOfClass:[NSString class]] || str.length == 0)
Maybe you can try something like this:
+ (BOOL)stringIsEmpty:(NSString *)str
{
return (str == nil) || (([str stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]).length == 0);
}
Based on the Jacob Relkin answer and Jonathan comment:
#implementation TextUtils
+ (BOOL)isEmpty:(NSString*) string {
if([string length] == 0 || ![[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length]) {
return YES;
}
return NO;
}
#end
Should be easier:
if (![[string stringByReplacingOccurencesOfString:#" " withString:#""] length]) { NSLog(#"This string is empty"); }

Problem in String camparisson ...!

here is my code :
NSUInteger f;
for (f = 0; f < [appDelegate.books count]; f++) {
check = [appDelegate.books objectAtIndex:f];
checkthis = check.LotteryNumber;
mystring = check.LotteryNumber;
NSLog(#"Dynamic Value: %#",mystring);
NSLog(#"Static Value: %#",checkthis);
if (checkthis == mystring) {
found = YES;
break;
}
printf("In LOOP");
}
if ( found ) {
// do found
NSLog(#"Found");
} else {
// do not found
NSLog(#"not Found");
}
//if (checkthis == mystring) {
in above line if i place checkthis on both side , its working , but when i am taking a dynamic value its not working..
i also tried like this
if(checthis isEqualToString mystring)
same problem here ....
Thanks in advance
You're using pointer comparison and not string comparison.
You should be using:
if([checkThis isEqualToString:myString]) { ...
You are using comparision by pointer the comparison you made checks memory a ddresses and will only return true if its the same object being compared, you should use [string isEqualToString:otherString] method from NSString instead