Compare the text of two text fields - objective-c

How do you compare the text in two text fields to see if they are the same, such as in "Password" and "Confirm Password" text fields?
if (passwordField == passwordConfirmField) {
//they are equal to each other
} else {
//they are not equal to each other
}

In Objective-C you should use isEqualToString:, like so:
if ([passwordField.text isEqualToString:passwordConfirmField.text]) {
//they are equal to each other
} else {
//they are *not* equal to each other
}
NSString is a pointer type. When you use == you are actually comparing two memory addresses, not two values. The text properties of your fields are 2 different objects, with different addresses.
So == will always1 return false.
In Swift things are a bit different. The Swift String type conforms to the Equatable protocol. Meaning it provides you with equality by implementing the operator ==. Making the following code safe to use:
let string1: String = "text"
let string2: String = "text"
if string1 == string2 {
print("equal")
}
And what if string2 was declared as an NSString?
let string2: NSString = "text"
The use of == remains safe, thanks to some bridging done between String and NSString in Swift.
1: Funnily, if two NSString object have the same value, the compiler may do some optimization under the hood and re-use the same object. So it is possible that == could return true in some cases. Obviously this not something you want to rely upon.

You can do this by using the isEqualToString: method of NSString like so:
NSString *password = passwordField.text;
NSString *confirmPassword = passwordConfirmField.text;
if([password isEqualToString: confirmPassword]) {
// password correctly repeated
} else {
// nope, passwords don't match
}
Hope this helps!

Related

Convert Swift convenience init with Switch statement to Objective-C

I am trying to convert this swift code to Objective-C
convenience init(fromString string: String, format:DateFormat)
{
if string.isEmpty {
self.init()
return
}
let string = string as NSString
switch format {
case .DotNet:
let startIndex = string.rangeOfString("(").location + 1
let endIndex = string.rangeOfString(")").location
let range = NSRange(location: startIndex, length: endIndex-startIndex)
let milliseconds = (string.substringWithRange(range) as NSString).longLongValue
let interval = NSTimeInterval(milliseconds / 1000)
self.init(timeIntervalSince1970: interval)
So far, I am doing this:
-(id) initFromString: (NSString *) string format: (DateFormat *) format{
if (string == nil) {
self = [self init];
return self;
}
switch (format) {
case .DotNet:
NSRange *startIndex = [[string rangeOfString:#"("] location]+1;
}
}
and have already run into the following errors:
for the switch(format): statement requires expression of integer type (DateFormat * __strong' invalid)
and for the 2 following lines: Expected expression
Any ideas ?
In Objective-C, the string is impliedly optional. Testing for nil merely tests whether a string was supplied. It doesn't check whether an empty string was supplied. You probably want to switch to string.length == 0 as, by the magic of nil-messaging, that'll work to check for either an empty string or no string at all.
Objective-C uses C's switch statement. So you can switch on integral types only. If this were Objective-C code originally, DateFormat would probably be an NS_ENUM — an integral type rather than an object type. It looks like the original was an enumeration from your use of dot syntax? If you can make it an Objective-C enumeration then do so and simply use:
- (id)initFromString:(NSString *)string format:(DateFormat)format {
....
switch(format)
{
case DateFormatDotNet: {
....
} break;
}
(with the curly brackets within the case being because you want to declare variables in there).
Otherwise, if it must be an object format then you're looking at a painful construction like:
if([format isEqual:[DateFormat dotNetFormat]]) {
}
else if([format isEqual:[DateFormat otherFormat]]) {
}
... etc ...
Also Objective-C has a syntactic distinction between structs, which are exactly what they are in C — named fields but no built-in behaviour — and object types, which is again because it's a strict superset of C. NSRange is a struct. So square bracket messaging syntax doesn't work on it. Instead of:
[[string rangeOfString:#"("] location]
Use:
[string rangeOfString:#"("].location
Square brackets around the rangeOfString call because it's a message dispatch to an object, then a dot for location because you get back a C struct as a value, and that's how one accesses a field in a C struct.
(dot syntax also works for properties on Objective-C objects, but explicitly to alias to getter and setter calls, and only for about the most recent of Objective-C's three decades)
Assuming this code is related to How to convert a Swift enum: String into an Objective-C enum: NSString?
Since your DateFormat variable is an object with a dateFormatType that is an NSString, you are going to have to use a chained if-else construct to select from the various possibilities:
if([format.dateFormatType compare: DotNetDateFormatType] == NSOrderedSame) {
[self handleDotNetDateFormat: format]
} else if ([format.dateFormatType compare: RSSDateFormatType] == NSOrderedSame) {
[self handleRSSDateFormat: format]
...
Objective-C has no concept of the dot-value syntax for enum values (so ".DotNet" is not a valid term in Objective-C). That's why the compiler is complaining about those either lines.

Using a function argument inside a function in Objective-C

I am new to Objective-C development and I have already run into the first problem. I am trying to write a function that takes a string as argument and compares that string with other strings. The pseudo code for the function would be the following:
String string2
String string3
function compare_string (String string) {
if (string == "a specific string" &&
string == string2 &&
string == string3) {
// do something
}
}
Until now I only have the following:
NSString *string2 = #"Second string";
NSString *string3 = #"Third string";
(void) compare_string: (NSString *) string {
but now I am already stuck because I don't know how to call the input string string inside the function. Should I simply do something like
if (string == string2) { ... }
or is there another way to use function arguments in Objective-C?
This will be like this:
-(void)compareString:(NSString *string){
if ( [string isEqualToString:#"a specific string"] && [string isEqualToString:string2] && [string isEqualToString:string3] ){
// do something
}
}
NOTE: str1==str2 will compare the memory address, and isEqualToString: compares the contents of the strings.
Check out the docs for NSString there are a bunch of methods that do this for you already - so you don't need to make your own string comparison code
An example would look like
if ([string compare:string2] == NSOrderedSame) { ... }
This is handy if you wish to do complex comparisons like case insensitive etc
for simple equality you could just use
if ([string isEqualToString:string2]) { ... }
Edit
I mis read the question - here is an answer that actually relates to what you asked
You need to use the isEqual: methods defined on object for checking equally. == will only check the pointer values.
You could write your method like this
- (void)compareString:(NSString *)string;
{
if ([#[string, string, string] isEqual:#[ #"a specific string", string1, string2]]) {
// do stuff
}
}
Then later calling it would look like this
[self compareString:#"A string to compare"];
NB
Wrapping it up in arrays reads slightly nicer than comparing them all individually

How to check if NSString returned by objectForKey is "" objective c

I'm not exactly sure how to check whether a NSString is blank or not, I've got this code...
NSString *imageName = [myItem objectForKey:#"iconName"];
if(imageName == #"")
{
}
And when I do a print on the myItem object, it comes up as..
iconName = "";
At the NSString *imageName line, I noticed in xcode in the console it says
"variable is not NSString"
Which I don't get as iconName is saved and stored on the parse.com database as a NSString.
When I run that code though it doesn't seem to realise that imageName = "";
You should use this code block when comparing strings:
if ([imageName isEqualToString:#""]){
}
You need to use isEqualToString to compare two strings. If you just use == then you are comparing two pointers.
You could also check to see if the object you are receiving is a NSString by:
if ([imageName isKindOfClass:[NSString class]])
Hope this helps.
Although you have a few answers already, here is my take.
First of all, your warning (not error) can be fixed like this:
NSString *imageName = (NSString *)[myItem objectForKey:#"iconName"];
Then, I would check to make sure that the string is not nil and that it is not blank. The easiest way to do this in objective-C is to check the length of the string, since if it nil it will return 0, and if it is empty, it will return 0:
if([imageName length] == 0)
{
// This is an empty string.
}
As #jlehr points out, if there is the possibility that imageName may not actually be stored as a string, then in order to prevent a crash you need to check first. (This may or may not be needed, depending on the logic of your application):
if ([imageName isKindOfClass:[NSString class]]
{
if([imageName length] == 0)
{
// This is an empty string.
}
}
The "variable is not NSString" is probably because objectForKey: return an id.
To should use [imageName isEqualToString:#""].

If "a == b" is false when comparing two NSString objects

I have a class with an accessible method that passes back an NSString when called.
[MyClass getMyString]
The string variable in that class is actually assigned in the didSelectRowAtIndexPath: part of a table like this:
myString = cell.textLabel.text;
When I retrieve the string by calling that method, I assign it to another string in the class that called it and compare it to a string I have defined
NSString *mySecondString;
mySecondString = #"my value";
if(mySecondString == myString){
i = 9;
}
I have stepped through the code and every time it evaluates the if statement, it skips right past the i=9 and goes to the next else if statement. Why would this be? Why don't they evaluate to be the same value? If you hover your cursor over each of the values during debugging they will show they have the same value, but the code for some reason with not do as I expect it to do and assign 9 to i.
Any thoughts?
You're assuming that the C == operator does string equality. It doesn't. It does pointer equality (when called on pointers). If you want to do a real string equality test you need to use the -isEqual: method (or the specialization -isEqualToString: when you know both objects are strings):
if ([mySecondString isEqualToString:myString]) {
i = 9;
}
You are comparing pointers to strings, rather than the strings themselves. You need to change your code to
if (if([mySecondString isEqualToString:myString]) {
....
}
you can not use '==' to compare two NSString
you should to use [NSString isEqualToString:(NSString*)] to compare two string
You can not compare the two string using "==" this is for int and other values.
you can use below code for the comparing two string
if ([Firststring isEqualToString:Secondstring]) {
NSLog(#"Hello this both string is same ");
}
It's a basic concept of pointer, you are missing. (YES, myString and mySecondString are pointers to the string).
Now, if(mySecondString == myString) will go TRUE only if, both the pointers are pointing to the same location. (Which they won't in most cases)
You should be doing if ([mySecondString isEqualToString:myString]), which will be comparing your both string's content for equality.

Checking for equality in Objective-C

How do i check the key in dictionary is same as the string in method parameter?
i.e in below code , dictobj is NSMutableDictionary's object , and for each key in dictobj i need to compare with string. How to achieve this ? Should i typecase key to NSString??
-(void)CheckKeyWithString:(NSString *)string
{
//foreach key in NSMutableDictionary
for(id key in dictobj)
{
//Check if key is equal to string
if(key == string)// this is wrong since key is of type id and string is of NSString,Control doesn't come into this line
{
//do some operation
}
}
}
When you use the == operator, you are comparing pointer values. This will only work when the objects you are comparing are exactly the same object, at the same memory address. For example, this code will return These objects are different because although the strings are the same, they are stored at different locations in memory:
NSString* foo = #"Foo";
NSString* bar = [NSString stringWithFormat:#"%#",foo];
if(foo == bar)
NSLog(#"These objects are the same");
else
NSLog(#"These objects are different");
When you compare strings, you usually want to compare the textual content of the strings rather than their pointers, so you should the -isEqualToString: method of NSString. This code will return These strings are the same because it compares the value of the string objects rather than their pointer values:
NSString* foo = #"Foo";
NSString* bar = [NSString stringWithFormat:#"%#",foo];
if([foo isEqualToString:bar])
NSLog(#"These strings are the same");
else
NSLog(#"These string are different");
To compare arbitrary Objective-C objects you should use the more general isEqual: method of NSObject. -isEqualToString: is an optimized version of -isEqual: that you should use when you know both objects are NSString objects.
- (void)CheckKeyWithString:(NSString *)string
{
//foreach key in NSMutableDictionary
for(id key in dictobj)
{
//Check if key is equal to string
if([key isEqual:string])
{
//do some operation
}
}
}