Objective-C: Two 'identical' strings do not match? - ios

I have a two strings.
Once is a response from a TCP server using NSStream events, using:
NSString *output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding];
And one is a string produced from on the fly, that should match the returned string from the NSStream.
I have NSLog both of these out, and they are identical.
I have tried to NSLog the Lengths of the strings, and one is two characters longer - Even though they are both identical in 'text' form.
Any suggestions to point me in the right direction?
I need to know if they match, as if they do, another event will be triggered to enhance and add additional functionality to my app.

Never use == to compare strings. If their contents are character-by-character identical, you can use isEqualToString to compare 2 strings. If your strings have different lengths, though, then they are not character-by-character identical.
Write a for loop that uses the method characterAtIndex to log the characters from each string 1 at a time and compare them. You might need to log the characters' integer values so you can see info about the non-printable ones.

Thanks Guys.
Fixed with #rdelmar suggestions - I didn't know this was possible in Objective-C:
NSString *trimOutput = [output stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];

Related

NSAttributedString & decomposedStringWithCanonicalMapping ranges

I'm running into problems with international (in this case Korean) NSString values.
The same input string is used in two different parts of the program. The first part finds a substring that needs highlighting, stores the NSString and the range for the highlighting into a database.
The second part of the program retrieves the string and displays the highlighting.
The marking part is done using an NSString that has been normalized in Unicode Normalization Form C using the precomposedStringWithCanonicalMapping method on NSString. An NSRange and an NSString are then stored into the Core Data database.
The graphical highlighting is performed by retrieving the NSRange and NSString from the database, putting the NSString into the same Form C using the same method, using this to initialize an NSMutableAttributedString and using the NSRange to set its text attributes.
At this stage, the program crashes because the NSMutableAttributedString is 80 characters long, whereas the NSString was 81 characters long..
NSAttributedString does not have a precomposedStringWithCanonicalMapping method and I assume it changes the representation internally resulting in a different encoding and thus length.
What can I do?
is the a way of forcing NSAttributedString to keep an underlying encoding?
is there a way of converting an NSRange from one encoding to another?
or is there anything else I can do?
Ok,
I did eventually find out what had happened. In one particular place in the program I mistakenly used decomposed​String​With​Canonical​Mapping rather than precomposed​String​With​Canonical​Mapping and that's where the "wrong" mapping came from.

How to decode \U201a\U00c4\U00f2\U201a\U00c4\U00f4 this? [duplicate]

This question already has answers here:
UTF8 character decoding in Objective C
(4 answers)
Closed 6 years ago.
Aam getting long text from server and that text contains character \U201a\U00c4\U00f2He-Must-Not-Be-Named\U201a\U00c4\U00f4.
When I display text in textView am getting some different characters...
How do I get normal Text in objective c???
Please help me out with this
When I received data from server I use
infoDictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
and from that infoDictionary I get text like
locks his cousin Dudley in the snake\U201a\U00c4\U00f4s captivity just in the blink of an eye. Each wand has a magical core such as phoenix\U201a\U00c4\U00f4s hair or dragon heartstring, that performs all the magic.
\n
And I assign this value to textView like
detailsTextView.text = [infoDictionary objectForKey:#"DESCRIPTION"];
But in textView am getting some different characters..
There are two possibilities, one more likely, one less likely.
The less likely one is that your server sends rubbish when it tries to translate its data into JSON.
The more likely one is that you are just frightening yourself, and there is nothing wrong. Something like \U201a\U00c4\U00f2He-Must-Not-Be-Named\U201a\U00c4\U00f4 is exactly how non-ASCII characters are encoded in UTF-8. For example, U201A is the Unicode character "Single Low-9 Quotation Mark". Use the character viewer in MacOS X to find out what the characters are if you are curious. If you use NSLog, you will also get the same strange characters. They should be displayed in your text view perfectly fine.
However, in your case, the sequence \U00c4\U00f2 or \U00c4\U00f4 seems to be highly unusual. This would seem to be a problem with the server code, or with the actual data that is stored. If you are given rubbish data, there's nothing you can do about it. It's also not created by one of the typical stupid mistakes on the server (storing MacRoman characters, or taking UTF-8 and assume the bytes are code points). The only thing you can do is to contact whoever is supplying this data.
Now there is something you can do. You can use the method stringByReplacingOccurencesOfString: to replace nonsense data with something sensible. I wouldn't expect the sequence \U201a\U00c4\U00f4s = ’ to ever appear in a string that I display. So figure out what string belongs there (say a quotation mark) and replace it. So get the description into an NSString, use stringByReplacingOccurencesOfString: and use the result. There may be more strange combinations than just this one.
stringWithUTF8String: takes const char* as an argument, so no "#"
symbol in the front.
NSString *description = [infoDictionary objectForKey:#"DESCRIPTION"];
NSString *str = [NSString stringWithUTF8String:description.UTF8String];
detailsTextView.text = str;
Show this str in your textview.

How to take non-english characters from UITextField and consider them as normal characters

i have a database that contains non-english words ( for those who wonders turkish letters). And i have an algorithm which compares the input with database.
So my problem is this; in my database all the strings are written with turkish characters. So lets say i have thıs element to compare heyyö. When user enters heyyo it won't find it since they are considered as different words.
My first thought was put special cases and when a non-english character found consider whether english or non-english letter ( like g with ğ or i with ı) but that means a lot of brute force.
how can i do this with elegance.
Oh and user enters this inputs from a textfield if that wasn't implied.
The removal of diacritics is called "folding." You can compare strings without regard to diacritics using the option NSDiacriticInsensitiveSearch.
[string compare:otherString options:NSDiacriticInsensitiveSearch] == NSOrderedSame
You can similarly generate a folded string using stringByFoldingWithOptions:locale:.
Note that this only removes diacritics. There are many ways that characters can "seem" the same without being the same. Turkish is somewhat notorious about this because the lowercase version of "I" is "ı" (LATIN SMALL DOTLESS I), not "i". If you're particularly dealing with Turkish, you may have to account for this.
What you can do is something like this:
NSString *input = #"heyyö";
NSData *intermediaryDataForm = [input dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *output = [[NSString alloc] initWithData:intermediaryDataForm encoding:NSASCIIStringEncoding];
That way, because the turkish letters are not part of ASCII, and you are allowing a lossy conversion, then it automatically changes 'ö' to 'o' when converted to the NSData form. Then converting it back to NSString solves the issue.

NSStrings' not equal even though characters are the same

I'm retrieving a string from an NSData object dataOut (coming from a CBCharacteristic), and defining a testString as well which is defined as the same value as shown below:
The problem is when I try to compare the two, I get that the two strings are not equal, even though the debugger shows otherwise:
Here is the comparison:
The log keeps logging "Strings are not equal!"
What am I doing wrong? Is the encoding incorrect, even though the strings are the same?
You will see them are different when you convert them to NSData and print out the data.
What you see is not always what you get especially with Unicode characters. There maybe invisible characters or some characters that looks similar.

Compare Phone Numbers with different format

Phone nubmber can have different Formats , like 0XXXXXXXXXX or +91XXXXXXXXXX or XXXXXXXXXX.
In all cases , phone number is similar.
How can i compare ?
Please do this for love of god: Handling all formats of phone numbers is as tricky and hairy as handling different data formats. It's always a sane option to use some existing "mature" library. Use PhoneNumberKit, its one of the mature and popular libraries out there.
But if you want to live on the edge, you can try something like this -
Reverse the string & compare only the first 10 chars.
Regular Expressions would be a better solution. Have as many regular expressions as there are formats & you are good to go.
Please open source this library for others to benefit :)
General reading on handling phone numbers
You could start comparing right to left using a custom character by character match code. It also works because the last few digits on phones vary more than the first few, so your code will fail fast in a unequal comparison which is what you want anyways. Keep a count of how many matches you have and if it passes a certain threshold say 10, then call the number equal. Without know more specifics this would be made to work reasonably well.
As Mentioned by srikar to reverse the string and compare 10 characters.Create the method and call it for all the three strings and after that compare them.
NSMutableString *reversedString = [NSMutableString string];
NSInteger charIndex = [myString length];
NSInteger count;
count=10;
while(count >= 0) {
count--;
charIndex--;
NSRange subStrRange = NSMakeRange(charIndex, 1);
[reversedString appendString:[myString substringWithRange:subStrRange]];
}

Resources