xcodebuild where is the output binary? - ios

Sorry, I'm very new to iOS development.
I'm building a Cordova/Meteor app. Meteor creates a build directory, and I'd like a command line script to build the binary to upload to itunesconnect.
Here's what I have so far:
#!/bin/bash
CODE_SIGN_IDENTITY="Michael"
NAME="appExpertAlerts"
# Create the xcode project
meteor add-platform ios
echo "STARTING BUILD"
meteor build ../../ops/production/ios \
--mobile-settings ../../ops/production/meteor/settings.json \
--server https://phone.app.io:443 \
--verbose
meteor remove-platform ios
popd
# Build the xcode project
pushd ios/ios/project
xcodebuild \
build \
-sdk iphoneos \
-configuration Release \
-xcconfig cordova/build.xcconfig \
-project "$NAME.xcodeproj" \
-target "$NAME" \
SHARED_PRECOMPS_DIR=$(pwd)/build/sharedpch \
CODE_SIGN_IDENTITY="$CODE_SIGN_IDENTITY" \
ARCHS="armv7 armv7s arm64" \
VALID_ARCHS="armv7 armv7s arm64" \
CONFIGURATION_BUILD_DIR=$(pwd)/build/device \
popd
The build says it's a success, and I can see output files, but I can't find the binary to upload to itunesconnect.
Where is the output binary? Or how do I create one?

I have not yet implemented an automation of the build-upload to itunesconnect, sounds interesting :-)
Yet, after the build has been triggered, I think, what you try to achieve would be better implemented as a "run script" build phase. There you have the variables set as described here:
https://developer.apple.com/library/mac/documentation/DeveloperTools/Reference/XcodeBuildSettingRef/1-Build_Setting_Reference/build_setting_ref.html#//apple_ref/doc/uid/TP40003931-CH3-SW42
Especially interesting for you should be TARGET_BUILD_DIR:
TARGET_BUILD_DIR
Description: Directory path. Identifies the root of the directory
hierarchy that contains the product’s files (no intermediate build
files).
Run Script build phases that operate on product files of the
target that defines them should use the value of this build setting.
But Run Script build phases that operate on product files of other
targets should use BUILT_PRODUCTS_DIR instead.
Example values:
/Volumes/Users/genica/MyProject/build/Debug
/tmp/MyProject.dst/Users/genica/Applications
/Volumes/Users/genica/MyProject/build/UninstalledProducts Related to:
DEPLOYMENT_LOCATION (Deployment Location), INSTALL_PATH (Installation
Directory), SKIP_INSTALL.
The variables can be accessed as ${VAR NAME} in your script.
The .ipa archive can be created as shown in this SO article: Xcode "Build and Archive" from command line
You may pay special attention to the shenzen tool, which is, if I understand you correctly, exactly what you are currently building. https://github.com/nomad/shenzhen

Related

How does the XCode-Run-Command look like?

For an automatic testing purpose, I have to build & run a XCode Project. Right now i prepare my project using scripts, then I open XCode, chose the right scheme and click the run-button. Afterwards I run my test script. All works fine!
I have to eliminate the manual steps (open XCode, run Project) and use scripts as well. Until now I did not yet figure out how to build and run my project exactly the same way as XCode does. I tried with the commands xcodebuild, xcrun simctl, ios-sim and all kind of parameters.
How can I fire the exact same command in the terminal? Thanks!
Edited
I reference to this question https://github.com/calabash/calabash-ios/issues/1076, which is the root of this question.
I tried again using both the "Debug Config" and the "-cal target" approach (https://github.com/calabash/calabash-ios/wiki/Tutorial%3A-How-to-add-Calabash-to-Xcode). Both possibilities work perfect if I do a manual build in Xcode. I studied jmoodys Examples and tried the following (I changed it a bit cause of the nature of my Ionic project):
xcrun xcodebuild \
TARGET_BUILD_DIR=\$BUILT_PRODUCTS_DIR \
DWARF_DSYM_FOLDER_PATH=\$BUILT_PRODUCTS_DIR \
-xcconfig cordova/build-debug.xcconfig \
-project './ABC.xcodeproj' \
-scheme 'ABC-cal' \
-configuration Debug \
-sdk iphonesimulator \
-SYMROOT="build/app" \
ARCHS="i386 x86_64" \
VALID_ARCHS="i386 x86_64" \
ONLY_ACTIVE_ARCH=NO \
build
The build runs without any error, creates the app at the exact same location as the xcode build and cucumber runs and opens the app, BUT the steps are never executed and I dont get any error. I guess my build is still not exact the same?
There are example scripts in these repositories:
Permissions
CalSmokeApp
CalWebApp
iPhoneOnlyApp
The Permissions repo is the easiest to understand. You can probably just grab the bin/make/app.sh and bin/make/ipa.sh and update a couple of environment variables.
I can't be sure, but I think you posted this exact question as an issue on Calabash iOS. If so, please don't cross post. I answered your question there, provided the same examples, and asked you follow up questions that you did not respond to.

Continuous integration of an iOS project in a workspace with Jenkins and Fabric

I have a workspace with multiple projects in it. In one of the project I am using Fabric to distribute my build to beta testers. It works perfectly as expected.
Then I moved to continuous integration with Jenkins. Build is successful. However, Fabric doesn't upload the dSYM file.
I have the following script in Execute Shell of Jenkins
Note: Fabric.framework/run command is added in Build phase of the project
=====================================================
ARCHIVE_DEST_PATH="${WORKSPACE}/archive"
ARCHIVE_PACKAGE="${ARCHIVE_DEST_PATH}.xcarchive"
PROJECT=<project>
FRAMEWORK=<project-sdk>SharedSDK
cd ${WORKSPACE}
if [ -f "$ARCHIVE_PACKAGE/Info.plist" ]; then
rm -r "$ARCHIVE_PACKAGE"
fi
xcodebuild -workspace <project-ws>.xcworkspace -scheme ${FRAMEWORK}
xcodebuild -workspace <project-ws>.xcworkspace -scheme ${PROJECT} -archivePath ${ARCHIVE_DEST_PATH} archive
Mike from Fabric here.
If you're using Jenkins, then you want to add a script such as this:
/path/to/Crashlytics.framework/submit <API_KEY> <BUILD_SECRET> \
-ipaPath /path/to/my.ipa -emails TestEmail#fabric.io,AmazingTester#twitter.com \
-notesPath ~/Notes/ReleaseNotes.txt \
-groupAliases GroupAlias,GroupAlias2 \
-notifications YES
as mentioned in our documentation.

Is it possible to include a .framework in a .framework and how?

i'd like to mention this question Include a framework into another one, is it possible? and this Include an iOS Framework into another one.
Also there is a similar to the target question from me as well, https://stackoverflow.com/questions/23022211/create-framework-including-plcrashreporter-linked-xcodeproj-source-code-to-the.
I want to achieve the same thing. Don't want the developer to have to link to both frameworks but only mine which is merged with the other.
Both questions in the link have no answer. Any update on the subject?
P.S. I have the source code also but this is not an option since it introduces several problems.
How can I do it, any tutorials, blog, book etc?
Thank you.
Yes, it is possible to include a .framework in a .framework. I've never done it, but i know coacoapods does that and older version of parse framework used to include the facebookSDK so you could start researching into how parse did it, by downloading older versions of parse.
This doesn't answer the question so i will delete it when an answer is posted, but at least you have a information you could use to do research to find the answer :D
Here try using this Wenderlich Tutorial to make a static library. From there you can start toying around with the settings. Make sure that any framework you create has the #import statement in the main header file. You know the -Project/Project.h- that is common in most frameworks, in that .h file have all the import statements.
I have found the solution creating an aggregate target and adding the following run script in the build phase section.
I will name the static library target name as StaticLibraryName for the example.
xcodebuild -project "StaticLibraryName.xcodeproj" -configuration "Release" -target "StaticLibraryName" -sdk iphoneos
xcodebuild -project "StaticLibraryName.xcodeproj" -configuration "Release" -target "StaticLibraryName" -sdk iphonesimulator
mkdir -p "${SRCROOT}/Products/StaticLibraryName.framework"
mkdir -p "${SRCROOT}/Products/StaticLibraryName.framework/Versions"
mkdir -p "${SRCROOT}/Products/StaticLibraryName.framework/Versions/A"
mkdir -p "${SRCROOT}/Products/StaticLibraryName.framework/Versions/A/Resources"
mkdir -p "${SRCROOT}/Products/StaticLibraryName.framework/Versions/A/Headers"
ln -s "A" "${SRCROOT}/Products/StaticLibraryName.framework/Versions/Current"
ln -s "Versions/Current/Headers" "${SRCROOT}/Products/StaticLibraryName.framework/Headers"
ln -s "Versions/Current/Resources" "${SRCROOT}/Products/StaticLibraryName.framework/Resources"
ln -s "Versions/Current/StaticLibraryName" "${SRCROOT}/Products/StaticLibraryName.framework/StaticLibraryName"
cp -R "build/Release-iphoneos/usr/local/include/" "${SRCROOT}/Products/StaticLibraryName.framework/Versions/A/Headers/"
lipo -create "build/Release-iphoneos/libStaticLibraryName.a" "build/Release-iphonesimulator/libStaticLibraryName.a" -output "${SRCROOT}/Products/StaticLibraryName.framework/Versions/A/StaticLibraryName"
libtool -static -o "${SRCROOT}/Products/StaticLibraryName.framework/Versions/A/TheOtherFrameworkName" "${SRCROOT}/Products/StaticLibraryName.framework/Versions/A/TheOtherFrameworkName" "${SRCROOT}/Vendor/TheOtherFrameworkName.framework/Versions/A/TheOtherFrameworkName"

Azure Mobile Services iOS Library fails to build with Release configuration

When archiving my iOS app the Windows Azure Mobile Services library fails to build.
The App builds fine when using Debug configuration.
While running this script:
/bin/sh -c \"/Users/user/Library/Developer/Xcode/DerivedData/myapp-bxucrfbhixkrpqfwaaovtqqpsvyd/Build/Intermediates/ArchiveIntermediates/MyApp\ (testing)/IntermediateBuildFilesPath/WindowsAzureMobileServices.build/Release-iphoneos/WindowsAzureMobileServices.build/Script-E8E37A27161FAA9600C13F00.sh\"
This turns out to be, this script form the "Build Phases" tab:
# Exit immediately on any errors
set -e
# Set some variables
OUTPUT=${BUILT_PRODUCTS_DIR}
WAMS="WindowsAzureMobileServices"
WAMS_FRAMEWORK="${WAMS}.framework"
WAMS_LIB="lib${WAMS}.a"
HEADERS="Headers"
# Create the needed directories for the framework
mkdir -p "${OUTPUT}/${WAMS_FRAMEWORK}/Versions/A"
mkdir -p "${OUTPUT}/${WAMS_FRAMEWORK}/Versions/A/Headers"
# Add the headers and lib to the framework
cp -a "${OUTPUT}/${HEADERS}/" "${OUTPUT}/${WAMS_FRAMEWORK}/Versions/A/Headers"
lipo -create "${OUTPUT}/${WAMS_LIB}" -output "${OUTPUT}/${WAMS_FRAMEWORK}/Versions/A/${WAMS}"
# Set up the links to complete the framework
ln -sf Versions/Current/Headers "${OUTPUT}/${WAMS_FRAMEWORK}/Headers"
ln -sf "Versions/Current/${WAMS}" "${OUTPUT}/${WAMS_FRAMEWORK}/${WAMS}"
ln -sf A "${OUTPUT}/${WAMS_FRAMEWORK}/Versions/Current"
It fails with this error:
cp:
/Users/user/Library/Developer/Xcode/DerivedData/MyApp-bxucrfbhixkrpqfwaaovtqqpsvyd/Build/Intermediates/ArchiveIntermediates/MyApp
(testing)/BuildProductsPath/Release-iphoneos/Headers/: No such file or
directory
I'm assuming that the error corresponds to this line:
cp -a "${OUTPUT}/${HEADERS}/" "${OUTPUT}/${WAMS_FRAMEWORK}/Versions/A/Headers"
I cannot see any differences in the build settings between Release and Debug.
Update
After some investigation I have determined that when Xcode archives a product it does not create the "headers" folder in ${BUILT_PRODUCTS_DIR}. It instead puts them in `/Build/Intermediates/ArchiveIntermediates/UninstalledProducts'. So the script fails.
Setting the "Skip Install" to NO for the Release build and then checking for the existence of the ${INSTALL_DIR} in the script will successfully build the library.
if [ -d "${INSTALL_DIR}" ]; then
cp -a "${INSTALL_DIR}/" "${OUTPUT}/${WAMS_FRAMEWORK}/Versions/A/Headers"
else
cp -a "${OUTPUT}/${HEADERS}/" "${OUTPUT}/${WAMS_FRAMEWORK}/Versions/A/Headers"
fi
However, Xcode failed to build because it can't find the headers:
fatal error: 'WindowsAzureMobileServices/WindowsAzureMobileServices.h' file not found
#import <WindowsAzureMobileServices/WindowsAzureMobileServices.h>
Update 2
Setting "Skip install" to no causes archiving issues, see this question: Compile, Build or Archive problems with Xcode 4 (and dependencies)
So I have removed the script that fails in the build phases and added "${PROJECT_DIR}/../azure-mobile-services/sdk/iOS/src" to the "User Header Search Paths" list.
This is messy and not my preferred solution.

Batch Build and Archive of iOS apps via Terminal

I am trying to simplify the build->archive->submit process for iOS app publishing.
We have over 50 mobile apps that have nearly identical framework, but with different artwork and configuration settings.
I normally would load each project in xcode 4.2 and build->archive->submit the usual way with the xcode GUI, but we are up over 50 apps now and this process is very tiresome any time we push out an update.
That being said, I am trying to speed up this process with using a shell function.
I did plenty of research and found that xcodebuild (See Reid's answer) should work, however the Archive option is not working as I get the following error:
unsupported build action 'archive'
So I wrote the following:
# $1 should be a date like: 2012-07-17
# $2 should be a time like: 10.31AM
# $mybase will be the current directory at the time the function was called
# so make sure to cd into the folder containing the xcode project folders first
function xcodeArchive {
mkdir ~/Library/Developer/Xcode/Archives/$1
mybase=$PWD
for x in `ls`
do
mkdir ~/Library/Developer/Xcode/Archives/$1/$x
mkdir ~/Library/Developer/Xcode/Archives/$1/$x/dSYMs
mkdir ~/Library/Developer/Xcode/Archives/$1/$x/Products
mkdir ~/Library/Developer/Xcode/Archives/$1/$x/Products/Applications
cd $mybase/$x
xcodebuild
#read -p "Press [Enter] to continue"
cd $mybase/$x
cp $x/$x-Info.plist ~/Library/Developer/Xcode/Archives/$1/$x/Info.plist
cp -r build/Release-iphoneos/$x.app.dSYM ~/Library/Developer/Xcode/Archives/$1/$x/dSYMs/$x.app.dSYM
cp -r build/Release-iphoneos/$x.app ~/Library/Developer/Xcode/Archives/$1/$x/Products/Applications/$x.app
cd ~/Library/Developer/Xcode/Archives/$1/
mv $x $x\ $1\ $2.xcarchive
cd $mybase
done
}
export -f xcodeArchive
I put this in my .bash_profile and everything runs correctly as I would expect, except I'm not copying the correct "Info.plist" and I can't figure out where to copy it from or how to generate it. So now I am stuck.
Xcode will recognize the archives, but it lists them under "Unknown Schema" and "Unnamed Archive" in the organizer.
Any help regarding now to get the correct Info.plist is greatly appreciated.
I also welcome recommendations on how to improve the script and/or a more efficient way to batch build+archive these iOS apps.
Note:
I am unable to upgrade beyond Xcode 4.2 as that requires (as I understand it) OS X 10.7+ which I am not able to obtain yet (company computer).
I am still very much a bash/shell novice, so I apologize for any ugly code/practice above.
Also, this is for official app submission, not for ad-hoc or anything like that.
Thanks again for your help.
I had the same issue with the archive command, and found this question via Google. It would fail with this build command:
xcodebuild -verbose -project $ProductName.xcodeproj -target $ProductName -configuration Release -sdk $SDK clean archive CONFIGURATION_BUILD_DIR="$PROJECT_PATH/build" PROVISIONING_PROFILE="${DIST_PROVISONING_PROFILE}"
Yet, it would succeed with this build command:
xcodebuild -verbose -project $ProductName.xcodeproj -scheme $ProductName -configuration Release -sdk $SDK clean archive CONFIGURATION_BUILD_DIR="$PROJECT_PATH/build" PROVISIONING_PROFILE="${DIST_PROVISONING_PROFILE}"
The only difference is specifying the scheme in lieu of the target to build. If there is a sensible reason for this behavior, I'd enjoy hearing it.
I'm running XCode 4.5.1 on Mac OS X 10.7.5
OK I found a solution that will work. After doing a lot more searching and a lot of guess and check, I found I can still use the "archive" option with xcodebuild, I just have to specify a workspace and scheme and apparently I wasn't doing that correctly before as it now works.
So, for anyone looking for a similar solution (to batch archive xcode projects), here is my function:
# $mybase will be the current directory at the time the function was called
# so make sure to cd into the folder containing the xcode project folders first
function xcodeArchive {
mybase=$PWD
for x in `ls`
do
cd $mybase/$x
xcodebuild -workspace $x.xcodeproj/project.xcworkspace -scheme $x archive
cd $mybase
done
}
export -f xcodeArchive

Resources