Multiple Info.plist files in MonoTouch solution - ios

I'm trying to write two separate submittable apps: one for iPad and the other for iPhone. This necessitates having two separate plists to allow independently specifying different app icons, launch images, etc.
When I try to rename my Info.plist, MonoDevelop autocreates a new empty Info.plist and uses that instead. By the same token, I can't seem to move my Info.plist to the iPad/ subfolder and have MD pick it up there.
Currently we have 3 projects in 1 solution: iPad, iPhone, common files and libraries.
Is the only solution to have separate .sln files in the appropriate subfolders, or can I still somehow build two separate apps from one .sln?
EDIT: Project structure is below if that helps visualise the problem.
MyApp.sln
MyApp-iPad.csproj
MyApp-iPhone.csproj
MyApp-Common.csproj
Main.cs
AppDelegate-iPad.cs
AppDelegate-iPhone.cs
Info.plist (MD currently uses this for both projects)
Common/
iPad/
iPad/Info.plist (for -iPad.csproj)
iPhone/
iPhone/Info.plist (for -iPhone.csproj)

Here's my current and very ordinary solution: Add a custom command that runs Before Build
cp iPad/Info.plist Info.plist
And for iPhone:
cp iPhone/Info.plist Info.plist

I have a project where I need to be able to build the application with different icons and resources.
I use different build profiles and build scripts that copy in the correct files into a resources folder. This also changes the application name and identifier.
This is a similar solution to yours, but it would allow you to bundle different images with your application like you wanted.

You need to make 2 projects, one for iPad and one for iPhone.
You should "link-in" all the code files from one project to the other. You can have different Info.plist files, icons, images, etc. with this route.
Here is a link talking about various strategies: http://docs.xamarin.com/ios/Guides/Application_Fundamentals/Building_Cross_Platform_Applications/Sharing_Code_Options

Related

Keep WatchKit Extension code (git repo) separated from the existing iPhone code (repo)

I wanted to add a WatchKit Extension (with SwiftUI supported on iOS13+) to my existing app (target iOS12) while keeping both codebase separated (two repos).
How can I separate the WatchKit Extension code from the Mobile One?
Will my Watch App with SwiftUI only work for users with WatchOS 6 and iOS13 without affecting the existing users with iOS12?
How about the app binary size increase?
Thanks for reading!
I am not sure if there is a simpler solution, but this one should work:
Separation of both apps:
If you open in Xcode the Source Control navigator, you see that Branches, Tags and Remotes belong to a main entry in the Project navigator, i.e. to a Xcode project. So in order to have separate repos, you need separate Xcode projects to which you can assign separate repos.
You can however have multiple projects in one workspace, so that all files are available in this workspace.
To have one standalone app, and one app with a watch extension, just setup a workspace with your standalone app, and add another new project. This new project needs all files of the original app plus the watch extension.
Since you need files from one project also in the other, you could drag them from one project to the new one, but then they will be copied (a green + badge is shown during dragging). Usually this is not what you want, since you usually don’t want to maintain two copies separately. Instead, you can show such a file in the finder, and then drag it from the finder to the new project. In this case, you have the option only to copy the reference.
Independence of both apps:
Since you have two separate projects, you can set the deployment target in the target’s build settings as required.
Size:
Each project will get separate products, the standalone app only an xxx.app, and the new project xxx.app, Watch.app, and Watch Extension.appex. So there should be no overhead.
EDIT (due to the comment of Ouadie in his question):
I am not sure if I understand your problem:
With the procedure above, you get a single workspace with two separate projects that share part of the files.
The „mobile project“ is the same as you use right now. It has only a single target (despite of test targets) that is built exclusively with the sources required. It has thus the same size as now.
The „watch project“ is new. It has 3 targets, the „mobile“ target, the Watch target, and the Watch Extension target (despite of test targets). It is built with the shared sources, and the additional watch extension sources. Its size is thus larger, but the increase depends of course on your sources.
Since you have 2 repos, the projects are decoupled, but both repos share some files. If you want to decouple them completely, you could copy the files from your current project to your new project (instead of copying only references), but then you had to maintain 2 copies.
I hope this helps!

How do I distribute my default settings plist file with a single known name, and have a different file depending on the selected target?

I want my iOS app to read default settings from a configuration file. It will be a plist file. The source code should have the path and name of the file hard-coded and my code wold just open the file and read the contents at startup. But I would need to have two files with the same name and path in the Xcode project to do it this way. Of course, each file would be for a different target and only one would get included in the distribution package.
I have not investigated renaming files in a build script. I hope there is a better way.
I have considered having different file names and then searching for the file within the known relative path. This seems easy and is the option I will go with if there is no simpler or more clever way to do this.
So is there a way to pick from two different files, based on the selected target of the app, and have that file end up in the distribution package with a specific name (always the same name)?
There are different approaches that can achieve it. One is to create >different targets, each one of which employs different Info.plist. Each >time a target is selected, a different Info.plist will be used, hence we >will be able to differentiate variables like token, URLs for different >builds. The alternative approach is to put your build configuration >settings into .xcconfig files and refer those in your project info.
It could also be achieved by using Bundle Identifiers
I hope this link will be helpful to you,
https://www.appcoda.com/xcconfig-guide/
https://www.appcoda.com/using-xcode-targets

Have two GoogleService-Info.plist (or more) in one target (GCM)

I am integrating GCM in an app and we happen to have several build configurations for the same target and some of them use different Bundle Ids (we have different accounts, enterprise and appstore) so if we want to enable GCM push notifications in both we need two different GoogleService-Info.plist files (each one for the different BundleID). I cannot find a way to tell the GCM sdk to initialize from a different named file but the default one. Does anyone know if this is possible?
I can think of a two solutions, but I would rather not do them.
- Write to the plist file the bundle id once the app is started (or before)
- Create a different Target each one with a different plist file
Thanks a lot.
Regards,
Javier
I had a similar problem: Use User-Defined build settings in custom .plist file
You can use a Build Phase Script to copy the proper .plist file to your location:
Create a new folder (for example: GoogleServiceInfoPlists).
Copy there all .plist files (for example: GoogleService-Info-Debug.plist, GoogleService-Info-Stage.plist and GoogleService-Info-Prod.plist).
Add new Run Script Phase (Xcode: Target->Build Phases->"+" button)
Use script below to copy (replace) .plist file for given environment to the main directory (it's src in my case):
cp "${SRCROOT}/src/Resources/GoogleServiceInfoPlists/GoogleService-Info-$CONFIGURATION.plist" "${SRCROOT}/src/GoogleService-Info.plist"
Please note that src/GoogleService-Info.plist file must be added to the Xcode project (Build Phases->Copy Bundle Resources) while /src/Resources/GoogleServiceInfoPlists/GoogleService-Info-* files not necessarily.

Loading a different plist depending on the target

I thought it would be interesting to attempt building multiple apps using the same code base, where the only differentiating data is held in a few plists. For example, one plist holds some theme info - a few key/values to drive the color scheme used in the app. I'll call the original version of this theme.plist.
I soon learned that I should create multiple targets in my project, and have been able to add these successfully. Each one, via it's own appname-info.plist, has a different name and bundle id - it's neat seeing all three on my home screen without any real extra work.
But right now they are all identical. I haven't figured out how to use a different set of data for each one.
My first thought was to have some folder for each target - each with its own theme plist named theme.plist - and somehow distribute each target with a different folder. But researching that idea doesn't get me much google juice.
So what about multiple theme files? Ok, so far that looks better - I can create an app1-theme.plist and 'app2-theme.plist' with different values for the same keys in each. And Xcode even lets me use some flags to say which targets should include each resource.
But I don't know how to load the appropriate plist at runtime. I need to examine something (the bundle ID?) and then assign the appropriate name of the theme plist to something (what)?
It seems like this might have something to with #ifdef, whatever that might be...?
Can someone explain how I should be looking to accomplish this? Am I on the right track? I'm happy to put some reading time in but I don't even know what to look up yet.
You are just about there. Xcode supports having multiple files with the same name in a project, one way you can do this by storing them in different folders within your project folder.
Unfortunately at this point Xcode won't give you a lot of help, so open your project in the Finder, create one subfolder for each of your apps, in those folders place a copy of the plist. Now add each copy in turn to your project, making sure you add each to just one of your targets.
You might want to create a group in Xcode called, say, "Theme files", to keep them altogether.
HTH
What you are trying to do is trivial. If you select a file from your project, and bring up the "File Inspector" in the utilities area (Press Command option 1) you should see a section "Target membership". Each target in your project will be listed, with a checkbox next to it. If you check the checkbox for a file and target, that file is built into that target. Un-check the checkbox for a file and target and that file is not copied over to the specified target (you may need to run a clean, and delete the app from the target device, to get rid of files that used to be included but that you have un-checked. Xcode generally won't automatically remove things that used to be included.
You could create a directory in your bundle and teach your app to scan that directory for plist files. Then include a different set of files in that directory for each target and each target app's behavior will change.

An iOS app with multiple brandings

I have an iphone app working just fine - it basically just displays news from a feed, but now we want to have a second app that is a clone of the first but branded a different way and displaying news from a different feed - the xml feed and the graphics/colors would be the only difference.
I'm trying to not duplicate any effort. I can easily set a define and build the app using different colors and images and the xml feed url with one codebase. But what is the preferred way to do this so that I can make a change to some common code and easily rebuild both apps and get them updated in the app store without maintaining separate xcode projects, separate files, etc?
You can do this easily by adding a new target to your project.
Create unique branded assets and configuration files with identical names, but keep them in different folders. When you're ready, add each folder to the project and set the "Target Membership" to the appropriate target. If you make a mistake, you can change it in the File Inspector pane.
When you build a specific target from the shared codebase, only those resources will be bundled with the app. As long as the filenames are identical, it should work.
You can use one project with more then one target. For each target you can add different resources (Info.plist, icon, etc.).
XML feed can be defined in settings.bundle (which also can be dependent on the target).
Layout you can read from dictionary, which also should be dependent on the target.

Resources