xcode compile flags to create two apps - ios

To what extent can I use compile flags. I want to use the same xcode project but compile two apps. The differences are:
The bundleID
The Provisioning Profile used
The URL that the code uses to access it's services
The app name (the test app has 'Test' appended to it)

As mentioned, you need two targets. Each target get it's own bundle id, Info.plist etc. Crucially, it can share source code between the two app targets, so you can create a lite and pro version of your app (not sure if that's what you are trying to do).
All you need to do is pass -DPROVERSION=1 (or whatever) to the compiler in order to do conditional compilation within a shared source file:
#if PROVERSION
// Show supadupa feature
#endif
This is done within the Build Settings of the pro app target.

Related

How to make an extension work for several app targets?

I have an iOS App target, open to everyone for the public store, all fine.
And I have 2 extensions with it in the project, including the bundle identifier in their identifier of that iOS App target.
Now I duplicated the first App target, added some changes, etc for B2B & MDM usage, but I want to use the same extensions, without having to change their bundle identifiers each time I change the build target, and I don't want to duplicate them as well with different bundle identifiers as well, if that is avoidable.
Visual example:
Basically I want to avoid delivering the code of the second target to the users of the first target, because after all, it is the minority who needs those changes.
I tried it with App groups, but that doesn't seem to help in any way.
Is there a way to make the extensions work for both App targets?
There are these option to you:
1.
You can duplicate the extensions, provide id from your developer portal, or let Xcode add them itself, and change the target identifiers to your new target.
2.
The other way is, to change the extensions bundle ids on build actions of the scheme to your currently required ones.
This could look somewhat like this, if you want to use PlistBuddy:
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier fullBundleIdOfExtension" $PROJECT_DIR/Extension\ Directory/Info.plist
fullBundleIdOfExtension is something like com.company.application.extension
This way could cause errors sometimes on the build after a target switch, showing a dialog that the App could not be installed. This requires you to perform a clean build and rebuild.

Apple Watch for Multiple target

I have multiple target in my App like QA,Release,Develop and i want to create watch app for all targets I have already added watch app for QA target and my question is How can i use same classes and storyboard for other targets e.g Release and Develop.
Thanks
You should create a Framework, in which you include all classes and files that you need to access from each target and then include the framework in your targets. Embedding Frameworks in an app
I think a watch app target can only have one companion iOS application. Different target (QA, Release, Develop) means different bundle ID. Watch target bundle ID has to match companion app's bundle ID as its prefix.
For example, com.xxx.yyy.watchkitapp has to have an iOS companion with com.xxx.yyy. Therefore I think it's impossible.
However, if your code base for all targets are roughly the same you can have single target with multiple build Configurations.
Inside Build Settings for the single target, you can set different flags for Preprocessor Macros.
In code, you can do something like this to differentiate each build configuration.
#if QA
// enable QA feature
#elseif RELESE
// disable beta features
#else
// enable everything
#endif

How to configure Bundle ID for iOS Framework targets for App and Appex

There is a KeyboardKit (Swift 3) iOS Framework which I recently decided to separate into two targets KeyboardKit and KeyboardKitAppex. The former will be used within the Application target, the latter within Application Extension target respectively.
To do so, I just duplicated KeyboardKit target, renamed the duppy to KeyboardKitAppex and changed these build settings:
Require Only App-Extension-Safe API set to Yes;
Other Swift Flags is set to -D APP_EXTENSION.
Basically, I have copied this setup from mixpanel-swift. However, mixpanel managed to have the same Bundle ID in the build configuration for all targets. It is somehow replaced with unique Bundle ID during the build stage, and I'd like to know, "how?".
In my framework targets, I had to manually edit the Bundle ID to be unique per target. Otherwise, the app cannot be installed on device, complaining about Bundle ID not being unique among embedded bundles.
How to properly separate an iOS Framework into two targets with less hardcoded configuration (specifically, Bundle ID)?
My current Setup is the following:
KeyboardKit
KeyboardKitAppex
...comparing this with mixpanel-siwft setup:
Mixpanel
MixpanelAppex

Xcode : build two apps in same target (with the same plist)

Now I have 3 targets in my iOS application so I build 3 apps (3 ipa).
But I want to keep only 3 target but I want to generate 6 apps (6 ipa).
On each target I want to create an app and a pilot app.
I really want to keep only 1 plist for app and pilot app.
Only differences with app and pilot app are :
Bundle identifier (to install these two apps on the same device)
Icon application
1 parameter in plist
Few line in code (changing with #IF PILOT add code #ENDIF
It's important to keep the same plist for each target (a target is equivalent to en environment TEST, INT and PROD). Because if I duplicate my target in two target (PROD and PROD PILOT for example) it will be more difficult to maintain thes application because if a day I want to change something in plist I will do the same in PILOT target plist.
So you understand it can create differences if I forget to dusplicate my changements.
Finally it will be great if I can build the app and the pilot app just in 1 build and generate 2 Archives in one time also.
Is it possible ?
And have you ideas for the realisation ?
Me I have just fews ideas like :
Add arguments in my target
Add user defined setting
Add preprocessing macros
Thanks
under your project settings, for each target, look under build settings -> packaging, try set all the info.plist files to point to the same one instead of their own versions.
If it is testing purpose,
Try changing Bundle identifier in Project settings and change Product Name in build settings and take archive files.
It will be deployed as separate app in device.
Thanks Fonix !
My solution use your advice.
I duplicated my 3 targets but an app target and its pilot version are linked to the same plist file.
Moreover, I had a preprocessor macro "PILOTE=1" in each pilote version.
Finally I declare a string in user-defined to define my icon ("ICON -> icon.png or icon-pilote.png) and I declare in CFBundleIcon item0 -> ${ICON}).
And to add part of code I juste declare the code difference in :
#IFDEF PILOTE
//Code Pilot version
#ELSE
//Code standard version
#ENDIF
Is it a nice choice for my needs ?

Adding Framework and App Extension targets to IOS App project, am I doing it correctly?

I'm studying IOS/Swift development and I'd like to build an IOS app that in the future will have its own Today Extension. I've read that it is better to put the common logic (for example the logic that accesses Internet resources, performs some job on the result etc) between the App and its extension into a Custom Framework.. Since I think I'll need to change both Framework and App code during the development of the App, I'd like to avoid building the framework in a separate project, than use Show In Finder function to locate the framework bundle and then drag-and-dropping it within the App project.. So I'd like to know if this is the correct way to set up a Workspace with an App, the framework it uses and the Today Extension of the App:
Create a new Project with an IOS App target
Select the project in the Project Navigator and then Editor->Add Target... and specify a Cocoa Touch Framework
Editor->Add Target... and specify Today Extension
Add the framework in Linked Frameworks and Libraries
In this way I've seen that changes to the Framework sources do not need a Framework target recompilation, maybe because the project knows about the need to recompile framework sources even if I only build & run the IOS App target that uses that framework? Am I doing it right? I've seen that the Today Extension created in such way does not lists the framework in the Build Phases -> Target Dependencies while the IOS App does, but both of them correctly use the updated code of the Framework when I update it.
Then, I've noticed the following warning when I compile the project, but I don't know if it is related to the way I've setup the project:
ld: warning: linking against dylib not safe for use in application extensions: /Users/gianni/Library/Developer/Xcode/DerivedData/TestFrameworkApp-dshihhfiuepeqzddbnpgnfwilhem/Build/Products/Debug-iphonesimulator/TestFramework.framework/TestFramework
BTW is it normal that the entries within the Products folder are always red? Is it due to the fact that I build only for IOS Simulator since I don't have a Paid developer account that allows me to build for an IOS Device? Does this prevent me to build a framework that can be exported for some other Project since I can't find the Framework bundle with a right clicking on the framework product and selecting Show In Finder (and so I can't drag-and-drop it to another project)?
I hope I've been clear enough and that you'll point me in the right direction to understand what is the suggested way of starting my new project :)
It sounds to me like you're headed down the exact path I would take.
Regarding the warning you're seeing... I believe that checking the "Allow app extension API only" for your shared framework will supress that and cause build failures when you attempt to use a API that is not allowed in extensions.

Resources