If it's any help, I've just done this (last night).

I have an app which is also white labeled. There is the main one, and
two white labels (at the moment). Each has their own app name,
identifier, default.png, icon etc.

I moved ALL the code into a library, made a new "root" project (for
each one), and just kept the plist's, mainwindow.xib and the
AppDelegate in the "root" project. They also have their own compiler
defines.

Everything else is in the other assembly.

Appears to work well :)

I'd love it if I could have a single SLN which has 3 apps and a
library, but I think I might be wishing a bit there. Either way, this
is very workable.


On Tue, Oct 25, 2011 at 17:32, Guido Van Hoecke <[email protected]> wrote:
> Hi,
>
> Thanks to suggestions and remarks from you and this list I came up with a
> working setup. Just for the record, I want to describe how one can easily 
> setup
> a solution with two apps with distinct names but sharing all source and
> resource files.  These apps produce different code using
> [Conditional("OPTIONXYZ")] compilation.
>
> Create a 'MyApp' solution and app.
> That gives you a directory /Users/you/.../MyApp/MyApp or /Users/you/.../MyApp 
> if
> you do not create a solution directory, which is fine if you like it that way.
>
> You now want a lite version of your app, called MyApp_Lite. All sources are 
> the
> same as for MyApp, only certain parts will compile differently depending upon
> the presence or absence of e.g. the LITE symbol at compile time.
>
> Rather than creating a new app, just copy your MyApp.csproj file to
> MyApp_Lite.csproj in the same directory and add it as existing project to your
> solution. You now have two projects which are identical apart from their name.
> You are free to change the compiler symbols for the lite app. These symbols 
> are
> stored in the csproj files, so each app can have its own values.
>
> You must edit the output path for both projects (again the output path is
> stored in the csproj file, so they may and should be different for each of the
> apps). The normal output path, as you all know, is 
> 'bin/Platform/Configuration'
> (e.g. bin/iPhone/Release)
>
> Obviously this has to be changed if both apps reside in the same directory.
> Just change 'bin/Platform/Configuration' into
> 'bin/AppName/Platform/Configuration' (e.g. 'bin/MyApp_Lite/iPhone/Release').
> Don't forget to set this for each combination of both apps.
> You now can build all platform and configuration combinations for both your
> apps.
>
> There is one more file that is different for each project, namely the
> Info.plist file. Unfortunately, its name is not AppName dependent. It contains
> the Bundle Identifier com.yourcompany.MyApp or com.yourcompany.MyApp_Lite and
> the bundle display name MyApp or MyApp_Lite. You don't want to change these
> each time you build the other project.
>
> So when it's setup correctly for MyApp you should copy Info.plist as
> Info.plist.MyApp and then you set it up for MyApp_Lite and copy the Info.plist
> as Info.plist.MyApp_Lite. So now you have Info.plist, Info.plist.MyApp and
> Info.plist.MyApp_Lite and all you need is some automated system to copy
> Info.plist.MyApp or Info.plist.MyApp_Lite before building MyApp or MyAPP_Lite.
>
> Custom commands to the rescue: further down, you'll find a MtPlistCopier.pl
> perl script which you should enter in your project options (again, that's the
> csproj file) as a 'Before Build' and an 'After Build' command, with the 
> Working
> Directory set to the target directory $(TargetDir). This little script will
> rename your plist out of the way and copy your project plist as Info.plist 
> when
> called before the build; when called after the build, it will restore the 
> saved
> plist. This prevents version control from detecting irrelevant changes to
> Info.plist each time you build the other app.
>
> You now have a fully automated setup where you can build either app to 
> whatever
> platform and configuration combination.
>
> As a freebie, I also want to show you how you can register the version control
> revision used to build your app within your app. I use svn here, but this can
> easily be adapted to other version control systems. The MtSvnRevision.pl perl
> script further down is to be setup as an 'After Build' custom command, again 
> to
> be ran from the target dir. I just creates inside your MyApp.app or
> MyApp_Lite.app directory a little file 'svn.info' with the output of the 'svn
> info' command run in your project directory. This info is then freely 
> available
> from within your app, e.g. with the VersionAndRevision method which you can
> also find here after. Don't forget to set MtSvnRevision.pl as After Build
> custom command for all platform / configuration combinations of both your 
> apps.
>
> This setup is probably far from perfect and I'm well interested in your
> suggestions and improvements. At the very least, I hope that it will help some
> of you in setting up this or some similar system to build apps with shared
> sources and resources.
>
> (One last note: it is less work if you first define the output paths, Before
> and After Build commands for your MyApp. If you then copy the MyApp.csproj as
> MyApp_Lite.csproj, it will already have all these things setup)
>
> Guido.
>
> ------ MtPlistCopier.pl ------
>
> #!/usr/bin/perl
> #{= MtPlistCopier.pl 2011.10.25 14:54 [email protected] =}
>
> # This script copies either renames Info.plist to Info.plist._Saved
> # and copies ProjectName.Info.plist to Info.plist
> # or it renames Info.plist._saved back to Info.plist
> #
> # This is only needed if your project directory houses more than one
> # project, i.e. more than one .csproj file.
> #
> # The script is to be called with $(TargetDir) as current directory.
> # Currently there is no way in MonoDevelop to pass a parameter to an
> # external command, but the 'active' project name can be retrieved
> # from the target directory path, which is to be the current directory
> # when calling this script.
> #
> # This script assumes that the current (target) directory is as follows:
> # /ProjectPath/bin/AppName/Platform/Configuration
> # where
> # - /ProjectPath/ is the fully qualified path with your .csproj
> #   and Info.plist files (e.g. /users/me/solution/project/)
> # - bin is the default bin directory as is the case for all apps
> # - AppName is the non-standard additional path component required to
> #   ensure that each of the .csproj files in the project directory
> #   generates the app in a dedicated directory without interfering
> #   with the output of the other csproj files in the project directory
> # - Platform is iPhone or iPhoneSimulator
> # - Configuration is Debug, Release or Distribution
> # This script needs the ProjectPath and the AppName
> #
> # The project directory  is expected to contain a default Info.plist
> # belonging to whatever project and an Info.plist.AppName file
> # It will rename the existing Info.plist to Info.plist._saved
> # and copy Info.plist.AppName to Info.plist
> # However, if it detects an existing Info.plist._saved, it will
> # simply rename it as Info.plist
> #
> # The idea is to call this script as pre-build as well as
> # as after-build externbal command. The saving and restoring part
> # avoids version control changes that are really irrelevant as far
> # as version control is concerned.
> #
> use Cwd;
> use File::Copy;
>
> my $dir = cwd();
>
> # extract the project name
> my ($ProjectPath, $AppName) = $dir =~ m{(.*)/bin/([^/]+)};
> warn "Couldn't define the ProjectPath directory from $dir" unless 
> $ProjectPath;
> warn "Couldn't define the AppName name from $dir" unless $AppName;
>
> # define the Info.plist names
> my $dest = "$ProjectPath/Info.plist";
> my $from = "$dest.$AppName";
> my $save = "$dest._saved";
>
> warn "There's no $from to copy as $dest" unless -e "$from";
> warn "There's no $dest to be copied to" unless -e "$dest";
>
> if (-e $save) {
>    # we're called as after-build command, just rename saved plist
>    rename ($save, $dest) or warn "Failed to rename $save yo $dest : $!";
> } elsif (-e $dest && -e $from) {
>    # called as a pre-build command: save the Info.Plist
>    rename ($dest, $save) or warn "Failed to rename $desy to $save : $!";
>    copy ($from, $dest) or warn "Failed to copy $from to $dest : $!"
> }
>
> #{= MtPlistCopier.pl 2011.10.25 14:54 [email protected] =}
>
> ------ end of MtPlistCopier.pl ------
>
> ------ MtSvnRevision.pl ------
>
> #!/usr/bin/perl
> #{= MtSvnRevision.pl 2011.10.25 15:09 [email protected] =}
> #
> # This script writes an svn.info file in the target monotouch app directory
>
> # Get the current working directory, supposed to be the target directory
> # for a directory with one or several projects
> # e.g. either /Users/guivho/Mono/Solution/AppName/bin/iPhone/Release
> # or /Users/guivho/Mono/Solution/Project/bin/AppName/iPhone/Release
> # The second case is where there are several project files in the same 
> directory
> use Cwd;
> my $dir = cwd();
>
> # extract the project name
> my ($root, $p1, $p2) = $dir =~ m{(.*/([^/]+))/bin/([^/]+)};
> my $proj = $p2 =~ /iPhone|iPhoneSimulator/ ? $p1 : $p2;
> print "===> Project name: $proj\n";
>
> # The app should have that part followed by .app
> $app .= "$proj.app";
> print "=======> App name: $app\n";
>
> # only proceed if the app does exist
> die "There's no '$app" unless -e "$app";
>
> # Get the svn status info for the project directory
> my $svn = `svn info $root`;
> print "=======> SVN info:\n$svn\n";
>
> # Write this info to svn.info in the app directory, so it could be
> # /Users/guivho/Mono/bin/iPhone/Release/AppName.app/svn.info or
> # /Users/guivho/Mono/bin/AppName/iPhone/Release/AppName.app/svn.info
> my $fout = "$app/svn.info";
> open (FH, ">$fout") or die "Failed to create $fout ($!)";
> print FH $svn;
> close FH;
>
> #{= MtSvnRevision.pl 2011.10.25 15:09 [email protected] =}
>
> ------ end of MtSvnRevision.pl ------
>
> ------ VersionAndRevision ------
>        /// <summary>
>        /// Get the version and revision of the current app.
>        /// <para>This is composed of the value of the "CFBundleVersion" entry
>        /// in the app's Info.plist, followed by the current svn
> revision.</para>
>        /// <para>The svn revision is extracted from the svn.info file
> that is expected
>        /// in the root of the .app directory.</para>
>        /// <para>This file is to be created by an external command
> executed after the
>        /// build. </para>
>        /// </summary>
>        /// <returns>The current version and revision</returns>
>        public static string VersionAndRevision()
>        {
>            var version =
> NSBundle.MainBundle.ObjectForInfoDictionary("CFBundleVersion").ToString();
>            if (!File.Exists("svn.info"))
>                return version;
>            var sr = new StreamReader("svn.info");
>            var s = sr.ReadToEnd();
>            sr.Close();
>            var svn = Regex.Replace(s, @".*Revision: (\d+).*", "$1",
> RegexOptions.Singleline);
>            return string.Format("v{0} r{1}", version, svn);
>        }
> ------ end of VersionAndRevision ------
> _______________________________________________
> MonoTouch mailing list
> [email protected]
> http://lists.ximian.com/mailman/listinfo/monotouch
>



-- 
Nic Wise
t.  +44 7788 592 806 | @fastchicken | http://www.linkedin.com/in/nicwise
b. http://www.fastchicken.co.nz/

Nearest Bus: find when the next bus is coming to your stop. http://goo.gl/Vcz1p
mobileAgent (for FreeAgent): get your accounts in your pocket.
http://goo.gl/IuBU
Trip Wallet: Keep track of your budget on the go: http://goo.gl/ePhKa
London Bike App: Find the nearest Boris Bike, and get riding! http://goo.gl/Icp2
_______________________________________________
MonoTouch mailing list
[email protected]
http://lists.ximian.com/mailman/listinfo/monotouch

Reply via email to