Adding a target to an Xcode project - iphone

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.

Related

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.

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.

How to build both Lite and Full version of iPhone app based on one xcode project?

I do not want to maintain two sets of code. I just need to limit some features in the Lite version and add some advertisements on it.
How to do that?
Create multiple targets.
You can vary build configurations by right-clicking on a target and selecting Get Info. From there, you can do things like change which Info.plist file it's looking at (to do things like add "Lite" to the name and change the icon/load images) and set compiler flags so that you can #ifdef in places.
If there are lots of files that are only applicable in the full version, then you can right-click on them and remove them from the Lite target to make a smaller app.
I've experimented with various alternatives, such as multiple configurations, and I keep coming back to multiple targets. I usually have at least three defined - Development, Ad hoc and App Store, each with their own particular settings.
Add an additional target to your Xcode project by duplicating the existing one. Define a macro in the new target (under "preprocessor macros" in build settings), something like "macroIsFreeVersion"
Now you can do this:
#ifdef macroIsFreeVersion
// code that will only execute in the free version here
#endif
and this:
#ifndef macroIsFreeVersion
// code for only the paid version goes here
#endif
You will need to make additional changes for the bundle id, provisioning profile, etc. All the stuff you did to put your paid version into the store.

How to share code & xib files between iPhone apps?

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.

What is the recommended way to reuse utility functions among apps in my Xcode based iphone apps?

I have some utility functions like:
void myVibratePhone()
{
AudioServicesPlaySystemSound (kSystemSoundID_Vibrate) ;
}
that I'd like to use across all my projects.
In C, I'd give each project the header file, and link in the .OBJ file (or perhaps create a library).
What is the Apple-approved recommended way to share code (cocoa and C primarily) among my apps? Would I need a framework for this? How would I go about creating one?
Also, since I'm using subversion for version control, if I use a framework, do I place the version of the framework that the app is using in the subversion repository for the project so that anyone who checks it out can build it straight away or make it a requirement that people check out a project + check out the utility functions also for a successful build of any project?
I don't plan on putting anything on the App Store at this time, but I don't want to do anything that will cause apple to not accept an app in any case.
I found this writeup about xcode 3.0 (I'm using Xcode 3.2.1):
How do I create a bundle of reusable code in Xcode?
I followed it, but am having one issue:
1) trouble finding my library .h file in the main project: I've tried both hardcoding it in the main projects .h file
#import "file://localhost/Users/piesia/Documents/My Utilities/MyUtilities.h"
as well as:
#import "/Users/piesia/Documents/My Utilities/MyUtilities.h"
and
#import "~/Documents/My Utilities/MyUtilities.h"
I've also tried updating Header search paths in the Project Build settings:
"/Users/piesia/Documents/My Utilities/**"
when using #import
After a lot of trying (and replacing %20 with space), I was only able to get the variants
#import "/Users/piesia/Documents/My Utilities/MyUtilities.h"
and
#import "../../My Utilities/MyUtilities.h"
but I'd prefer not to hard code the path if I can figure out a better way.
So, in closing, 1) is the writeup that I'm following the recommended way to do shared code in Xcode 2) is it recommended that I keep the shared files in a separate subversion repository from the main program and link and include it in as I'm doing now and 3) do you know what I'm doing wrong in my attempts at loading the shared header file? Would anything that I'm doing or not doing with shared code hurt my chances of getting approval if I ever decided to submit it to the App Store?
I agree with creating a static library to share the code.
To add the headers to the project you need to set the "User Header Search Paths" to the location of the .h files.
You then import the headers using something similar to:
#import "YourHeader.h"
You shouldn't need any additional path information in the import if the header search path is set correctly.
Oh this one is a bugger! - I think unfortunately the easiest way is to hardcode.
My team has dozens of reusable components in our products, many of them shared between Mac and iPhone. My experience in this is that most of the time it's much easier to just include the source code rather than to create a separate static library. The separate project for the library adds a lot of complexity and seldom provides much value. Here is how I usually approach it:
In subversion we have a directory tree like this:
/common
/Component1
/Component2
/Project1
/Project2
...
In Project1.xcodeproj, we just drag in "Existing files" from common into the tree (don't copy). Doing it this way avoids lots of overhead in managing another project. This does mean that changes to the common tree can break any of the projects. That means you need to recompile everything before committing (we use a top-level build script to check that you didn't break anything). The advantage of the static library is that you can stage this by upgrading the library for each project when it's ready. On the other hand, it means that you have to rev the library often and manage syncing it around. We've found that just sharing the code directly typically is much more effective.