MKReverseGeocoder; Can i get the location only in english? - mkreversegeocoder

Hi there
I am using corelocation in my app and everything works fine and well. Except that i would like to have mkreversecoder give me the location in english.
Some parts of my app are dependent on the location, where by, it grabs some data from the server based on the location. The problem here is mkreversecoder follows the phone's language when retrieving the country
So australia becomes 오스트 레일 리아
Is there anyway that i can force mkreversegeocoder to give me location only in english?
Thanks

For now i have chose this method
Grab the current language from standardDefaults
Set the language to English ( [[NSUserDefaults standardUserDefaults] setObject: [NSArray arrayWithObjects:#"en", nil] forKey:#"AppleLanguages"];)
Once the reverse geo coding is done, reset the language with the value grabbed in step 1
Is there any other sane way?

Related

iOS:How to get current application language

The application that I'm working on supports 3 languages: English, French and German.
How I can get the current application language (NOT the device language)?
The problem is that I have to get the current language of the application in order to send it with a request to the server and the respond should be in the right language. The device language is useless because if the user switch the os language to Italian, the app is running in English and I need to send english to the server.
Thanks
The accepted answer is a workaround.
Regarding language preferences in the device itself, you have the
[NSLocale preferredLanguages]
which will give you an ordered array of the preferred languages as defined in the system's General Settings.
The Cocoa Touch framework will take this list of preferred languages into account when loading the app's localization resources and filter it according to the translations you provide in the bundle.
This filtered and ordered list of localized languages can be obtained with
[[NSBundle mainBundle] preferredLocalizations]
Your server requests should match the first value in this array or you will have a language mismatch between app and server data.
What i always do:
Add a string entry into the Localizable.strings files.
I always use the key "lang"="de"; (or "lang"="en", etc.).
Then you can use it in your NSURLRequest by adding the language over NSLocalizedString(#"lang", #"")
With that method you have absolute control what is going to be sent to you backend.
You may use the preferredLocalizations method of the NSBundle class:
NSString *currentLocalization = [[[NSBundle mainBundle] preferredLocalizations] objectAtIndex:0];
Since iOS 13 the language can be set for each app individually.
In the session "Creating Great Localized Experiences with Xcode 11" at WWDC19 they showed two options for determining the user settings for the application.
Get the currently running application language:
Bundle.main.preferredLocalizations.first
Get the best language, given an external language code list:
let availableLanguages = Server.requestLanguages()
Bundle.preferredLocalizations(from: availableLanguages).first
The app language will change when the user change the device language and you can get it from the NSUserDefaults (i will show you how if you want to ) unless there are an option to change the language inside the app then you can easy save the current used language and send it to the server when ever you want.

Change an App Setting when updating the iPhone application to a new Version

I want to change the URL that my application connects to, to a new sever. The problem is, the URL value is saved in a settings file. When I update the application to the new version, the old file is read from the device, and overwrites my settings. What I want is to use the new URL the first time the updated version is launched. After that, I am happy to read the URL from the file.
Is there any way I can determine this is the first time after an update when I lauch the application?
Thanks!
As another user, you can get the current version by reading the CFBundleVersion of your app's bundle. The problem with this approach is that a user might not install "version 1" of your app. Instead, I suggest putting something like the following in your app's didFinishLaunching method:
#define kSettings [NSUserDefaults standardUserDefaults];
if(![kSettings objectforKey:#"isFirstRun"]){
// You could check the version here
// and do some initial setting up.
[kSettings setBool:NO forKey:#"isFirstRun"];
}
Then, for each subsequent version, you can add another if block with another flag to check for that version, like so:
if(![kSettings objectForKey:#"isFirstRunForVersionX"]){
// Do some version specific set up here.
[kSettings setBool:NO forKey:#"isFirstRunForVersionX"];
}
I've successfully used this approach in several of my apps.
To determine it it's the first launch after the update, you could retrieve the version number with this piece of code:
NSString* v = [[[NSBundle mainBundle] infoDictionary] objectForKey:#"CFBundleVersion"];
And compare it to a previous value you have saved.
You can store flag in NSUSerDefault. So You need to check first time if isFirstTime==0 then do your code and make isFirstTime=1; So it only runs first time.

Unable to read contact sort order in iOS (address book API seems broken)

I'm trying to use ABPersonGetCompositeNameFormat() to read the sort order settings for the user's address book. It always returns kABPersonCompositeNameFormatFirstNameFirst regardless of how I configure the "Display Order" preference in the Settings application. The Address Book application changes appropriately when the display order is set to "Last First" but the API call always returns the same value that represents the "First Last" display order. Has anybody else had this problem? I'm running this on an iPhone4 with iOS 4.3.3.
I've just found a solution - ABAddressBookRef has to be obtained (by ABAddressBookCreate) at least once before calling to ABPersonGetCompositeNameFormat(), but there are no mentions about it in the documentation.
ABRecordRef source = ABAddressBookCopyDefaultSource(addressBook);
people = (NSArray*)ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(addressBook, source, kABPersonSortByLastName);
It helps you.

Creating a localized iPhone app but allowing the user to change language for the application

I'm working on a localized app and everything is working fine. The problem is I want to allow the user to specifically select the lenguage for the specific app, in the app settings folder. This should users that their phone is set to one language (e.g. french) to set the app to work in English.
I'm currently using NSLocalizedString to get localized string but looking through all variation of the macro I can't find one that will let me specify the language.
Any ideas on how to do it?
There are three issues here:
Strings
Other resources (including NIBs)
System messages
The last is almost certainly not fixable, so we will leave it be. They're going to show up in the device language.
The other two are solvable, but you will need to do more things by hand. For strings, instead of creating a single Localizable.strings and then localizing it, create completely separate tables (English.strings, French.strings, etc.) Then, use NSLocalizedStringFromTable(), passing the language as the table.
For NIBs, there are two approaches. You can put each set of localized NIBs into its own Bundle and then pass that Bundle rather than nil to -initWithNibName:bundle:. Alternately, you can hand-load the NIBs after finding them with [NSBundle -pathForResource:ofType:inDirectory:forLocalization:].
There is a better way to do this. You can force the language like so:
[[NSUserDefaults standardUserDefaults] setObject: [NSArray arrayWithObjects:#"en", nil] forKey:#"AppleLanguages"];
And undo this setting by:
[[NSUserDefaults standardUserDefaults] removeObjectForKey:#"AppleLanguages"];
NB. you will normally have to restart the app for this to take affect.
Consider if you need to call [[NSUserDefaults standardUserDefaults] synchronize];
I agree there is little need to allow the user to specify a language. However the one exception is being able to override the language and set it to the developer's native language. If the user can speak the developer's language (e.g. English for me) then they may wish to use the App in that language, if the translations are incorrect.
I reference this answer: How to force NSLocalizedString to use a specific language (the answer doesn't actually work for me, but following the ideas in the comments did. The undo stuff I worked out.
The trick to use specific language by selecting it from the app is to force the NSLocalizedString to use specific bundle depending on the selected language ,
here is the post i have written for this http://learning-ios.blogspot.com/2011/04/advance-localization-in-ios-apps.html
and here is the code of one sample app https://github.com/object2dot0/Advance-Localization-in-ios-apps
The correct "User experience" is for the user to select their language via the system preference panel; not your app (or your app's settings panel, etc.). There is no way to override this per-app and we wouldn't want any app changing the system wide setting.

String value in Settings.bundle empty after update

For QA purposes I display our app's build version in the application' settings view as a PSTitleValueSpecifier. I set our app's current build number as the DefaultValue and I update it for every new build.
My problem is, whenever I deploy a new build of our application on a dev phone via Xcode, the version value doesn't update but remains with the previous build. The only way to update the version's value is to delete the app from the dev phone and then deploy the new build. Obviously, this approach does not please our QA department since they then loose all of their persisted data.
I have tried, cleaning the project, re-compiling and deploying but I get the same behavior.
Has anyone else experienced this issue? Any idea on how to work around it/fix it?
It is because this value is stored using NSUserDefaults which is stored on the disk and only removed when the app is removed. You can explicitly set it in code the same way you would any other user default. You could just create a field in your Info.plist that you change when you want to send a new build. Read that value from the plist on startup and then write it to your user defaults with:
NSString *value = [[NSBundle mainBundle] objectForInfoDictionaryKey:#"build_version"];
[[NSUserDefaults standardDefaults] setObject:value forKey#"build_version"];
[[NSUserDefaults standardDefaults] synchronize];
Of course, you replace "build_version" with whatever your key name is in your settings file. It's a hack, but it might satisfy your QA people.
For argument sake, it is actually reasonable to expect that you have to completely remove the previous version before seeing the version number update, however I realize not all QA people are reasonable. ;-)