Custom xcconfigs
Last modified on Wed 17 Jan 2024

Usually, when you work in a team environment, and/or when you need to use multiple configurations, Xcode project settings UI can quickly get really messy, and it becomes hard to track changes.

git log is not really useful with the amount of noise you get by changing one simple bool.

Proposed project structure (xcconfig files, build targets, build configurations)

Configuration structure

Configurations
    |
    |-----> Shared (Project settings - Inherited from Xcode and custom (e.g. extra CLANG warnings))
    |   |
    |   |-----> Project - Shared.xcconfig
    |   |-----> Project - Debug.xcconfig
    |   |-----> Project - Release.xcconfig
    |   |-----> Project - QA.xcconfig
    |
    |-----> Target0
    |   |
    |   |-----> Target0 - Shared.xcconfig
    |   |-----> Target0 - Debug.xcconfig
    |   |-----> Target0 - Release.xcconfig
    |   |-----> Target0 - QA.xcconfig
    |
    |-----> Target1
    |   |
    |   |-----> Target1 - Shared.xcconfig
    |   |-----> Target2 - Debug.xcconfig
    |   |-----> Target3 - Release.xcconfig
    |   |-----> Target4 - QA.xcconfig

Shared

Target

xcconfig

// Asset Catalog App Icon Set Name
//
// Name of the asset catalog app icon set whose contents will be merged into the
// Info.plist.

ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon

// Code Signing Identity
//
// The name ("common name") of a valid code-signing certificate in a keychain within your
// keychain path.   A missing or invalid certificate will cause a build error.

CODE_SIGN_IDENTITY = iPhone Developer


// Info.plist File
//
// This is the project-relative path to the plist file that contains the Info.plist
// information used by bundles.

INFOPLIST_FILE = Park-AAA copy-Info.plist


// Runpath Search Paths
//
// This is a list of paths to be added to the runpath search path list for the image
// being created.  At runtime, dyld uses the runpath when searching for dylibs whose load
// path begins with '@rpath/'. [-rpath]

LD_RUNPATH_SEARCH_PATHS = $(inherited) @executable_path/Frameworks


PRODUCT_BUNDLE_IDENTIFIER = infinum.co.Park-BBB


// Product Name
//
// This is the basename of the generated product.

PRODUCT_NAME = $(TARGET_NAME)

Build targets

Build configurations

User-defined keys

[[NSBundle mainBundle] objectForInfoDictionaryKey:@"HockeyKey"]];

Custom xcconfigs

Step 0—empty project

Step 1—targets

Step 2—add new build configurations

Step 3—build settings

Project

Target

Step 4—custom xcconfig

Step 5—set up custom xcconfig

Resolved | Target0 | Config.File (Target Build) | Project | Config.File (Project Build)| iOS Default

Step 6—custom Info.plist

The great thing about custom Info.plist is that you can easily set up custom AppIcon, Assets Catalog...

Step 7—Cocoapods

platform :ios, '8.0'

use_frameworks!

# Debug/release config specification
# You need to add the same configuration names you have set in the project file
project 'Project', {
  'Debug' => :debug,
  'Release' => :release,
  'ClientDebug' => :debug,
  'ClientRelease' => :release
}

# If you need a pod only for some configurations, eg. only for debug and release
def debugging
  pod 'Sentinel', :configurations => [
    'Debug',
    'Release'
  ]
end

def shared
    pod 'Alamofire'
end

# If you have targets which use the same pods, you can combine them into an abstract target
# then you won't need to specify every single target like we do below.
# You can use either this or specify every single target
# abstract_target 'MainTargets' do
  # Shared pods
#  shared
#  debugging

#  target 'Target0'
#  target 'Target1'

#end

target 'Target0' do
   shared
   debugging
end

target 'Target1' do
   shared
   debugging
end

Build a project :)

Resources