How does the XCode-Run-Command look like? - ios

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.

Related

What could cause code coverage enabled builds to fail?

Summary
I'm trying to get a code coverage report from my project. However when I try to build and run tests, there is no CodeCoverage folder created in the derived data folder.
How am I trying to do this?
I am running xcodebuild as follows:
xcodebuild \
-workspace <some_workspace> \
-scheme <some_scheme> \
-destination <some_destination> \
-derivedDataPath <some_path> \
-enableCodeCoverage YES \
build test
What is the problem?
For my workspace/project it fails at the very end with a line:
xcodebuild: error: Failed to build workspace <some_workspace> with scheme <some_scheme>.
Reason: Could not determine bundle identifier for <some_test_target>'s TEST_HOST: "<some_path>/Build/Intermediates/CodeCoverage/Products/Debug-iphonesimulator/<some_product>.app"
At first it seemed directly linked to the TEST_HOST issue, but that's not the case here.
There is simply no CodeCoverage folder:
<some_path>/Build/Intermediates/CodeCoverage
What have I tried?
I tried the same with a clean new project, same running the same xcodebuild command, which succeeds. Within the Build/Intermediates/ folder exists the CodeCoverage folder.
However, in my own project, which is more complex, the Build/Intermediates/ folder contains a bunch of *.build folders (related to the app and the various frameworks, HockeySDK.build for example) and PrecompiledHeaders but no CodeCoverage folder.
When looking through the output of xcodebuild I never see a reference to the CodeCoverage folder for my project. However, for the test project, the first mention is at:
Write auxiliary files
/bin/mkdir -p /<some_path>/Build/Intermediates/CodeCoverage/Intermediates/<some_project>.build/Debug-iphonesimulator/<some_project>.build/Objects-normal/x86_64
For my project I see:
Write auxiliary files
/bin/mkdir -p /<some_path>/Build/Intermediates/<some_project>.build/Debug-iphonesimulator/<some_project>.build/Objects-normal/x86_64
Workaround
Something else that seemed to 'trick' it into working is to set the Host Application to None. After doing this it builds and tests, but tests fail due to the lack of host. However, this causes the CodeCoverage folder to be created, and if the Host Application is correctly set again, running the build and tests works fine, with a code coverage report produced.
You have to assure the package name is equal in all configurations. Xcode modifies it in case you are using unsupported characters. For instance Xcode replaces "-" with "_".
In all configurations, go to:
Project -> Build Settings -> Product Module
and set the exact same name without spaces.

xcodebuild where is the output binary?

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

Teamcity Step tests (Command Line) failed when testing an iOS app

I am trying to run tests automatically using Teamcity, but it seems that when the agent is compiling the project, it is not done correctly because when I run the command like for running test, I am getting the following error:
fatal error: 'Pushwoosh/PushNotificationManager.h' file not found
#import <Pushwoosh/PushNotificationManager.h>
[16:48:51][Step 2/2] ^
[16:48:51][Step 2/2] 1 error generated.
However, when I run manually the same commands I get no errors, but my test running. The application that I want to run was written in objective-c, and the command lines I am using are the following:
$ git clone REPOSITORY_URL (runs sucessfully)
$ pod install (runs sucessfully)
$ xctool -workspace Supermaxi.xcworkspace -scheme Supermaxi test -only FunctionalTests:TestCase000_Registration/test00_WrongEmail -sdk iphonesimulator (fails and I get the previous described error)
After being helped by I friend of mine, we found the solution to this issue in this link.
It turns out that the main problem was, as the link states, that CocoaPods uses symbolic links in it’s directory structure, and TeamCity can have trouble copying symbolic links in the VCS checkout to build agent, so I had to set the Version Control Settings of Teamcity as it is explained in the previous link.
Therefore, I have just changed the VCS checkout mode from Automatically on server to Automatically on agent (if supported by VCS roots). After that I run the agent again, and it worked properly.

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"

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