Target Properties changes by xcodebuild command - ios

How can i manipulate my iOS Target Properties by xcodebuild command tool ?
In example, i have one project with one target and with Facebook SDK Key in Target Properties in Info tab
FacebookAppID: 01234567891234
And with console command xcodebuild i'm compiling two Apps with Developer and Production provisions with two console commands:
For Developer:
xcodebuild -project Projectname.xcodeproj clean install OBJROOT=ObjRoot ... CODE_SIGN_IDENTITY={iPhoneDeveloper} PROVISIONING_PROFILE="Dev.mobileprovision"
For Distribution:
xcodebuild -project Projectname.xcodeproj clean install OBJROOT=ObjRoot ... CODE_SIGN_IDENTITY={iPhoneProduction} PROVISIONING_PROFILE="Prod.mobileprovision"
And i need use in Developer one FacebookAppID, and in Production a other FacebookAppID, and how i can change my command lines for realize this?
Thanks

Arguments to xcodebuild are best used for values that change every time they're invoked, like a destination directory that includes a build number.
For data as foundational as a Facebook app ID, I'd recommend using your build configurations, e.g. "Debug" and "Release". Create a user-defined build setting (in Xcode 5.0.2, Editor -> Add Build Setting -> Add User-Defined Setting) named something like "FACEBOOK_ID", and in your Info.plist, set your desired key's value to ${FACEBOOK_ID}. In your target's build settings, define FACEBOOK_ID differently for your Debug and Release configurations. Your code then now has to pull the current value out of Info.plist at runtime.
If you really want to override build settings as arguments to xcodebuild, you can do so, just by adding "FACEBOOK_ID=12341234" to the end of the command, but this only works if you've done the work I just described to make FACEBOOK_ID into a configuration-specific build setting. I can't think of any sound reasons to keep this kind of app data outside of a build configuration.
If build configurations are new to you, I'd suggest starting with WWDC 2012 session 408, "Working with Schemes and Projects in Xcode".

Related

Add value to Info.plist array after building (but before installing)

I have an Xcode project that builds into a few different apps (whitelabels) using different configurations.
For a new payment method I need each app to have a unique CFBundleURLScheme.
I wrote the following "Run Script" that is before Compile Sources in "Build Phases".
INFO_PLIST="${PROJECT_DIR}/${INFOPLIST_FILE}"
plutil -insert CFBundleURLTypes.0.CFBundleURLSchemes.0 -string "swish${PRODUCT_BUNDLE_IDENTIFIER//.}" $INFO_PLIST
This adds the value swishourbundleidentifier. (So, swish + our.bundle.identifier, but without the dots)
This currently changes the actual Info.plist. What I want is that it changes the Info.plist that's in the folder where the app is built to, so that it is overridden each time (so there are no double values) and that the added value doesn't show up in git.
How would I go about that? I guess it's simply changing "${PROJECT_DIR}/${INFOPLIST_FILE}", but to what?
If any more information is needed, please let me know.
EDIT: Actually, if it is possible, a better solution would be to add something like swish${PRODUCT_BUNDLE_IDENTIFIER//.} in the Info.plist's URL Schemes. So that it's compiled to that on build time, but no double values. I tried this but it doesn't seem to work like that unfortunately.
You could access to build directory with
$CONFIGURATION_BUILD_DIR/$CONTENTS_FOLDER_PATH
Reference: https://help.apple.com/xcode/mac/10.2/#/itcaec37c2a6
(Xcode 11.2)
It is possible to do what you're asking:
You can get the path of the app bundle's Info.plist at ${TARGET_BUILD_DIR}/${INFOPLIST_PATH}.
BUT: In the New Build System, any custom build steps will run before the New Build System's Process .../Info.plist step, so you cannot edit the app bundle's plist via a Run Script step to Build Phases, because your changes will just be overwritten:
To run a shell script after Xcode finishes building, you can add it to your scheme(s) as a build post-action:
Product > Scheme > Edit Scheme... > Build > Post-actions
If you're going to reference any build system environment variables (e.g. BUILT_PRODUCTS_DIR or INFOPLIST_PATH), make sure you select your app target in Provide build settings from.
Add your shell script, but remember that if you edit any file in the app bundle (i.e. Info.plist), you'll need to re-sign the app. Add this to your script:
export CODESIGN_ALLOCATE=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/codesign_allocate
/usr/bin/codesign --force --sign - --entitlements "${TARGET_TEMP_DIR}/${FULL_PRODUCT_NAME}.xcent" --timestamp=none "${CODESIGNING_FOLDER_PATH}"
App bundle is read-only. Info.plist is in app bundle

Specify individual target build settings with xcodebuild

I have an iOS app that uses Cocoapods, and has a local cocoa touch framework target, and I'm running into an issue with specifying build settings in the command line using xcodebuild.
I understand that you can specify build settings like PROVISIONING_PROFILE, CODE_SIGN_IDENTITY, and DEVELOPMENT_TEAM by appending their key=value pair to the end of the command.
However those setting appear to be applied to the entire project, but I only need them to apply to the app target since touch frameworks cannot be signed.
How do I specify build settings for an individual target using xcodebuild? If it cannot be done using xcodebuild, could this be accomplished using fastlane?
Use schemes. You can set the scheme to build/archive with a particular build configuration and executable.

Build os x tool as part of iOS project without breaking xcodebuild archive?

Each time I build my iOS project, I'd like to it also build a couple OS X projects. These are command line tools. I don't care if they're included in the Archive, I just want to make sure they compile correctly each and every time.
They're little command line tools for specific tasks which access the same libraries. In the past, I've built these far less frequently and as a result they suffer from code rot. I'd like to build them each time I build the iOS project, even when I just Build in Xcode.
To do this, I tried dragging the projects into my iOS project and set them as dependancies.
This works fine in the IDE, but when I try to build via xcodebuild:
xcrun xcodebuild -sdk iphoneos -workspace AppName.xcworkspace \
-scheme AppName archive
I get an error that looks like this:
=== BUILD TARGET dslfi OF PROJECT dslfi WITH CONFIGURATION Release ===
Check dependencies
target specifies product type 'com.apple.product-type.tool', but there's no such
product type for the 'iphoneos' platform
** ARCHIVE FAILED **
The following build commands failed:
Check dependencies
(1 failure)
Is there any way to continue to build these each time I build while still satisfying xcodebuild?
You can add any number of targets (iOS app, static lib, contole app, etc) into same project.
Then you should create another target -
Then you have options:
3.1 Go to scheme settings for aggregate target and add other targets:
where you can specify actions you want to perform on certain target
3.2 You may pick aggregate target and go to build settings and add other targets as a dependencies for this target.
Option 3.1 seems to be the one you need: you can add as many targets as you wish to be build. And you can specify another target for running.
So you'll have something like:
targets:
target 1 - iOS app
target 2 - other app
target 3 - other app
target 4 - aggregate target
scheme configuration for target 4
build section:
target 1
target 2
target 3
run section:
executable: target 1 (iOS app)
Once this is completed you may use your scheme to do builds
xcodebuild -scheme your_scheme [...other options...] archive
UPDATE
You can skip creation of aggregate target.
You can directly create new scheme and to the configuration you want without involving aggregate target.
UPDATE 2
Make sure to share your scheme to be able to keep it in source control.
UPDATE 3
The option w/o aggregate target is more preferable way to achieve this in case if your targets are not depend on each other directly (as far as I understand you). This is the main purpose for schemes.
A scheme is a collection of settings that specify which targets to
build, what build configuration to use, and the executable environment
to use when the product specified by the target is launched. When you
open an existing project (or create a new one), Xcode automatically
creates a scheme for each target.

Lipo error with additional schemes in XCode

I want to create additional build configurations and schemes in my XCode project in order to build sepcific archives for TestFlight. One connected to our DEV environment for internal testers, and one connected to our PROD environment for external beta testers.
So I was following this excellent blog post and I created 2 additional build configurations by duplicating the Release one. Then I created 2 additional schemes based on the default one, by changing the build configuration of the Archive build operation to the proper build configuration. Finally I set some user-defined settings in each build configuration to point to the right server URL depending on whether we are in a DEV build or a PROD build.
But now when I archive my project using one of these two additional schemes, I get the following Lipo error:
/fatal error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/lipo: can’t open input file: /Users/sarbogast/Library/Developer/Xcode/DerivedData/Build/Intermediates/ArchiveIntermediates/MyAppTestFlightPROD/IntermediateBuildFilesPath/MyApp.build/TestFlight PROD-iphoneos/MyApp.build/Objects-normal/armv7/MyApp (No such file or directory)
And indeed when I go to /Users/sarbogast/Library/Developer/Xcode/DerivedData/Build/Intermediates/ArchiveIntermediates/MyAppTestFlightPROD/IntermediateBuildFilesPath/MyApp.build/TestFlight PROD-iphoneos/MyApp.build/Objects-normal/armv7 directory, there is no MyApp file or directory in there.
I read here and there that setting 'Build Active Architecture only' to YES might solve the problem, but I don't want to do that as these are release builds for TestFlight and I want them to work on all architectures.
Any idea what might be wrong in my set up?
I am using CocoaPods and I had log messages saying that the linker could not find Pods for my new scheme. So I added my new scheme to link_with in my podfile and now it works perfectly.
I still don't understand why, because I thought link_with was only to list targets and this is not a target, this is a scheme. But it works.

xcodebuild workspace and scheme

I am a little confused as to what happens with the xcodebuild command line tool when you specify a workspace and scheme.
I understand how a configured scheme works in the XCode IDE GUI. The build action lists the targets to build and for each action (Analyze, Test, Run, Profile, Archive), you select which one you want the build action to execute for.
So if I have each action (Analyze, Test, Run, Profile, Archive) selected in the build action for building, what happens when I execute the below command.
xcodebuild clean install -workspace MyWorkspace.xcworkspace -scheme MyScheme
-configuration AdHoc SYMROOT=PATH DSTROOT=PATH...
It searches for MyScheme.xcscheme in the main xcodeproj which has all this configuration specified when editing the scheme in XCode.
What does xcodebuild read in from this file? Does it just build the configured target with the AdHoc configuration and disregard everything else?
You're almost there, but your syntax is a bit off.
According to the man page:
xcodebuild -workspace workspacename -scheme schemename [-configuration configurationname]
[-sdk [sdkfullpath | sdkname]] [buildaction ...] [setting=value ...]
[-userdefault=value ...]
Where buildaction is one of the following:
buildaction ...
Specify a build action (or actions) to perform on the target. Available build actions are:
build Build the target in the build root (SYMROOT). This is the default build action.
archive Archive a scheme from the build root (SYMROOT). This requires specifying a scheme.
test Test a scheme from the build root (SYMROOT). This requires specifying a scheme.
installsrc Copy the source of the project to the source root (SRCROOT).
install Build the target and install it into the target's installation directory in the dis-
tribution root (DSTROOT).
clean Remove build products and intermediate files from the build root (SYMROOT).
In the Xcode IDE, you choose the buildaction to run through the Product menu, or by clicking and holding the round button on the top left of the IDE (Run = Play triangle, Test = wrench icon, etc).
Also, be careful to note where xcodebuild is looking for your build scheme - it can either be in your .xcproj OR your .xcworkspace file, depending on which one you created.
(If you didn't manually create a workspace, you will have a .xcproj file).
You can also ascertain which schemes you have via your 'Manage Schemes' setting in Xcode.

Resources