Loading wrong xib after updating the app - iphone

I already have my app on the App Store and I want to publish a new internationalized version. So, I created a xib for the english version and a xib for the french one (localized in the good en.lproj and fr.lproj folders). And when I set up the app on my iPhone that already have the first no-internationalized version, I had some troubles with the interface : the app does not update all the changes on the UI and I still have french labels even if I set the iPhone language to English (the app does not choose automatically the good xib).
If I only clean the project and build again, it still does not work but when I cleaned my project, deleted the app of the phone and build again, everything works like a charm. I don't want that the problem occurs to people who already have the app and update it via the App Store :/ is there a way to understand what happens ?

This is what happens: In your old version, you have one .xib file in the application bundle, and the bundle looks like this:
<bundle-path>/interface.xib
In the new version you have the two localized versions of this file and your bundle looks like this:
<bundle-path>/fr.lproj/interface.xib
<bundle-path>/en.lproj/interface.xib
When the app tries to load the xib file it looks directly in the bundle directory first and, if it doesn't find the file there, looks for the file in the subdirectories with the localized files.
If you have the old version on the device and then build and run the new version from Xcode, legacy files are not deleted, so you end up with this bundle
<bundle-path>/interface.xib
<bundle-path>/fr.lproj/interface.xib
<bundle-path>/en.lproj/interface.xib
and the app loads the unlocalized file as it never needs to look into the localization subdirectories.
I assume that legacy files are not deleted when you deploy from Xcode to a development device for performance reasons.
However, your users will not run into this problem. When a user installs an update of your app, the app bundle will be completely replaced by your new bundle. So if you upload a "clean" bundle without legacy files, and this version works when you do a fresh install on a your device, it will also work on your users' devices.

Related

iPhone app Update Vs new version

Let's say I have an existing IOS app live on Appstore which is version 1.0
Now I make some changes to the app and want to submit back.
Are there 2 separate ways to submit ?
Like can I still keep the version as 1.0 and just submit the app OR
I need to create a new version 1.1 and then submit it ?
What are the differences in the process?
Also from the customer end, how does this work for new/existing users ?
I have just discovered something about version upgrades and the App Store. Just now, I'm suffering issues and users crashes because of a behavior of iOS system that I can't figure before. And, very important, iTunes, AppStore and iOS have modified some upgrading and installing rules in last versions. Now, it works this way:
- When user install a new version, all the files in the bundle are downloaded and copied in the previous existing bundle, but OLD FILES OR COMPONENTS ARE NOT DELETED (or not all are deleted). So, the final bundle IS NOT equal to the bundle of a fresh installation of the new version.
- For example, if a xib/nib file is localized to different languages for the new version, the updated bundle will include both versions: the one in the root folder and the other one in each localized folder. The system, obviously, will use the first one and only a fresh installation will show localizations for that file.
One of my apps shows that issue with MainWindow.xib and as there are some modifications in references and classes, the updated apps crash each time you try to run as it is using a obsolet object. I have built a new version changing the name of the xib/nib files that have been localized. As MainWindow is one of them, I have to modify the reference in info.plist of course.
OK, knowing that, you can build a new version with complete different components in the bundle that, if files of previous version does exist, the app then offers the user the option of using them. That is, two versions of the app in a single icon and bundle. Not very difficult to do.
BUT, the very weird thing is that I think that new iOS version and iTunes don't allow downgrades. I have tried to do it but didn't get it done. That is, if you install a version, for example 1.2, it is impossible AFAIK to install latter v1.1 on the device nor in iTunes->"Applications". So, the double version bundle will live until a reinstallation of the app.
You need to create a new version number, which makes sense since this is a new version of your app. This will then appear as an update for your customers. I don't think you can upload a new binary with the same version without removing the old one from the store.
You add a new version in iTunes connect, then update the version number in Xcode to match and create a new archive. It's pretty straightforward.
You must always increase the version number of any update to your app.
Users will see a badge on the App Store icon on the device, and in iTunes on their PC. Going into the updates section, it will list your app along with the list of changes you've provided, and a button to install the update. They can also update all apps at once.
NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:#"CFBundleVersion"];
NSLog(#"version is%#",version);
You do not have to open version numbers to submit any longer. Open up Xcode, go to Window - Organizer - Archives and Distribute an app you have created successfully.

Adding localizable files to project on Xcode 4

I'm developing an App that needs Localization.
I've followed these steps:
I've created the es.lproj, it.lproj, en.lproj folders in the root of the project with finder.
I've created the Localizable.strings file in each folder with the key pair values corresponding to the target language.
I've imported with Add Files To option from Xcode.
When I test the App in the iphone simulator all works fine. I configure the iphone to any localizaed language and the app is translated properly.
But when I run the App in the device, only shows the strings in english.
I've made a test following these steps.
From Xcode 4 right button over Supporting Files Folder, New File.
Create Localizable.strings file
In file inspector, section Localization. I've added the rest of languages. Creating the file like a folder with all Localizable files in the tree.
In the root folder of the project, the xcode created a folder for each language.
After editing every file, I've executed in simulator and all works fine. I've tested in 3 different devices and the only language is English.
In the Project -> Info -> localization I've added every language.
In the Build Phases I've observed that only is referenced the Localizable.string file in the en.lproj folder. I've tried to add the rest of files, but only accepts one more Localizable file. I've tested in device with the "extra" added language but doesn't works.
Can someone help me please?
Thanks in advance.
Try this: Remove the app from the device, clean project, make sure that the files appear in Build Phases>Copy Bundle Resources and run again.
Are you sure you are testing properly on your device ? I just tried making a simple localization test, just a Hello world in different languages, and when i
I used Xcode 4 and followed the same steps as you. Changed my device language, reloaded the app, and there it was.
You might need to do a clean install in order for this to work. Do the clean install after you changed your device language to "something you haven't seen yet" ;]
Maybe this tutorial can help you : Localization Tutorial with XCode
Have you tried to delete the app from the device and then reinstalling?
EDIT: I have checked in a project of mine and the names I see are: English.lproj, French.lproj, etc.
Don't know if this could make a difference, but you could try it. Also, you can go to the app binary for the iPhone with the Finder and select Show package content to inspect its content and make sure the localization files are there This could help to pin down the problem...
If it can be run in the simulator ok, but the device has a problem with the localization, then the link provided here by Nils Munch has the answer. In troubleshooting it says "Unlike the iPhone simulator, the iPhone only recognizes strings files that are formatted UTF-16. Always test your localizations on the device, as the simulator and the device do not always behave the same way."
I think the problem here might be the file is UTF-8. The simulator can handle that but the device can't.

Why isn't my iPhone app bundle replacing the old one during an update?

I'm starting with an app that has foo.png as a resource, and the app is installed (either in the simulator or on the device). If I delete foo.png, do a clean build, etc., and install, then it still shows up in the bundle on the simulator or device!
But I know the file isn't in the bundle before copying to the simulator or device (for example:
I can see it's not there in the build folder.
If I delete the app from the simulator or device, and then install, then foo.png doesn't show up on the simulator or device.
So it seems that when updating, it doesn't replace the app bundle; instead, it only copies new files and replaces updated ones. (I can confirm that it does, in fact, copy and replace files properly.)
Why isn't it replacing the entire app bundle?
If you update your application through iTunes using an ad hoc build you will see that your .app bundle will be replaced completely and old resources, such as the foo.png file described in the original post will be removed.
Reset the simulator, go up to the menu and then click reset simulator. I always have that problem with databases on the device. You will have to delete it on the device. Just a quirk that I've experienced as well.

iphone app upgrade and moved xibs/nibs leads to stale resources

I have an unlocalized shipping app which has foo.xib in the main project directory. In preparation for localization, I moved this to en.lproj/foo.xib. Now, when I build my app and install on my test device, it ends up using the stale old foo.nib which must be there from before (the installation process must not remove old files in the app's bundle). Deleting the app from the test device and re-installing fixes it -- but I don't want my existing customers to have to do that.
Some of these are coming from calls to UIViewController's -initWithNibName:bundle method (to which I'm currently passing nil for the nibBundle). I can probably create an NSBundle instance here which points at the correct localized directory. The others are specified in Info.plist or in the "NIB Name" section in interface builder and I don't see a way to specify a bundle for those.
It might just be easier to rename all my xibs to (e.g.) en.lproj/newfoo.xib, then I presume it will find the correct nib at runtime. (And I'll have to remember to never again use the old "foo.xib" name in a new version.) Is there a more clever solution here though? (Other than going back in time and starting with en.lproj directories from the beginning ;-)
Thanks!
-Mike
Answering my own question in case anyone else runs into this issue. It appears that this is an artifact of the Xcode build-publish cycle, and it isn't a problem when user's upgrade via the App Store. I went ahead and published my update and no one has noticed problems that would result from stale resources.
As a speedup to development, it appears that Xcode only copies over resources that it detects have changed when you build and install to the simulator or a test device. (To prevent a game with 500MB of resources from having to be re-copied each and every time you build and test.) When you (re)move a resource from a project though, it does not detect this and (re)move the old copy. I will file a bug with Apple about it.
However, the App store does appear to do a clean install with each upgrade (copying over the user's documents directory) so this is not a problem from the App Store. I'm not sure if it is a problem when emailing beta testers an .ipa file or not.
I'm having the same issue. The problem is that the phone keeps a cache of the nibs. Somehow thus cache needs to be cleared for you to see the new localized nibs. I also don't want my users to have to delete the app since it stores data.
I just had the same issue but found a solution which works, even with Xcode's deployment quirkiness: Prevent UIViewController loading stale XIB from app bundle

New iPhone app as update to old app, same Bundle identifier, Xcode gives error

I currently have an app in the App Store and on my device, called, for the sake of this post, MyApp1, with bundle identifier com.myname.myapp.
Over the last couple of weeks I have been rewriting the entire app from scratch, also adding lots of new features, as a new Xcode project alongside the old one. As far as iTunes Connect and iOS are concerned though, it should still be an update do the old (version of the) app.
During testing I had both apps running alongside each other on my device and in the simulator, with the new app using bundle identifier com.myname.myapp2, and everything worked fine.
But now that the app's finished, I want it to overwrite/update the old app on my device and in the simulator, to see if the code importing the data from the old app works as expected.
So, I changed the bundle identifier of the new app in its Info.plist to com.myname.myapp, and chose Build and Debug in Xcode. But instead of the new app overwriting the old app while still using the same Documents folder, so it could import the old data, as I expected it to, I got an error.
This is what I'm doing and what happened:
Simulator: Reset cache
Xcode for MyApp1: Clean All Targets
Xcode for MyApp1: Build and Run (using Release configuration)
MyApp1: Change some NSUserDefaults data using the app, changes that should later be imported by MyApp2, which uses a different data model
Xcode for MyApp1: Stop
Xcode for MyApp2: Clean All Targets
Xcode for MyApp2: Build and Run (using Release configuration)
What happens is the following error shows up 3 times, each time for a different classs in MyApp2's Console:
Unknown class [class referenced in the MyApp1 MainWindow.xib file] in Interface Builder file.
So it looks like for some reason not all files are overwritten, as the error is caused by the old version's MainWindow.xib being loaded.
(Relatively uninteresting stack frame: http://cl.ly/1F1w1J1u3t1C2U2o2D2C)
Would anyone happen to know how I can make this work, how I can have an essentially new app overwrite the old one on my device and in the simulator, so it will still use the same Documents folder?
Thanks in advance!
Things I already tried, as suggested by others, but didn't help:
Restarting Xcode
Restarting computer
Deleting build folder from Xcode project folder
Touching MainWindow.xib
Download the old app's Documents folder to your Mac using the Xcode organizer window. Then remove the old app completely, install the new one. Finally restore the Documents folder backup using the Xcode organizer.