How to share code & xib files between iPhone apps? - iphone

I'm in the process of creating an app. I'd like to have a pared down free version and a full paid version. Obviously, they will share a lot of code and some xib files. How to I share these without just duplicating them?

Create a second target (duplicate the main one) for the light version. You can then remove any files as necessary and define a preprocessor macro if necessary to distinguish between code for the lite vs paid version within a given code file.

How about making it one project with some sort of key or switch or something like that which will distinguish with version of the code to run.

Related

Organizing Different Versions of App in Xcode

I'm developing an iPhone app that can edit images. Ultimately, I want to have a small version that allows the user to simply edit their images, and a large version that allows social networking of the images. Then I'd like to develop a version of each for the iPad.
Being that this is my first foray into commercial mobile development, I'm confused about how to organize all these versions in Xcode. Obviously, there will be file reuse shared between each version. I guess my question is, how do I go about organizing these separate projects in the most efficient way so that they share files and so when I edit a particular file that is shared, the changes are made to each version of the application? Is there some kind of construct to follow in XCode?
Are there any links or literature on how to go about doing this? (was not sure the correct term to search for it).
Remember: If you find yourself repeating/duplicating something, suspect that you're doing it wrong.
Your Xcode project will have 4 targets in this scenario. The basic target layout for this setup looks like this:
A Static Library (for your shared source files)
A Resource Bundle (for your shared resources)
App-Full (Universal)
App-Lite (Universal)
The apps link to the shared static library, and copy the resource bundle.
Naturally, apps will have sources/libraries/dependencies which differ -- those go in the app target (or some other dependency).
Given your background: Plan on it taking a good amount of time (initially and as you go) and patience to figure out how these dependencies should be composed, used, and maintained.
I would suggest keeping the "lite" and "full" projects separate but within the same workspace. That way you can keep the shared files in one project and simply use a shared reference to them in the other. All changes made to the shared files from either project will affect both.
As far as iPhone/iPad versions, I would also suggest that you keep these apps completely separate but within the same workspace (so that they can share code) as well. If you look around about the suggestions for managing both apps in a single project (aka, universal app), the only real benefit is that customers can buy one app and can download it on either device and some may get upset if that isn't available to them. If your app is free, don't worry about it.
Lastly, a caveat about workspaces, you need to uniquely name your files across all projects. For example if you're working with a project that uses a MainViewController.h subclass and another project that uses a MainViewController.h subclass, you could assign or edit the wrong one by accident regardless of what project you're in, so be wary. If using unique file names is a problem, you can bypass using workspaces by simply creating an empty project to dump all of your shared code into and then add references to your standalone apps from there.
If you choose to keep various copies of your project for different functionality, it will be eventually confusing, as there are places when XCode offers you one thing instead of another. One such place is - when you open a project from location X, it will also show you your copy from location Y since you opened it last time. As a result, you are likely to commit more mistakes. Organizer is one more such place where you can make mistakes.
XCode is self-contained enough to maintain both iPhone and iPad versions. You will have two separate storyboards which can be made part of one project if you chose universal as the type of app.
As for various features, you shouldn't be maintaining separate copies of your project. Instead, recommended way is to keep all features within single project, and have app logic provide access to various features.
XCode keeps version of your build under Targets section when you click project. To maintain multiple versions through your dev cycle, use source code repository (git or svn).

Two versions of iOS app - Free and Paid - how to conditionally change project ID in Xcode?

I have my app with ID com.mydomain.AppName which is a paid version.
I decided to introduce free version as well, and through my code I easily add ads/remove some functionality with simple #defined/#ifdef business.
However, I do need my app ID to be different for free version. How do I do this conditionally (i.e. #ifdef FREE_VERSION ... etc.) for my app?
This question was answered in a previous post
The basic idea is that you create two targets and then either use #ifdefs or create separate files to control the content in the two targets. Creating another target is dead simple. Just right-click on your existing target and duplicate it. Give it the name that you want for the free app.
In your case, you'll probably want to have different icons for the Free and Paid game, so create two icon folders—one called Free-Icons and the other called Paid-Icons. Put them in the project folder and when importing attach them to one of the targets.
I duplicated the original Info.plist and Prefix.pch files and gave them different names but you could use the same names, just put them in different folders. You'll need to adjust the build settings for each target to reflect the new names.
You might also have less content in the free app. Just select the sounds and pictures that are only in the paid app and in the inspector mark the Target Membership as just the paid app.
You'll also need to edit your schemes as so that you can build two versions. I just finished doing this for a project that I'm working on and it took about two hours from start to finish to find everything that needed changed. I'm guessing I could add another version in about 15 minutes now that I know what I'm doing.
This way of doing things is way better than duplicating the code or swapping the content out in one code base because you can easily switch back and forth between targets to make sure everything works when you make changes.
You could achieve this by having different XCode projects - one for each type of app that rely on common code (aka library XCode project(s)). One XCode project would be for paid app, and would have different macros, setup functions. The other XCode project would be for free app. Both the apps's projects can include shared sources - which would be compiled based on macros (PAID or FREE) etc.

Adding a target to an Xcode project

I have an iPhone application which is currently in the app store. I want to make what is effectively exactly the same application, but which is free of charge and features ads.
My plan was to effectively just copy the project, create a new one and add ads into the code and release as separate app. However, someone mentioned that the best solution would be to add an additional target to the existing application, providing two binaries at run time.
Seems like a good solution to me, however I am a little confused as to how I would go about altering the code to have ads built into the new target, and leaving the original untouched?
I followed this tutorial which, although old, was basically the same for xcode 4. I duplicated the target and p-list, making sure I was able to run it with changes and not affect the full version target.
I then duplicated the .xib files that would be different. If you look under the project settings, somewhere you can find a list which allows you to choose which resources are included. Include the lite version's xibs in the the lite version, and the full version's in the full respectively. Then you will be able to edit each without affecting the other.
The icons and images can be changed in the same way. Simply create a lite version icon set or other set of images and include the lite icons in the lite target's resource settings instead of the full version's images.
Also, you'll want to create some preprocessor macros. In the build tab look for them, and crete a macro called LITE_VERSION (or whatever you want, it doesn't really matter) for every preprocessing option - debug, distribution and release.
That allows you to add differing code in the same .h and .m files. Simply use
#ifdef LITE_VERSION
// Lite version only code here
#endif
to separate the two. You can also use #ifndef LITE_VERSION to add code only to the full version.
That's it! After all of the above steps, you should be able to edit the lite version's .xib files, put code into the lite or full version only, and have separate images and icons for each.
XenElement's answer is correct. But you should see the best practice to do it. You should have an identifier class to check for targets. If you use macros everywhere in the code, it won't seem good for you and other developers as well. In this little blog post you can see how to create that kind of an identifier class and learn some best practices about targets in xcode.
I followed this Just2us: How to create multiple targets for Xcode iPhone Projects tutorial.
I decided change step-3 with Stu's clue, setting FULL_VERSION explicitly in the paid version.
"To address the concern of not having accidentally LITE_VERSION defined as a macro preprocessor (thus releasing a full version accidentally), I put this little snippet of code in a header file (it just needs to be somewhere in the code base , just make sure that is common to all configurations)":
#ifndef LITE_VERSION
#ifndef FULL_VERSION
#error You probably forgot to specify if this is the Lite or Full version of the app
#endif
#endif
PS: I wrote the code above right after the #import in AppDelegate.

Is it possible to hide the source codes of .m files and build project using xcodebuild

I have created a Mac app that can generate iphone ebook app project source codes.
I know I can using xcodebuild to build the project to get the release binary file.
Is it possible to hide the source codes of .m files(maybe store in memory) and build project using xcodebuild?
Welcome any comment
Thanks
Marc
It sounds to me like you are attempting to generate source code for others to use, but then hide it so they cannot see whats been generated. Basically not possible. You could generate obfuscated code which would make it harder to read, but not impossible.
Realistically what you are trying to do is generate template code for others to use. If you don't want them to be able to see it, then you presumably don't want them modifying it. The easiest answer is to simple not do it. Instead, create a compile static framework containing your code and IP, and then only generate templates which makes calls to your framework. Thus your code is protected.
Your question lives on the edge of being programming related, and I'm not exactly sure what problem you're trying to solve.
However, you can create a RAM disk, store your project there and run xcodebuild against that. Just be aware that you're not really protecting the .m files so much as limiting how long they are easily visible.

iPhone: Completely different project for Lite version of my app?

I've run into a bit of a dilemma.
I'm considering making a lite version of my app that will be for free but will run on iAds. The Lite version will therefore have different .xib files because I have to make room for those iAds.
So what's better, should I just make some more .xib files in my project and then somehow programmatically load them. Or should I just create a completely new project (copy & paste
my old directory) and create the lite version?
Definitely don't fork it. You will regret it big time down the road as you'll have to merge virtually every commit across projects. (And XIB files can't be merged...)
I don't even know if you necessarily need to create additional XIB files. You could probably just conditionally resize/hide the necessary views in code. But even if you have to create additional XIB files, it doesn't compare to the pain you'll go through from forking.
Just create a different target within the same project. You can include different combinations of xib and source files within each target, and use some #ifdef's in your source code to limit features or functionality in the Lite version of the target by using a preprocessor define in the Lite target Build settings.