Change language in app - how to restart? - iphone

I want to give the user the possibility to change the language in my app.
The way to do this is described here, in monotouch code to set the preferred language to Dutch and alternate language to English:
NSUserDefaults.StandardUserDefaults.SetValueForKey
(NSArray.FromStrings("nl", "en"), new NSString("AppleLanguages"));
You have to restart the application before this will take effect. But on the iPhone 4 the app does not restart when you close it, it is just hidden. Is there a way to force an app to restart after closing?

Thanks Dimitris. So changing the language at runtime is not that simple.
I found a solution which works in my case:
When the user changes the language I use the solution described by Mauro Delrio in "How to force NSLocalizedString to use a specific language". In monotouch:
string newLanguage = "nl";
myBundle = NSBundle.FromPath(NSBundle.MainBundle.PathForResource(newLanguage, "lproj"));
All strings will now be loaded in the selected language with myBundle.LocalizedString(...). Of course, everything which was already printed on a view is not yet translated. But I found an easy way to reset all views. In my app I use a MainTabController which looks like this:
public class MainTabBarController : UITabBarController
{
public override void ViewDidLoad()
{
Reset();
SelectedIndex = 2;
}
public void Reset()
{
ViewControllers = new UIViewController[]
{
new ViewControllerTab1(),
new ViewControllerTab2(),
new ViewControllerTab3(),
new ViewControllerTab4(),
new ViewControllerTab5()
};
}
}
So all I have to do is call Reset like:
((AppDelegate)UIApplication.SharedApplication.Delegate).MainTabBarController.Reset();
All current views are disposed and re-created in the correct language. Seems like a trick, but it is perfectly legal and documented, see Apple documentation for MainTabBarController viewControllers property. It even activates the same tab index as the one which was active, so for the user it seems that nothing but the language is changed.
Of course, any unsaved data in all views is lost, so if this is a problem, you have to find a way to save this before resetting.

No there is no way to restart an app. You can only force it to terminate when the users presses the home button by setting the property "UIApplicationExitsOnSuspend" in your Info.plist file to true.

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

As an additional note, to force the UIBarButtonSystemItem to change their locale, you have to add
<key>CFBundleDevelopmentRegion</key>
<string>nl</string>
to your info.plist. Just fire up TextEdit and place it somewhere. Hope this helps!

Related

Xcode 8.2.1 not showing documentation description on autocomplete

I'm having problems adding documentation to my code in Xcode 8.2.1.
Here's my code:
/// Test documentation method
///
/// - Parameter string: The input string
/// - Returns: The output bool
func testMethod(string:String) -> Bool {
if string == "YES" {
return true
}
return false
}
The documentation shows as expected in the quick help window but the description doesn't show in the code autocomplete window.
Is there a way to get the description to show in the autocomplete box as in the image below:
You are right, the descriptions you added to the top of your methods and properties don't appear in the popover anymore.
As noted, you can only see the descriptions of Apple's own methods and properties.
The reason being that Xcode doesn't parse these from their classes but rather from a separate documentation set (which you can find in Xcode's Help/Documentation and API reference tab).
So unless Apple decides to change this, I'm afraid it won't be possible to see your own in the popover.
You could keep an eye on existing doc set generators (AppleDoc, Jazzy), maybe they'll offer a way to link their documentation to Xcode's popover.
Keep in mind that you do see your own comments when opening the quick help popover with alt + click on a method or property.
For me the best way to resolve this is by cleaning the project Shift+Command+K, and if that is not working, it is a god idea to remove Derived Data folder.
To remove this folder go to Xcode preferences, Locations tab
and click on the small arrow to open a finder, and remove manually the folder.
Restart Xcode, and check if now is working
https://developer.apple.com/library/content/documentation/Xcode/Reference/xcode_markup_formatting_ref/MarkupFunctionality.html#//apple_ref/doc/uid/TP40016497-CH54-SW1
please refer the official documentation

How to simulate the very first start of an app in Xcode 6

I need to test some behaviors of the iOS 8 at the very first start of my app. Is it possible to simulate this in Xcode 6? If yes, then how?
Deleting the app will do it but note that certain pieces of information will be cached for a while like your permissions settings (notification, calendar, etc.). You can go to settings.app and reset settings to clear those out if that matters in your use case.
If you mean the FIRST start of the app, then what I did to achive this is, on start (viewDidLoad) check in the NSUserDefaults for example ,if the value "hasAlreadyStarted" exists (NSUserDefaults.objectForKey(..) ), if not, then its the first start of the app, and then i would set the value to true, so when you close the app, and open again, the value will exist.
Dareon I'm not sure what exactly you want to achieve. In Xcode 6 yes you can simulate your app from start. If you want to test behaviours I think you are looking for instruments. Right Click on the Xcode icon in your dock select option and choose instruments. You can add several instruments your phone or emulator support like connectivity or gps or memory to see exactly the behaviour of your app. Hope that helps
Well if by very start of the app cycle you mean before the app loads, there is a way.
In your ViewController call the ViewWillLoad function:
class ViewController
{
override func viewWillAppear(animated: Bool)
{
// your code
}
}
This event will be called before the view loads or appears.
Hope it helps :)
As Shanti K said in the comment, if you delete your application from the simulator and then run it again, you will be simulating the first run. To delete the application from the simulator, you mimic the same behavior on a device.
Click and hold on the icon, until they start shaking. Click the close X next to your application, and verify that you want to delete it if it asks. Then Shift + Command + H to simulate hitting the home button.

How to check if any apps are associated with file extension

I want to make "Open in.." function in my iOS application.
Is there any way to check if any app on this device is associated with file extension that i want to share?
If there are no apps on current device to open file with such an extension than UIDocumentInteractionController will not be displayed after clicking on "Open in.." button, but i want not to show this button in such case.
So the question is: how to check if any app on device can open some file with specific extension?
Update:
For example UIDocumentInteractionController has NSArray property icons.
It contains images of all aplications that can open the file with my extension. But if there are no applications it contans image of empty application.
So i can't check it using docInteractionController.icons.count == 0 for example. I am looking for other tricks.'
Thanks, in advance.
Although UIDocumentInteractionController does not offer a way to discover in advance whether there are any applications that can handle a document, -presentOpenInMenuFromRect: will return a flag indicating whether there were any applications that could open a document. This requires you to have already set up and presented the controller, which is not optimal.
There is a workaround for this, a little hacky but is functional: Before you invoke the "real" interaction controller, create a dummy one using a dummy document, and present it from the rect of the window's bounds. This guarantees that it will "appear" offscreen, so your user won't see it. At that point, you have the flag returned from -present, and you can immediately dismiss the dummy controller, and the proceed to show your UI appropriately.
On OSX, you can get a list of application bundle identifiers capable of handling a specific content type using LSCopyAllRoleHandlersForContentType. But on iOS, I don't think there is such a way.
If I find, I'll edit my answer.
Considering you are looking for other tricks, you can check if that one image in the icons array is the generic document icon.
If it is then you know that there is no app associated to handle that file type. But this approach will be OS version dependent as generic file icon may change.
From the official documentation:
To declare its support for file types, your app must include the
CFBundleDocumentTypes key in its Info.plistproperty list file. (See
“Core Foundation Keys”.) The system adds this information to a
registry that other apps can access through a document interaction
controller.
To me this indicates that the registry can only be accessed through UIDocumentInteractionController and so no, you would not be able to know in advance if there are any available apps for the file format (which would be totally in line with Apple's philosophy of not letting apps interact directly with each other).
UPDATE:
as you said the icons property contains an image even with no applications present. I checked and all the other methods and properties of the controller do not give an hint about the apps that may open the current file format.
You said in case that no app can open the specified file format there is an "image of empty application". Maybe you can extract that icon and when the array icons only has one image check if the extracted image and the icon are the same?

iPhone application preferences

I've been doing some research and so far I've been unable to find out how to display a Settings.bundle inside an application. The guides that I found are:
http://developer.apple.com/library/ios/#documentation/iphone/conceptual/iphoneosprogrammingguide/Preferences/Preferences.html
http://blog.webscale.co.in/?p=274
http://knol.google.com/k/iphone-sdk-application-preferences#
These all seem to skip a step: How to display the plist from a view in your application. I've got my view set up and my plist file set up, but I have no idea how to display the preferences plist from the view. Do I manually load everything and put them into labels, switches and whatnot?
This may seem like a stupid question but I honestly don't know. Would anyone be able to explain this to me?
Thanks in advance
EDIT: To clarify; I've found out that this allows me to access the preferences through the settings app. However I want to access these through a tab in the app itself.
http://knol.google.com/k/iphone-sdk-application-preferences#Step_4(3A)_Retrieving_Values_of_Settings appears to describe exactly how to access these...
It's a one-liner so i'll paste it here:
NSString* settingValue = [[NSUserDefaults standardUserDefaults] stringForKey:#"<Setting Key>"]
There's no magical setting key that you have to use. Use whatever you like, and it'll be there the next time the application loads.
I got the same problem; I have an application with a tabBarController as the RootController of my application and, separately, I have a settings menu (loaded from plist) available through the applications preferences of the device.
I do want to include this settings menu into my app as an other view for my tabBarController in order to avoid to have to exit my application to change the settings.
Finally, I have the plist file ready, I just want to know a way to do something like
[C#]
settingsController.View = UIView.LoadFromPList("settings.plist");
tabBarController.addController(settingsController);
... anybody knows ?

Eclipse - Blackberry SDK - Debugging on device: "details unavailable - not supported by VM"

I'm having a strange problem while debugging my Blackberry Application on a real device (BB Bold 9700). When I debug the same application within the BB emulator, the app runs fine, but when I run it on the real device, the app behaves differently (custom painting goes completely wrong). What's even worse is that my Eclipse environment seems to be unable to view live objects correctly while being at a break point (debug time).
I've added a screenshot to illustrate the strange behaviour:
As you can see, the app stops at the breakpoint within the IF statement, but the Variables pane says that the variable "methodName" equals null. Moreover, when I want to look at the variable "methodArguments" which is of type org.json.me.JSONArray, it says "details unavailable - not supported by VM".
Does anyone know what's going on here? My app works great on the emulator, but it's currently useless on the real device.
Thanks in advance!
I think I fixed it:
The problem was that I was laying out Fields on a manager that wasn't yet added to the viewstack.
What did the trick for me was overriding onDisplay() in the manager that contained the Fields that were displayed wrong:
protected void onDisplay()
{
//Make sure superclass is called
super.onDisplay();
/*You have to call "this.setDirty(true)" when you perform layout on a
*manager that isn't added to the viewstack. Then you can use
*"this.isDirty()" to determine whether you need to re-layout the fields
*when the manager becomes visible.*/
if(this.isDirty())
{
//I'm not sure if I need to use "invokeAndWait" and not "invokeLater"
UiApplication.getUiApplication().invokeAndWait(new Runnable()
{
public void run()
{
for (int i = 0; i < getFieldCount(); i++)
{
/*This (custom) function makes sure the Field gets its
*size and position*/
layoutItem(getField(i));
}
}
});
//Make sure you set "dirty" to false, to make sure this only happens once
this.setDirty(false);
}
}
If anyone has a better solution, I'd be glad to hear it (and maybe improve my app).
org.json.me.JSONArray, it says "details unavailable - not supported by VM".
the JSON related stuff is not available on device running 4.5 and 4.6 BB OS. Import it into the code.
Download it from here.
https://github.com/douglascrockford/JSON-java
it is available as Open Source and then use it into your applications.