How to use 'CapitalizedString' with Turkish letters? - ios

I have a problem with Turkish letters.
I have a method for deserialize the JSON. I'm getting the correct data from web service and I set it to my object's variable. newsCategory.name contains 'ASKERİ HAVACILIK' which is NSString.
+(NewsCategory*) convertCategory: (NSMutableDictionary *) jsonDictionary{
NewsCategory *newsCategory = [[NewsCategory alloc] init];
newsCategory.name =[jsonDictionary objectForKey:#"name"];
return newsCategory;
}
I have to convert 'ASKERİ HAVACILIK' to 'Askeri Havacılık'. So I used capitalizedString for this.
NSString *capitalizedName = [jsonDictionary objectForKey:#"name"];
newsCategory.name = [capitalizedName capitalizedString];
But unfortunately, it shows #"Askeri̇ Havacilik"
How I convert this to 'Askeri Havacılık' ?

NSString *capitalizedName = [jsonDictionary objectForKey:#"name"];
NSString *accentedString = capitalizedName;
NSString * capitalizedString = [accentedString stringByFoldingWithOptions:NSDiacriticInsensitiveSearch locale:[NSLocale currentLocale]];
newsCategory.name = [capitalizedString capitalizedString];
Depending on the nature of the strings you want to convert, you might want to set a fixed locale (e.g. English) instead of using the user's current locale. That way, you can be sure to get the same results on every machine.

Related

What is the difference between #"1.5" and #(1.5) while setting the value in NSDictionary?

In iPhone project,
It was while I was while setting Value in dictionary,
NSMutableDictionary*dictionary=[[NSMutableDictionary alloc] init];
[dictionary setValue:#(2.8) forKey:#"Why"];
AND,
NSMutableDictionary*dictionary=[[NSMutableDictionary alloc] init];
[dictionary setValue:#"2.8" forKey:#"Why"];
My question is Why not #"2.5" and #(2.5) ?
You have two questions, it would be better to have a single question.
But as to the difference,#"2.5" is an NSString where #(2.5) is an NSNumber. There is a big difference between textual and numeric data.
As for why you need an NSNumber and not NSString is obvious: the kerning is a numeric value.
using the #() syntax you can box arbitrary C expressions. This makes it trivial to turn basic arithmetic calculations into NSNumber objects see below:
double x = 24.0;
NSNumber *result = #(x * .15);
NSLog(#"%.2f", [result doubleValue]);
You can also refer NSNumber object as #"" string but cant make calculations like above example. In your case both are acceptable but here calculation makes difference.
When you use
#"2.5" it's behave like a string
NSMutableDictionary*dictionary=[[NSMutableDictionary alloc] init];
[dictionary setValue:#"2.8" forKey:#"Why"];;
NSString *a = [dictionary ValueforKey:#"Why"];
but when you use #(2.8) then it's behave like a NSNumber
NSMutableDictionary*dictionary=[[NSMutableDictionary alloc] init];
[dictionary setValue:#(2.8) forKey:#"Why"];;
NSNumber *a = [dictionary ValueforKey:#"Why"];
#(2.8) is a type of NSNumber.
#"2.8" is a type of NSString.
Both the type and value were different between there two.

How to get the data from a row in an NSArray using only part of the row to search

Lets say i have an array filled with several rows
dates = [NSArray arrayWithObjects:#"2012-05-01||Blue", #"2012-05-02||Red", #"2012-05-03||Green", #"2012-05-04||Orange", #"2012-05-05||Yellow", #"2012-05-06||Purple", #"2012-05-07||Silver", nil];
and then I have a date to search by 2012-05-01
How do i search for an object by only part of it without doing a big for( loop because this array will theoretically hold a few thousand cells.
EDIT:
if necessary how do i load the data into an NSDictionary? (i've never used them)
I know i can get the data like so
for(NSString *row in dates) {
NSString *date = [[row componentsSeperatedByString:#"||"] objectAtIndex:0];
NSString *color = [[row componentsSeperatedByString:#"||"] objectAtIndex:1];
}
NSMutableDictionary *colorsAndDates = [[NSMutableDictionary alloc] init];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd"];
for(NSString *row in dates) {
NSString *dateString = [[row componentsSeparatedByString:#"||"] objectAtIndex:0];
NSDate *date = [dateFormatter dateFromString:dateString];
NSString *color = [[row componentsSeparatedByString:#"||"] objectAtIndex:1];
[colorsAndDates setObject:color forKey:date];
}
If I am correct, this will format it into an NSDictionary, and then I can grab the color using:
NSString *dateToFind = #"2012-05-01";
NSDate *date = [dateFormatter dateFromString:dateToFind];
NSString *theColor = [colorsAndDates objectForKey:date];
Knowing this, I will have to go back and make it all revolve around NSDictionary instead of the strings they're in.
There's a couple of things you can do other than looping through the array:
1) Use a sorted array. Even if you need to keep the data in the initial order, you can make a sorted copy of it. Then you can do a binary search (if there are n items, check the n/2 item, if it's less than your date and repeat the process with only the data from n/2 to n, or if it's greater, then repeat with the data from 0 to n/2. Sort once, find many.
2) Create a dictionary on the fly using the data. You can use the the 10 character prefix of the data as the key. You'll have to maintain the dictionary along with the array, so this may not be practicable if you have a lot of changes. Create dictionary once, find many. (Note: despite the answers you've gotten, a dictionary may not be the best solution, particularly if you don't have unique keys (i.e. more than one record with the same date).
3) Forget the arrays and store your data in sqlite, and write a sql statement to get it. Most useful if you have a whole lot of data. You can use sqlite to build a primary key if you have duplicate dates in your data.
Creating a dictionary:
NSDictionary *dateDictionary = #{
#"2012-05-01" : #"Blue",
#"2012-05-02" : #"Red",
#"2012-05-03" : #"Green",
#"2012-05-04" : #"Orange",
#"2012-05-05" : #"Yellow",
#"2012-05-06" : #"Purple",
#"2012-05-07" : #"Silver"
};
NSString *date = #"2012-05-01";
NSString *dateColor = dateDictionary[date];
Using the example you gave (looping through the array to create a dictionary):
NSMutableDictionary *dateDictionary = [NSMutableDictionary dictionary];
for(NSString *row in dates) {
NSString *date = [[row componentsSeperatedByString:#"||"] objectAtIndex:0];
NSString *color = [[row componentsSeperatedByString:#"||"] objectAtIndex:1];
dateDictionary[date] = color;
}
NSString *date = #"2012-05-01";
NSString *dateColor = dateDictionary[date];

Passing a _CFNSString into an NSString

I have a loop that identifies elements of a webpage via its HTML and extracts the sections I need. I'm wanting to build an array or (very) long string of the extracted text which can be used later.
The extraction uses TFHpple from GitHub. The problem seems to lie with the extracted text being a _CFNSString, and these don't allow me to transpose them into a NSString or NSMutuableArray.
The code I'm using is:
NSArray *webNodes = [webParser searchWithXPathQuery:tutorialsXpathQueryString];
NSString *extractedText = [[NSString alloc] init];
NSMutableArray *extractedArray = [[NSMutableArray alloc] initWithCapacity:0];
for (TFHppleElement *element in webNodes) {
Extraction *extraction = [[Extraction alloc] init];
[extractedArray addObject:extraction];
extraction.title = [[element firstChild] content];
extractedText = extraction.title;
NSLog(#"\n\nTitle: %#", extractedText);
}
The NSLog at this point shows me extractedText holds I'm after for each loop, breaking the code shows extractedText to be a _CFNSString.
If I try adding
text = [text StringByAppendingString extractedText];
(with 'text' being an NSString initialised before the loop) as the last step of the loop I get a null value. Its the same if I try adding text or extraction.title directly into an array.
I found this question Convert NSCFString to NSString but the conversion seems to be going the other way (NSString to CFNSString). When I added equivalent code I got bridging errors and the code doesn't run.
How can I collect the data within extraction.title to build a string or array that can be used later?
You said you only want a text.
Get it in one line of code for array:
NSArray *extractedArray = [webNodes valueForKeyPath:#"firstChild.content"];
For string:
NSString *extractedText = [webNodes valueForKeyPath:#"firstChild.content"] componentsJoinedByString:#" "];

Replace String Between Two Strings

I have a serious problem about indexing in array. I've been working on this for 2 days and couldn't find answer yet.
I want to do that, search specific character in array then replace it with other string. I'm using replaceObjectAtIndex method but my code is doesn't work.
Here is my code;
NSString *commentText = commentTextView.text;
NSUInteger textLength = [commentText length];
NSString *atSign = #"#";
NSMutableArray *commentArray = [[NSMutableArray alloc] init];
[commentArray addObject:commentText];
for (int arrayCounter=1; arrayCounter<=textLength; arrayCounter++)
{
NSRange isRange = [commentText rangeOfString:atSign options:NSCaseInsensitiveSearch];
if(isRange.location != NSNotFound)
{
commentText = [commentText stringByReplacingOccurrencesOfString:commentText withString:atSign];
[_mentionsearch filtrele:_mentionText];
id<textSearchProtocol> delegate;
[delegate closeList:[[self.searchResult valueForKey:#"user_name"] objectAtIndex:indexPath.row]];
}
}
Ok, now i can find "#" sign in the text and i can match it. But this is the source of problem that, i can not replace any string with "#" sign. Here is the last part of code;
-(void)closeList
{
NSArray *arrayWithSign = [commentTextView.text componentsSeparatedByString:#" "];
NSMutableArray *arrayCopy = [arrayWithSign mutableCopy];
[arrayCopy replaceObjectAtIndex:isRange.location withObject:[NSString stringWithFormat:#"#%#",username]];
}
When im logging isRange.location value, it returns correct. But when im try to run, my application is crashing. So, i can not replacing [NSString stringWithFormat:#"#%#",username] parameter. How can i solve this problem?
If I understand correctly you want to change a substring in a string with a new string. In this case, why don't you use directly the stringByReplacingOccurrencesOfString method of NSString:
NSString *stringToBeChanged = #"...";
NSString *stringToBeChangedWith = #"...";
NSString *commentTextNew = [commentText stringByReplacingOccurrencesOfString:stringToBeChanged withString:stringToBeChangedWith];

Get Currency Symbol and Currency Code based on ISOCountryCode

There are similar questions to this one from newbies like me in localization, but I couldn't find one that does the trick for me.
Here is my problem. We can get all the ISO country codes in an NSArray with a statement of the form [NSLocale ISOCountryCodes]. Now, for each and every country of those I would like to print the local currency as well as the currency code used in that country. What would be the appropriate way of doing this?
I did the following that does not work in the sense that I get lines of the form
US United States: (null) ((null))
when instead I would like to get lines of the form
US United States: $ (USD):
myCountryCode = [[NSLocale ISOCountryCodes] objectAtIndex:row];
appLocale = [[NSLocale alloc] initWithLocaleIdentifier: #"en_US"];
identifier = [NSLocale localeIdentifierFromComponents: [NSDictionary
dictionaryWithObject: myCountryCode
forKey: NSLocaleCountryCode]];
myDictionary = [NSLocale componentsFromLocaleIdentifier: identifier];
myCountryName = [appLocale displayNameForKey:NSLocaleCountryCode
value:[myDictionary
objectForKey:NSLocaleCountryCode]];
localCurrencySymbol = [appLocale displayNameForKey:NSLocaleCurrencySymbol
value:[myDictionary objectForKey:NSLocaleCurrencySymbol]];
currencyCode = [appLocale displayNameForKey:NSLocaleCurrencyCode
value: [myDictionary objectForKey:NSLocaleCurrencyCode]];
title = [NSString stringWithFormat:#"%# %#: %# (%#)", myCountryCode, myCountryName, localCurrencySymbol, currencyCode];
[appLocale release];
(Above identifier, myCountryCode, myCountryName, localCurrencySymbol, currencyCode, and title are all NSString pointers. Moreover myDictionary is an NSDictionary pointer and appLocale is an NSLocale pointer). Essentially the above code will be in a pickerview where I want to generate the title of each line on the fly.
Thank you very much for your time. Essentially the question is once we have the ISO country code how can we print (in the application locale) the currency symbol and the currency code for that specific country.
For anyone just wanting to get the currency code from the 3 letter iso code ( commonISOCurrencyCodes ). You can simply do this.
NSString *localeId = #"JPY"; //[[NSLocale commonISOCurrencyCodes] objectAtIndex:1];
NSLocale *locale = [NSLocale currentLocale];
NSString *currency = [locale displayNameForKey:NSLocaleCurrencySymbol
value:localeId];
NSLog(#"locale %# currency %#", localeId, currency);
Prints.
locale JPY currency ¥
Try the following test app and adapt as needed
#import <Foundation/Foundation.h>
int main(int argc, char *argv[]) {
NSAutoreleasePool *p = [[NSAutoreleasePool alloc] init];
// select an arbitrary locale identifier; you could use your row index but your
// indexing scheme would be different
NSString *localeIdentifier = [[NSLocale availableLocaleIdentifiers] objectAtIndex:72];
// get the selected locale and the application locale
NSLocale *selectedLocale = [[NSLocale alloc] initWithLocaleIdentifier:localeIdentifier];
NSLocale *appLocale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US"];
// country code and name (in app's locale)
NSString *countryCode = [selectedLocale objectForKey:NSLocaleCountryCode];
NSString *countryName = [appLocale displayNameForKey:NSLocaleCountryCode value:countryCode];
// symbol and currency code
NSString *localCurrencySymbol = [selectedLocale objectForKey:NSLocaleCurrencySymbol];
NSString *currencyCode = [selectedLocale objectForKey:NSLocaleCurrencyCode];
NSString *title = [NSString stringWithFormat:#"%# %#: %# (%#)", countryCode, countryName, localCurrencySymbol, currencyCode];
[appLocale release];
NSLog(#"title = %#",title);
[p release];
}
This logs the following to the console:
2012-06-09 06:01:08.299 Untitled 2[11668:707] title = ES Spain: € (EUR)
I think your problem here is that you are expecting that componentsFromLocaleIdentifer will return information about the locale. Instead, it returns information about the string that is passed in as the identifier. Although you can receive NSLocalCurrencySymbol, it will only be present when the string that you are passing in has an override for the particular currency (which will never happen in your case, since you are only using the standard array). An example of this in the wild would be a user who has set up a FR system, but with a USD currency.
Generally, you shouldn't need to use -displayNameForKey:value: for the NSLocaleCurrencyCode and NSLocaleCurrencySymbol, since they both return international strings, not localized strings. Thus, once you have the preferred local, you should be able to get this information just by using -objectForKey:.
The tricky part, in my testing, is that assuming that the locale in the list is sufficient to create a valid currency code and symbol isn't true, instead you need to have a language and country code. Fortunately, +[NSLocale canonicalLanguageIdentifierFromString:] will provide you the right language, which you can then append to the country code (after a _) to create the country/language string that will appropriately result in the currency information being retrieved.
Here's my revised code:
myCountryCode = [[NSLocale ISOCountryCodes] objectAtIndex:row];
appLocale = [[NSLocale alloc] initWithLocaleIdentifier: #"en_US"];
identifier = [NSLocale localeIdentifierFromComponents: [NSDictionary
dictionaryWithObject: myCountryCode
forKey: NSLocaleCountryCode]];
myDictionary = [NSLocale componentsFromLocaleIdentifier: identifier];
myCountryName = [appLocale displayNameForKey:NSLocaleCountryCode
value:[myDictionaryobjectForKey:NSLocaleCountryCode]];
// Create the currency language combination and then make our locale
NSString *currencyLocaleLanguage= [NSLocale canonicalLanguageIdentifierFromString: myCountryCode];
NSString *countryLanguage= [NSString stringWithFormat: #"%#_%#", myCountryCode, currencyLocaleLanguage];
NSLocale *currencyLocale = [[NSLocale alloc] initWithLocaleIdentifier: countryLanguage];
localCurrencySymbol = [currencyLocale objectForKey:NSLocaleCurrencySymbol];
currencyCode = [currencyLocale objectForKey:NSLocaleCurrencyCode];
title = [NSString stringWithFormat:#"%# %#: %# (%#)", myCountryCode, myCountryName, localCurrencySymbol, currencyCode];
[currencyLocale release];
[appLocale release];

Resources