In general I know how to do the Localization of iOS apps, the only thing is to choose between available ways and do it the right way. So I'd like to ask you about your l10n approach for your projects.
Here are my inputs:
I have 15 XIB files (packed with
lots of IB outlets that are not
synthesized as properties, but will
have to be localized).
It is most likely that that my
app will have 3-5 language versions,
but it is possible that I will even
go for 10 languages in the future.
In near future I plan to add new
targets that may change UI design
(paid/free versions).
I see two ways I could go:
Option A: localize each nib file by making XIBs localizable and adding language versions:
I fear that with 15 XIBs and 3-5 languages it will be maintenance horror that will go out of my control when I'll extend localization to ~10 languages and introduce new targets (maintenance horror is not about SCM, I'm using git btw).
I'd need to keep in sync all versions of XIBs which would effect in painful change-request process.
I also fear that my app bundle will grow big (currently XIBs use ~1.1 MB and translate to ~120 kB of NIB files).
when I'll decide to do iPad version, the number of XIBs will grow again.
Option B: do the localization in the code by wiring up all needed outlets synthesizing them to properties and setting their labels/titles correctly:
I fear that my app memory footprint will be really big. Or, considering proper mem mgmt, should I not consider this an issue?
I'd go for 2nd option as I see less cons to it and it can allow having everything in one place under control in each view controller, but I'd like to know what would be your choice? Which way works better for you?
EDIT: I know that that ibtool could simplify the process in Plan A, but I'm still not convinced for it.
I am using Option B in all of my projects, since this also makes it easy for me to distribute the string files to the localizers. Testing is of course needed after that to make sure the strings fit into place. Also some projects do not use XIB files, so the process is always the same, no matter if XIB files are used or not.
There is no memory issue with that option at all in my experience.
Well, I was expecting a little more feedback from SO users, but that's fine as after some research I've made my own decision to abandon option B and go for a modified version of option A.
I've heavily used ideas from a Compile-time approach by Philippe Casgrain. In general it uses ibtool to automatically localize nibs when building. Philippe's approach keeps maintenance reasonably sane for now. All other strings that I use in the code are handled using NSLocalizedString approach which was quite easy to implement in my case (just used genstrings tool). The only issue that can potentially hit me in the future is adding new targets with different/modified UI layouts.
It's hard to say whether it was the best choice. Time will tell, so some day I'll update the question and share with you how the decision worked out for me. Maybe someone will benefit from it in the feature ;)
Related
I've been asked to write scope the effort for rebranding a significant iPhone/iPad application for multiple customers, locale, languages, etc. Each incarnation of the rebrand might include different look and feel, possibly different behavior, or subsets of functionality.
My initial impression is it should be possible to use a single xCode project, and just include multiple .plist files targeted to specific project configurations. I'm unsure exactly how to accomplish this in xCode, thus I'm not sure how to accurately estimate the effort required.
I'm looking for pointers and developer references to find the most reasonable method to rebrand an existing app multiple times without forking new xCode project each time.
The feature I've been looking for is called "Targets" in xCode.
I'm going to use these as described here to deploy my single project into multiple binaries.
I'm not sure that's possible but with MVC, Cocoa makes it easy to localize apps.
I've used a client-server approach, where everything specific to one customer is downloaded or configured from a remote server. You still need customers with overlapping requirements, but you can switch on/off modules based on the needs of a particular customer.
Low-tech approach: grab the data, configuration files, and images from a different location in the file system. Or the same location, but drop the new customer data into the directory and archive the old. A plist, a text file, a series of #defines, etc, can switch a behavior on or off. Write your code so that it doesn't know how many images, which modules, what color the buttons are, etc, until it checks the configuration and gets the data and images it needs from your directory.
Hi experts i have created a set of UItableviewcustom cell classes. Now can i group those classes to an static library so that i can include that library in whichever project i want and i can use it.
You can, but it really isn't worth the trouble... with the rate that they keep on releasing new SDKs, and considering that you'd have to make it a Universal binary supporting both the simulator and the iPhone device, it really isn't worth the effort... I'd just save the ".h" and ".m" files and drop them in a new project.
However, if you are absolutely determined to go that route... I do have some articles on creating iPhone frameworks: here. Note that they are somewhat outdated (circa iPhoneOS3.1), so I don't know how much has changed, and I've since converted to the Android camp... but you still might find the info there useful.
I recently became interested in iPhone app development, so I've been looking at online tutorials, and also reading a book, trying out the examples as I go along.
I'm getting better, but one of the things I still find quite annoying about the usual development model is that I really have no idea what the SDK is really doing behind the scenes to make the app "work" because Apple protects me from this. For example, when I make connections on interface builder, this presumably corresponds to code being generated somewhere... Where that code is and what it does and how it works are not obvious (to me).
So I'm wondering, is it possible to create an iPhone app entirely programmatically? That is, have execution start in some main method, which will then programmatically create any views, register event listeners, etc. And if yes, what are some good resources for something like this?
There is no generated code. It's serialization. Interface Builder serializes the object tree to the .xib file, your app deserializes it back.
Of course, you can also build your UI in the code, it's just more code. In early versions of the SDK this was even necessary, since Interface Builder was not available yet.
I don't use interface builder and it works great for me. When creating a new app in XCode you can chose "Window-based app" and it will create you a window in your new project and the application delegate. The application delegate has method applicationDidFinishLaunching which is effectively your "main" method - you can create views and them into window directly, or you can create viewcontrollers and then add their views into the window.
I'm getting better, but one of the things I still find quite annoying about
the usual development model is that I really have no idea what the SDK is really
doing behind the scenes to make the app "work" because Apple protects me from
this. For example, when I make connections on interface builder, this presumably
corresponds to code being generated somewhere... Where that code is and what it
does and how it works are not obvious (to me).
You've got it all wrong. IB helps you instantiate your control objects and helps you connecting them to your code logic through IBOutlets, but these are real, live objects, it's not code generated, this is a misconception. This code is archived in Nib files (runtime) and in Xib files (used by IB during design) all of this and more, including the Nib Object Life Cycle is explained in detail at https://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/LoadingResources/CocoaNibs/CocoaNibs.html#//apple_ref/doc/uid/10000051i-CH4-SW8
And yes, you can bypass IB entirely, but it's definitely not for beginners.
Short answer: Yes
Long answer:
Interface builder isn't doing much more than generating XML for you. You can open the XIB in a text editor to prove it, and Xcode is even smart enough to eval the XML and give you compiler warnings when appropriate.
There are lots of tools that auto-gen iPhone projects, probably the most popular being Unity. There is also the open source project Titanium for the adventurous. It's a lofty project to undertake by yourself, so I'd recommend pitching in to help one of the open source projects that are already out there first until you are well versed with it before trying to go off and reinvent a better wheel again.
I just have a question about binary file in an iPhone app.
When an iPhone developer wants to submit their app to testers or App store they build the binary file of their appliction. My question is it possible to edit your app's binary to get the source code, or just simply edit the binary for someones purpose.
If it is posible how can I prevent it to happen.
In general, getting source from compiled code is technically possible, but not to the extent you fear. Decompiling isn't usually done for a few reasons.
One of the things a compiler is optimize a lot of different things in your application, e.g. unrolling some loops or inlining some functions. That would make a decompiled code very different from the source and harder to modify.
Symbols are generally lost when compiling. I don't know the process for every compiler (Especially not for iPhone apps), but I know Visual Studio keeps a separate database for debugging. Without that database, var UserPreferences would turn to _a or something along those lines.
All that said, you can't completely keep someone from decompiling your code, but there's pretty much nothing you need to do to make it hard for them to get something useful.
As Alex said you cannot prevent someone from decompiling your binary if they really want to do so however unless you have some secret code or something they can't get any other way it is usually less work to write a clone of your app then decompile it and use the result.
If you do have a secret code or something you need to hide from people (usually as part of a DRM or DRM-like system) one way to made it harder to get to would be to not directly put the code in your app. Use a state machine or something to build the code so it is harder to figure out what is going on. That might buy you a week, anyway.
In order to provide nice URLs between parts of our app we split everything up into several modules which are compiled independently. For example, there is a "manager" portion and an "editor" portion. The editor launches in a new window. By doing this we can link to the editor directly:
/com.example.EditorApp?id=1
The EditorApp module just gets the value for id and loads up the document.
The problem with this is ALL of the code which is common between the two modules is duplicated in the output. This includes any static content (graphics), stylesheets, etc.
And another problem is the compile time to generate JavaScript is nearly double because we have some complex code shared between both modules which has to be processed twice.
Has anyone dealt with this? I'm considering scrapping the separate modules and merging it all back into one compile target. The only drawback is the URLs between our "apps" become something like:
/com.example.MainApp?mode=editor&id=1
Every window loads the main module, checks the value of the mode parameter, and and calls the the appropriate module init code.
I have built a few very large applications in GWT, and I find it best to split things up into modules, and move the common code into it's own area, like you've done. The reason in our case was simple, we had some parts of our application that were very different to the rest, so it made sense from a compile size point of view. Our application compiled down to 300kb for the main section, and about 25-40kb for other sections. Had we just put them all in one the user would have been left with a 600kb download, which for us was not acceptable.
It also makes more sense from a design and re-usability point of view to seperate things out as much as possible, as we have since re-used a lot of modules that we built on this project.
Compile time is not something you should generally worry about, because you can actually make it faster if you have seperate modules. We use ant to build our project, and we set it to only compile the GWT that has changed, and during development to only build for one browser, typical compile times on our project are 20 seconds, and we have a lot of code. You can see and example of this here.
One other minor thing: I assume you know that you don't have to use the default GWT paths that it generates? So instead of com.MyPackage.Package you could just put it into a folder with a nice name like 'ui' or something. Once compiled GWT doesn't care where you put it, and is not sensitive to path changes, because it all runs from the same directory.
From my experience building GWT apps, there's a few things to consider when deciding on whether you want multiple modules (with or without entry points), or all in one: download time (Javascript bundle size), compile time, navigation/url, and maintainability/re-usability.
...per download time, code splitting pretty much obviates the need to break into different modules for performance reasons.
...per compile time, even big apps are pretty quick to compile, but it might help breaking things up for huge apps.
...per navigation/url, it can be a pain to navigate from one module to another (assuming different EntryPoints), since each module has it's own client-side state...and navigation isn't seamless across modules.
...per maintainability/re-usability, it can be helpful from an organization/structure perspective to split into separate modules (even if there's only one EntryPoint).
I wrote a blog post about using GWT Modules, in case it helps.
Ok. I really get the sense there really is no "right" answer because projects vary so much. It's very much dependent on the nature of the application.
Our main build is composed of a number of in-house modules and 3rd party modules. They are all managed in seperate projects. That makes sense since they are used in different places.
But having more than one module in a single project designed to operate as one complete application seems to have overcomplicated things. The original reason for the two modules was to keep the URL simple when opening different screens in a new window. Even though had multiple build targets they all use a very large common subset of code (including a custom XML/POJO marshalling library).
About size... for us, one module was 280KB and the other was just over 300KB.
I just got finished merging everything back into one single module. The new combined module is around 380KB. So it's actually a bit less to download since most everyone would use both screens.
Also remember there is perfect caching, so that 380KB should only ever downloaded once, unless the app is changed.