I set up multiple environments for my app by creating multiple configurations, with multiple schemes for each configuration (Article Describes in more detail my set up). Therefore I only have to have one target. This works fine for the actual app itself but I'm having trouble doing the same setup within an app widget extension. The production scheme works fine but when trying to build the dev side scheme I'm receiving this error.
/Users/ss/Library/Developer/Xcode/DerivedData/appName-hdbxzenesdshvnfgnywdjhuifcbu/Build/Products/Debug Development-iphoneos/AppNameWidgetExtension.appex error build: : No such file or directory
When I look through the derived data I can see the dev versions .appex. AppNameWidgetExtension-dev.appex but it seems to be looking for the none dev versions .appex. I would like to be able to continue to use one app target and one extension target but not sure how to get the dev widget extension to refer to the correct .appex file.
I noticed that embedded foundation extensions within the app target only referes to the dubug Production .appex. How could I change this .appex based on current scheme? Screen shot below
Scheme setup (The same setup as article I've attached)
Ive seen similar problems here but most are referring to having multiple targets and id much rather keep my current environment only using one target for multiple configurations.
Update:
So I think my issue was renaming the product name in packaging (within the build settings of app target) which would change the product module name too. Instead, I put it back to $(TARGET_NAME). I was changing the product module name to change the app display name on phone so instead I added Bundle Display name key and set the value to $(APP_NAME) (app name is from config files) to app targets plist. I also moved all my configuration settings into config files and added config files to project configurations. I used this tutorial to help me set up my project with xcconfig files.
Related
Hi I have been working on my first iOS app. I have completed all of its requirements. Now its time to distribute. But before distribution I want to manage things well.
I searched for it and got "Target" as what I wanted. now just suppose the following requirement:
I have Client 1 and Client 2, and they both have different web addresses and Images and App Master password.
Now the 1 thing is to change them manually before making the build. But I wanted more proper way. So I thought of creating a Config file per target per client. but I am not getting it done.
Because after adding "Config" file for client 1 I am unable to create the 2nd "Config" file for Target 2 which indicates the client 2.
Please help me I am confused. Thanks in advance
Once you have different targets, you also have different property list attached to it. This allows you to customise some elements of your configuration for a specific target.
In this example, I duplicated my target and have now two targets, two schemes and two .plist files. I can customise one .plist without affecting the other target.
Another way to solve this problem is to create two configuration files in Swift. For instance, you can create a AppConfig struct foreach app configuration and attach it to one target at a time. It could be under AppConfig.swift and AppConfigDemo.swift, both with following code but different url in it.
struct AppConfig {
let urlString = "https://myclienturl.com"
}
The key is to include each file into the right target. Here, this AppConfig.swift is available with Test target. It won't be accessible in TestDemo target. You can do the same foreach one of your client.
Make sure they have different names, Info.plist and Client2-Info.plist (for example).
and you can set targets config file in its build settings. just search for Info.plist and set the relative path to the configuration you need.
I am currently working on an iOS project in XCode that uses configurations to specify the different API environments my app can connect to. Additionally, I use targets to override one of my project configuration's user-defined values to specify a particular configuration file to use in the app. However, this is the only value that changes in the target. I work with multiple different configuration files (maybe 10 to 20 at a time) and creating a new target for each file to update one value seems clunky.
My question: Is there a way to pass this one value in from the scheme instead of setting it in the target?
I have seen that there is a pre-build script that can be run but I have not yet had any success exporting environment variables.
CONFIG_FILE="My Config File"
export CONFIG_FILE
I have also seen that some people have had success using PlistBuddy to write the values into the info.plist file during the pre-build phase of the scheme. This may be an option as well although it would require I redo a lot of my build process. I wanted to see if there was any other options before heading down this path.
Thanks for the help.
I was able to do this by using a .xcconfig file that is updated during my pre-build action in my scheme.
I used this tutorial to learn how to set up the project: http://www.jontolof.com/cocoa/using-xcconfig-files-for-you-xcode-project/
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.
I have a project that I maintain for a client; let's call it MyDataAssistant. When the project goes into beta, the client likes to have a "separate app" built for them, which I create using a different provisioning profile and a modified bundle identifier (MyDataAssistant-BETA). It's a pain to always be going back and forth and changing the bundle identifier, code signature settings, and especially the icon. I understand that you can have multiple targets and multiple build settings (within each target?) in a project, but I'm not clear on what the difference is, or how to use them appropriately.
Additionally, the client would like a third version with read-only capabilities. I can accomplish this by just making a flag return from a certain part of my code, but I would like it if that flag could be toggled in the build (target?) settings.
Please advise on how to manage this kind of project with multiple "variations" of the build.
Add a new configuration to your project by duplicating the release one for example.
Give it a name "Beta"
Add a User-defined build setting
Call it MY_DATA_ASSISTANT_BUNDLE_ID_SUFFIX for example and set the value to be -BETA only for the Beta configuration.
Edit the MyDataAssistant-info.plist file by setting the bundle identifier to com.YOURCOMPANYNAME.MyDataAssistant$(MY_DATA_ASSISTANT_BUNDLE_ID_SUFFIX)
This will make it have different values for the different configurations.
You can also set the display name to have a different value by setting it to $(PRODUCT_NAME)$(MY_DATA_ASSISTANT_BUNDLE_ID_SUFFIX)
Set the right provisioning profile for each configuration. (Of course after creating the beta one in the provisioning portal as if it was for a new app with the bundle identifier having the suffix "-BETA")
Create a new scheme!
Give it a name: MyDataAssistant-BETA
Change its build configuration to "Beta" for all the actions and you should be ready to go.
If you want to have different icons for the beta version you can use the $(MY_DATA_ASSISTANT_BUNDLE_ID_SUFFIX) in the MyDataAssistant-info.plist file for the icons names and of course add them to the target.
I would recommend creating two targets. This will allow you to share what files you want between variations, as well as have custom source, or config files in each. The simplest implementation of this would be to have an identical target except for the info.plist file.
Simply right click on your current app target in project settings, and hit duplicate.
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.