Skip to content

Instantly share code, notes, and snippets.

@pnc
Last active August 29, 2015 14:24
Show Gist options
  • Save pnc/9c3ed45a9e450029a518 to your computer and use it in GitHub Desktop.
Save pnc/9c3ed45a9e450029a518 to your computer and use it in GitHub Desktop.
Declare Xcode project files
require 'xcodeproj'
# Avoid spaces, otherwise automatic crash symbolication breaks.
# To change how it appears to the user, set Bundle Display Name in the Info plist.
TARGET_NAME = "ExampleApp"
CONFIG = {"APP_BUNDLE_ID" => "com.example.example-app",
"ASSETCATALOG_COMPILER_APPICON_NAME" => {debug: "AppIconDevelopment",
release: "AppIcon"},
"ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME" => "LaunchImage"}
proj = Xcodeproj::Project.new("#{TARGET_NAME}.xcodeproj")
app_target = proj.new_target(:application, TARGET_NAME, :ios, '7.0')
TARGET_GLOB = "*.{m}"
RESOURCE_GLOB = "*.{png,xib,xcassets,bundle,json,response,strings}"
def create_files(target, group, directory, depth=0)
Dir.glob("#{directory}/*") do |item|
# Even though localized resources look like directories, don't recurse into them
if File.fnmatch?("*.lproj", item)
# Recurse without creating a group
create_files(target, group, item, depth)
elsif File.directory?(item) && !File.fnmatch?(RESOURCE_GLOB, item, File::FNM_EXTGLOB)
group_name = File.basename(item)
puts "#{" " * depth}+ #{group_name}"
create_files(target, group.new_group(group_name), item, depth + 1)
else
puts "#{" " * depth}- #{item}"
ref = group.new_file(item)
if File.fnmatch?(TARGET_GLOB, item, File::FNM_EXTGLOB)
target.add_file_references([ref])
elsif File.fnmatch?(RESOURCE_GLOB, item, File::FNM_EXTGLOB)
target.add_resources([ref])
end
end
end
end
def all_configurations(target)
yield target.build_settings("Debug")
yield target.build_settings("Release")
end
def clear_ldflags(target)
all_configurations(target) do |config|
config.delete("OTHER_LDFLAGS")
end
end
# Recursively read source files from the "Classes" directory,
# adding them to the application's target compile step as needed.
classes_group = proj.main_group.new_group("Classes")
create_files(app_target, classes_group, "Classes")
# Recursively read source files from the "Assets" directory,
# adding them to the application's copy resources step as needed.
assets_group = proj.main_group.new_group("Assets")
create_files(app_target, assets_group, "Assets")
# Create a unit test target
test_target = proj.new_target(:unit_test_bundle, 'Acceptance', :ios, '7.0')
test_target.add_dependency(app_target)
# Populate the unit test target with test files
# and fixtures from the "Acceptance/" directory.
classes_group = proj.main_group.new_group("Acceptance")
create_files(test_target, classes_group, "Acceptance")
# Xcodeproj sets these by default, but CocoaPods wants them to be inherited
clear_ldflags(app_target)
clear_ldflags(test_target)
# Example of custom build step:
# clear_plist = proj.new(Xcodeproj::Project::Object::PBXShellScriptBuildPhase)
# clear_plist.name = "Force Info.plist rebuild"
# clear_plist.shell_script = "rm -f \"${CONFIGURATION_BUILD_DIR}/${INFOPLIST_PATH}\""
# clear_plist.show_env_vars_in_log = '0'
# app_target.build_phases.unshift(clear_plist)
all_configurations(app_target) do |config|
config["GCC_PREFIX_HEADER"] = "Classes/Supporting Files/Application-Prefix.pch"
config["INFOPLIST_FILE"] = "Classes/Supporting Files/Application-Info.plist"
end
all_configurations(test_target) do |config|
config["TEST_HOST"] = "$(BUILT_PRODUCTS_DIR)/#{TARGET_NAME}.app/#{TARGET_NAME}"
config["BUNDLE_LOADER"] = "$(TEST_HOST)"
end
CONFIGURATION_NAMES = {debug: "Debug", release: "Release"}
CONFIG.each do |key, value|
if value.respond_to?(:each)
value.each do |config_name, value|
settings = app_target.build_settings(CONFIGURATION_NAMES[config_name])
settings[key] = value
end
else
all_configurations(app_target) do |config|
config[key] = value
end
end
end
proj.save
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment