iOS 13: How to obtain general device language? - ios

Prior to iOS 13 it was possible to call Locale.preferredLanguages.first to get general device language, but iOS 13 introduced app-specific languages. The problem is that if you select an app-specific language that doesn't match language in preferredLanguages then it will be pushed to the beginning of the array, but if you select the language that matches the language that contains in preferredLanguages then this language will stay on it place. So, starting with iOS 13 we cannot be really sure that the first language in preferredLanguages is indeed general device language and also the way that the array gets updated is really weird. I'm thinking about this problem for the entire day but cannot find the solution. Maybe someone knows the way to get general device language on iOS 13 device? Thanks

Related

App Store review rejected - app permission request language [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 9 months ago.
Improve this question
My application got rejected with the following reason -
Guideline 4 - Design
Your app's permissions requests are written in Ukrainian while the app is set to the Romanian localization. To help users understand why
your app is requesting access to a specific feature, your app's
permission requests should be in the same language as your app's
current localization.
The application is required to have both Romanian(Language A) and Ukrainian(Language B) localisation support. The application strings are localised in a usual way, nothing special - a Localizable.strings file with 2 languages support - A and B. It works well, no objections. When I change the app language from the iOS settings - all is good.
But, the issue arise(as Apple says) when I do an app permission alerts localisation. My application is using both camera and location(showing the embedded map view) permissions. To achieve this kind of localisation I'm using the all known approach of putting the InfoPlist.strings file in my app where it's basically just localising those 2 permission to an A and B languages.
/* Camera permission usage description */
"NSCameraUsageDescription" = "...";
/* Location permission usage description */
"NSLocationWhenInUseUsageDescription" = "...";
So, the behaviour now is that the app is getting localised with the language that is set in iOS settings for the app while the app permission alerts are getting their language as the iOS system preferred language. Means if I have an iOS device running on language A but set my application to run on language B, the app will actually run language B but those camera and location permission dialogs will be running on language A.
And I see no problems with that, it's obvious that the iOS is showing you those system alert on your preferred language. But now my app gets constantly rejected with the demand that the app permission alerts should also be running on the language B as the rest of the app.
So, how can I achieve this? Maybe I'm doing something wrong? Both localisation files seems to work since I'm able to reproduce the cases iOS - B, app - A and iOS - A, app - A.
Or maybe I'm just too stupid and misunderstood what Apple is trying to say? I can share the message history here if needed, but basically they are just saying:
Upon further review, we continue to find that the app's location
permission request is written in Ukrainian while the app is set to the
Romanian localization. Please note that your app's permission
requests should be in the same language as your app's current
localization.
Update:
Apple review reply on 03.05:
Spending even more time on investigation, trying and failing, we've managed to find a solution.
First of all, the Apple did a bad job explaining an issue fully. This is why it was leading me in a wrong directing. The issue supposed to be the following -
When you run an application in a language that is not present in your preferred languages list. In my case the app is in Romanian and device iOS language is set to English with no extra languages configured(Empty preferred languages list). This way the app will be in Romanian language and the camera permission alert is also in Romanian while location permission alert is in Ukrainian.
The fix was pretty easy with a single property in your Info.plist file that I'm seeing for the first time - CFBundleLocalizations where you basically just provide a list of languages your app supports.
Conclusion: The behaviour of system permission alert appearing in the iOS system preferred language is OK and works as supposed by Apple. But there might be a case when none of the app supported languages is present in the iOS system preferred languages list and it leads to multiple languages appearing in the app during runtime and this might be a potential Apple review reject reason.

Xcode 11 test plans don't seem to localize the simulator status bar

I use Xcode 11 test plans new feature to generate my localized screenshots for the app store. As explained during the WWDC19 you can use test plan configurations to play your UI tests generating screenshots in several languages.
Unfortunately it seems that it only specifies the languages and regions for the app, and not simulator-based.
For instance, when you use this configuration:
The problem appears especially on iPad when the status bar displays the date:
So if someone knows how to force the simulator to update its language for each configuration, I would be grateful.
PS: I used to work with fastlane/snapshot but test plans are much more efficient (5 minutes generation instead of more than 40 with fastlane) so I'd rather not go back to fastlane if I can do otherwise.
It seems that it's as simple as adding this to the setup:
app.launchArguments += ProcessInfo().arguments

Is dynamic language change in iOS app allowed?

Is dynamic language change in iOS app allowed? Normally the language is set basing on the device's language. But if I add settings in my app that would allow changing the language without changing the language of the device, will my app be rejected by Apple?
Many apps (mostly games) does it. Your app shouldn't get rejected, but it's not so welcomed by the users. It's generally much better to have the language setting handled by the system. It's much more convenient for the end user. I was trying to find anything in Apple Guidelines but didn't notice anything interesting on the topic.

AVSpeechSynthesizer voices on iOS 8

Is anyone else unable to use the AVSpeechSynthesizer with a voice other than "en-US"? The array that gets returned when I call AVSpeechSynthesisVoice speechVoices still returns the complete list that can be seen in iOS 7, but none of them actually work.
I tried looking through the known issues on the iOS 8 release notes, but didn't see anything about this. Hopefully this is something that will be fixed in the full version, as I have a couple apps that make use of multiple voices.
IMHO, this is a bug in iOS8, even for GM.
I was playing with this project: https://github.com/mattt/AVSpeechSynthesizer-Example
My findings are:
1) iOS 8 did not speak in any simulator (XCode 6GM, XCode 6.1b2). It did speak only on real device.
2 ) iOS 8 did speak in language of phone (Russian in my case) and English (en-US). When i did change Language of a phone to german, i can hear German and English TTS. Adding German as one of languages in preffered language list did not help, you should set language as phone language. For unknow reasons Russian did work even if it was not phone language, but not same for German - it was working only if it was set as a phone language. Maybe real location matters (I am in Russia). For sure: iOS8 did "optimize" TTS engines some way, so not all of them are ok to use.
3) some folks noticed another bug in iOS 8: first attempt to use AVSpeechSynthesizer produces silence. See workaround here.
This problem appears to have been fixed in iOS 8.1.

Updating app for iOS 8

I have an application whose minimum version has been set to iOS 7.0. This application also uses NSUserDefaults dictionary. This application is using UIAlertView and UIActionSheet extensively (not sure how much Apple non-disclosure covers). Now, with iOS 8.0, these two views have been deprecated and have been replaced by controller UIAlertController. Now, there are two ways that I can see which can help me in updating the app for iOS 8.
Raise the minimum version to iOS 8.0 for the update. This way, the users running iOS 7.0 won't be able to see the update. However, it leads to the following situation :-
However, there is one problematic case, and that comes from upgrades
performed from within iTunes or on a device with a higher version
number that is then synced to iTunes. When the user syncs the older
device with iTunes, iTunes will actually delete the application from
the device because it cannot run the new version currently within
iTunes. I had a couple of users with original iPod touches report this
when I upgraded one of my applications to only support 4.0.
The above comment is present under the accepted answer at the following url :-
Raising minimum iOS Deployment Target Version for App Update
Since, the application is using NSUserDefaults dictionary, the relevant entries in the dictionary would get erased when the application is deleted.
The other option is for me to detect in the code which version is being used and code accordingly using if-else statements. This would enable me to keep the iOS 7.0 as the minimum version and might also help me in deploying the update for iOS 8.0. However, this seems like a lot of work which can potentially lead to bugs.
So, I was wondering which option is better between the above 2 ways ? (This application would only be using Objective-C for now due to some constraints).
The best thing to do from the user's perspective is probably to code using UIAlertView and UIActionSheet even though they're deprecated. Keep your iOS 7 target the same as it's been. Xcode shouldn't give you warnings since you're using the older version as your base target. You won't need to change anything about your code and it should still work well enough.
Once you're ready to switch (perhaps when iOS 9 comes out), I would switch your base target to iOS 8 and update your code to use UIAlertController everywhere. To me, it doesn't make sense to spend time trying to support two different versions if it's just an API deprecation that still allows your code to work how you've written it for years. Saves resources and energy to just update it later.
But it's really up to you and how much you want to support iOS 7. I think it doesn't make sense to drop support until the next version comes out. I always try to support the current and last versions so there are no annoyed customers, but it depends on your own needs.
If you have analytics integrated, check out percentage of iOS 8 adoption once it's been released for the public. If not, it's a great opportunity to add it to find out how up to date your customers are!

Resources