Interface language in MFMessageComposeViewController - objective-c

I'm trying to send sms from my iphone using MFMessageComposeViewController. It shows a modal dialog with filled fields. everything work, but I want to show dialog in Russian Language.
I want to see all values (such as "New message", "send", etc) in Russian.
I'v checked default language:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSArray *languages = [defaults objectForKey:#"AppleLanguages"];
NSString *currentLanguage = [languages objectAtIndex:0];
NSLog(#"Current Locale: %#", [[NSLocale currentLocale] localeIdentifier]);
NSLog(#"Current language: %#", currentLanguage);
And it returns, that language is ru-RU.
How can I set a lang for this dialog?

You need to localize your app for Russian in order for it to show the localized controls you ask for.
All you should need to do is add a ru.lproj folder to your project (you could include here a Localizable.strings file if needed by your app) to let know Xcode that you are actively supporting that language.
For every language you add as language-code.lproj, every native control (MFMessageComposeViewController, MFMailComposeViewController) should consider using that language if set as local on the device.

Related

How to Change Xcode development region to print localized string using NSLog

Documentation of operatingSystemVersionString method of NSProcessInfo says "The operating system version string is human readable, localized, and is appropriate for displaying to the user. This string is not appropriate for parsing."
NSString *versionString = [[NSProcessInfo processInfo] operatingSystemVersionString];
NSLog(#"%#",versionString);
I want to check what it will return in case of other languages like China, French. I changed region and language but NSLog always prints in english language.What settings I should change in Xcode and System Preferences to check the behavior of operatingSystemVersionString based on region and language? Or NSLog prints in English only?
https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSProcessInfo_Class/index.html#//apple_ref/occ/instp/NSProcessInfo/operatingSystemVersionString
You can try adding these lines in the main.m file
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:#"en", nil] forKey:#"AppleLanguages"];
[[NSUserDefaults standardUserDefaults] synchronize];
Just change the 2 letter prefix (#"en") to any language you need.

Text Replace Service with Xcode - Not replacing selected text

I am trying to build a standalone system service (app with .service extension, saved to ~/Library/Services/) to replace user-selected text in Mac OS X.
I want to build it with Xcode and not Automator, because I am more accustomed to Objective-C than Applescript.
I found several examples on the internet, e.g. this and also Apple's documentation. I got the Xcode project appropriately configured and building without problems. However, when I install my service and try to use it, nothing happens.
The service method itself is executed: I placed code to show an NSAlert inside its method body and it shows. However, the selected text does not get replaced.
Any idea what might be missing? This is the method that implements the service:
- (void) fixPath:(NSPasteboard*) pboard
userData:(NSString*) userData
error:(NSString**) error
{
// Make sure the pasteboard contains a string.
if (![pboard canReadObjectForClasses:#[[NSString class]] options:#{}])
{
*error = NSLocalizedString(#"Error: the pasteboard doesn't contain a string.", nil);
return;
}
NSString* pasteboardString = [pboard stringForType:NSPasteboardTypeString];
//NSAlert* alert = [[NSAlert alloc] init];
//[alert setMessageText:#"WORKING!"];
//[alert runModal];
// ^ This alert is displayed when selecting the service in the context menu
pasteboardString = #"NEW TEXT";
NSArray* types = [NSArray arrayWithObject:NSStringPboardType];
[pboard clearContents];
[pboard declareTypes:types owner:nil];
// Set new text:
[pboard writeObjects:[NSArray arrayWithObject:pasteboardString]];
// Alternatively:
[pboard setString:pasteboardString forType:NSStringPboardType];
// (neither works)
return;
}
After careful reading of Apple's documentation, I found the answer: My service app's plist file was missing a key under the Services section:
<key>NSReturnTypes</key>
<array>
<string>NSStringPboardType</string>
</array>
I only had the opposite NSSendTypes key, which lets you send data from the client app to the service. This one is needed to send the modified text back (in the other direction).
It is weird because, Apple's documentation seems to imply that specifying these two is no longer necessary since 10.6 (Snow Leopard).
For (hopefully) useful console spew, in terminal type:
defaults write -g ViewBridgeLogging -bool YES
Note: useful for services and extensions also.

Xcode localization

I have a question on how to set the default language in an Xcode project.
My Mac OS X App supports German and English.
Everytime English is not selected in Systemsettings, default language is German.
I want to switch default language to English, so that non-german users get an English UI.
Changing "Localization native development region" in Plist file to English didn't solve the problem.
I tried to do it within the code but this is not what Apple recommends in their HIGs.
Sampleproject is hosted on Github.
https://github.com/christian123456/xcodelocalization
Xcode Version is 5.1.1
I recently added the screenshots to the repository. As you can see in the "german incorrect.png" screenshot, French and Portuguese languages are chosen but Mac OS picked German as language. I want the language to be English.
Testing and analyzing
I've added -NSShowNonLocalizedStrings YES into scheme-editor > Run .app > Arguments > Arugments Passed On Launch. This turns any string it cannot find a localized variant for into uppercase.
The result is, I see all uppercase.
To switch language for developing use -AppleLanguages (it).
As result, the en localization appears.
To switch the language of an app, you can also use the following app:
https://itunes.apple.com/de/app/app-language-chooser/id451732904?l=en&mt=12
For more information read here.
Solution
After a little searching and testing, I found this solution:
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:#"en", #"de", nil] forKey:#"AppleLanguages"];
[[NSUserDefaults standardUserDefaults] synchronize];
This would set the language english as default.
Another option is to create your own localization class. Call your class, and it can force localization into any language you want:
- (NSString*) MyLocalizedString:(NSString*) label;
{
NSUserDefaults* defs = [NSUserDefaults standardUserDefaults];
NSString* preferredLanguage = [defs objectForKey:#"LocalizedLanguage"];
NSString *path = [[NSBundle mainBundle] pathForResource:preferredLanguage ofType:#"lproj"];
NSBundle* languageBundle = [NSBundle bundleWithPath:path];
NSString *result = [NSString stringWithFormat:#"%#",[languageBundle localizedStringForKey:label value:#"" table:nil]];
return(result);
}
- (NSLocale *) forceEnglishLocalization;
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:#"en" forKey:#"LocalizedLanguage"];
NSLocale * currentLocale;
currentLocale = [[NSLocale alloc] initWithLocaleIdentifier:#"en"];
return(currentLocale);
}
Need help localizing your Xcode apps?
https://itunes.apple.com/mg/app/generate-localizable-strings/id890673579?mt=12

Get ios multi-value user preferences

I try to retrieve the value selected in Settings Application using "Settings Bundle". The field is "PSMultiValueSpecifier". In "Root.plist" I implemented:
Type: PSMultiValueSpecifier
Title: Abcdefg
Key: abcdefg
DefaultValue: aaa
Values (array):
Item 0: aaa
Item 1: bbb
Titles (array):
Item 0: A
Item 1: B
And, In the implement file I have wrote:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *string = [defaults objectForKey:#"abcdefg"];
But "string" is empty. When I do the same with a user default of kind: "PSTextFieldSpecifier" I can retrieve the value.
I follow the instructions explained in the book "Apress - Beginning iOS 5 Development: Exploring the iOS SDK" but I can not retrieve the value selected.
Instructions are the same of the "Apple Development Help".
I do not understand what is the problem. It seems easy.
I have found the bug.
If you implement "Multi Value" user preferences in "Settings.bundle" (with its "Default Value"), but never enter in settings iPhone simulator and never change the multi-value preference, the sentence:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *string = [defaults objectForKey:#"key"];
Returns a "nil" value. Incredible, I lost a week trying to find the problem!!!!
But I have a doubt:
If I implement a "Multi Value" user preferences and I publish the App in iTunes Store, but user not use this "Multi Value" user preferences, "NSUserDefaults" will return nill value?
Do I have to consider the possibility of receiving an empty value?
Really, I think it is ridiculous.
It seems that DefaultValue is used only in the official Settings app. Apparently, you have to register the defaults by 1) testing one of your settings to see if it's NULL, then 2) iterating through the settings, grabbing and setting the defaults:
sample Obj-C code for this by just.do.it
The documentation on PSMultiValueSpecifier does seem deficient here. Confusion on this shows up all over SO and the web. For example:
defaultvalue-for-psmultivaluespecifier on SO
app-preferences-how-to-get-psmultivaluespecifier-property on SO
No, I think you need to register your default value, for example in:
-(BOOL) application: (UIApplication*) application didFinishLaunchingWithOptions: (NSDictionary*) launchOptions
{
NSDictionary* defaults = #{#"key": #"default value"};
[[NSUserDefaults standardUserDefaults] registerDefaults:defaults];
}
This is because the app knows nothing about the settings bundle it contains. The page 430 of book Beginning iOS6 Development: Exploring the iOS SDK has a clear explanation of this.
if the returned object is nil then set the default value.
NSString * key = #"the key";
NSUserDefaults * uD = [NSUserDefaults standardUserDefaults];
NSString * stringValue = [uD objectForKey:key];
if (!stringValue) {
stringValue = #"the default value";
[uD registerDefaults:#{key: stringValue}];
}

Get list of installed apps on iPhone

Is there a way (some API) to get the list of installed apps on an iPhone device.
While searching for similar questions, I found some thing related to url registration, but I think there must be some API to do this, as I don't want to do any thing with the app, I just want the list.
No, apps are sandboxed and Apple-accepted APIs do not include anything that would let you do that.
You can, however, test whether a certain app is installed:
if the app is known to handle URLs of a certain type
by using [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:#"thisapp://foo"]
You can get a list of apps and URL schemes from here.
For jailbroken devices you can use next snipped of code:
-(void)appInstalledList
{
static NSString* const path = #"/private/var/mobile/Library/Caches/com.apple.mobile.installation.plist";
NSDictionary *cacheDict = nil;
BOOL isDir = NO;
if ([[NSFileManager defaultManager] fileExistsAtPath: path isDirectory: &isDir] && !isDir)
{
cacheDict = [NSDictionary dictionaryWithContentsOfFile: path];
NSDictionary *system = [cacheDict objectForKey: #"System"]; // First check all system (jailbroken) apps
for (NSString *key in system)
{
NSLog(#"%#",key);
}
NSDictionary *user = [cacheDict objectForKey: #"User"]; // Then all the user (App Store /var/mobile/Applications) apps
for (NSString *key in user)
{
NSLog(#"%#",key);
}
return;
}
NSLog(#"can not find installed app plist");
}
for non jailbroken device, we can use third party framework which is called "ihaspp", also its free and apple accepted. Also they given good documentation how to integrate and how to use. May be this would be helpful to you. Good luck!!
https://github.com/danielamitay/iHasApp
You could do this by using the following:
Class LSApplicationWorkspace_class = objc_getClass("LSApplicationWorkspace");
SEL selector = NSSelectorFromString(#"defaultWorkspace");
NSObject* workspace = [LSApplicationWorkspace_class performSelector:selector];
SEL selectorALL = NSSelectorFromString(#"allApplications");
NSMutableArray *Allapps = [workspace performSelector:selectorALL];
NSLog(#"apps: %#", Allapps);
And then by accessing each element and splitting it you can get your app name, and even the Bundle Identifier, too.
Well, not sure if this was available back when the last answer was given or not (Prior to iOS 6)
Also this one is time intensive, yet simple:
Go into settings > Gen. >usage. The first category under usage at least right now is Storage.
It will show a partial list of apps. At the bottom of this partial list is a button that says "show all apps".
Tap that and you'll have to go through screen by screen, and take screenshots (Quick lock button and home button takes a screenshot).
I'm doing this now and I have hundreds of apps on my iPhone. So it's going to take me a while. But at least at the end of the process I'll have Images of all my apps.