Xcode build issue with Jenkins job - ios

I am building an iOS app and generating .app file in following two ways:
using Xcode in my machine
Jenkins job set up
In my Jenkins script, I am using the command xcodebuild -configuration "$CONFIGS" to generate the build. Where CONFIGS is set to one of my project configuration. Locally, I am building a scheme which is linked to same configuration.
Problem: .app generated from Jenkins build crashes as soon as I launch the app on certain iOS like 8.4.1; works on certain iOS versions like 7.X. Build generated from my local Xcode works fine on all supported iOS versions.
Diagnosis: On further troubleshooting and build size comparison I found that size of exec file inside .app file from Jenkins is half the size of file generated from my local machine.
Anyone has idea on why there could be size difference in executable files?

As you suspected, an architecture is missing in your app.
Check the Xcode configuration used by Jenkins, especially that the Build Settings Build active architecture only is on No, and that the Valid Architecture contains all the needed architecture (arm64 and armv7).
If you need to change something, do take care of the Debug vs. Release thing -- by default, building on your Mac usually yields a Debug build; it may not be the same on the Jenkins job.

Related

`xcodebuild` for scheme and target options

why xcodebuild building the same application differently for scheme and target options?
xcodebuild -target uConnect build
Above commands builds with Release config in build folder inside
project.
xcodebuild -scheme uConnect build
Above builds with Debug config in Xcode’s DrivedData folder.
Wanted to understand what difference -target and -scheme options are making here?
As per my understanding it should always build the application in Release mode since we have selected Release at Project>>Info>>Configuration
use Release for command-line builds
Reference:
Screenshot of Scheme Details for reference
Try editing the scheme. You will see that it specifies the Debug configuration when building. It might look like this:
But, as you've said, when you build the target, you've specified the Release configuration.
A target describes a product that Xcode will build, like your app, the tests, an App Clip or an Extension. When using -target, it will use the configuration specified in the drop down at the bottom of your screenshot.
A scheme is a configuration that describes how a specific target will be built under different circumstances. If you go to the scheme editor, you'll see that you can choose which configuration to build when running, testing, profiling, analyzing, and archiving.

How does Xcode server run tests in release mode without Enable Testability?

When using Xcode server to execute UI Tests, the bot has a setting to 'override' the configuration to Release mode.
This was handy as tests would be executed on release build.
Now when I am trying to run tests on TeamCity or CLI and pass the -configuration Release I get an error saying Module 'App name' was not compiled for testing
This can be solved by toggling Enable testability flag for Release configuration in build settings but that will have to be changed back each time before releasing the app.
Creating another build configuration is also not a desirable option as I have a lot of targets and maintaining an extra config for all would be a pain.
So how does Xcode server do this? Is there a CLI param or something I am missing? Or does it just change the setting via a prebuild script?

How to dynamically change target for unit tests in Xcode 7?

I have a project that has multiple different targets/schemes (~38 of them as of writing this question) and I am trying to get unit testing working properly across all of the different targets. I got things working with one target, and tried adding my testing target to all of the different schemes, but it looks like when tests run for each scheme they actually run on the same, original target.
Looking in the project file I see that there's a specific Host Application associated with my testing target, and in the build settings the Bundle Loader and Test Host point to that same Host Application.
Is there any way to override those values for each scheme to run the tests against the current scheme's build target? Or some other way to set up a single test target to run across multiple build targets?
If you run the tests from the command line, or from an CI tool, like Jenkins, you can instruct xcodebuild to use the build settings that you provide. A simple usage example would be:
xcodebuild -scheme SomeScheme test TEST_HOST=target
You can control almost (if not any) build setting from Xcode, like code coverage generation, build directory, derived data directory, code sign identity, etc.
You can select the scheme when you run tests with Xcode server.
Look at WWDC 2014 continues integration talk for a walk through on how to set it up
https://developer.apple.com/videos/play/wwdc2014-415/
It's using Xcode 6 but it's very similar process to Xcode 7
Also check this CI(continues integration) guideline from apple
https://developer.apple.com/library/ios/documentation/IDEs/Conceptual/xcode_guide-continuous_integration/adopt_continuous_integration.html
If anyone is wondering how to do that with UI tests (maybe it is working with unit tests, too), this is what I came up with:
First, we need to build the application which we are going to use to host our UI tests:
xcodebuild -scheme "<appSchemeName>" build -destination "<yourDestination>"
More info about destination parameter: https://mokacoding.com/blog/xcodebuild-destination-options/
Then, we need to run tests on our newly built application:
xcodebuild -scheme "<uiTestsSchemeName>" -destination "<yourDestination>" test TEST_TARGET_NAME="<yourNewlyBuiltAppTargetName>"
Destinations should match, since after the build .app is generated in your DerivedData folder, which will be used for UI tests hosting application

64 bit support building Ipa with vs-mda-remote

I'm trying to build an Ipa with 64 bit support using Visual Studio Tools for Apache Cordova (CTP 3.0) but without success.
It seems that the vs-mda-remote agent builds just with the Arm architecture support.
Unzipping the Ipa and checking the binary with the file command, returns this result:
Mach-O executable arm
The curious thing is that opening the xcode project deployed to the mac builder machine, the build settings of the universal architecture are properly set and building and archiving it generates an Ipa that contains a binary that supports the 64 bit architecture.
Do you know why there's this difference?
Could be some parameters that vs-mda-remote sets to the command line when building the project, overriding the project's build settings?
Could be a Cordova problem?
64 bit support is included in Cordova builds since v3.4.1, so every version of Tools for Apache Cordova has had 64-bit support. vs-mda-remote simply does a base cordova build, so you should be getting arm, arm7v, and arm64 in one fat binary when building under release.
http://cordova.apache.org/announcements/2014/11/25/ios-64bit.html
However, right now the Cordova project only builds "active architectures" under the debug config while it builds all for release. Building only one speeds up build times during debugging.
If you don't like this debug behavior, you should be able override this by placing a custom build-debug.xcconfig in res/native/ios/cordova with the key ONLY_ACTIVE_ARCH = NO;
Here's the original: https://github.com/apache/cordova-ios/blob/master/bin/templates/scripts/cordova/build-debug.xcconfig

Xcode Server Bot Issue: warning. Build Service Error. Issue: archive at path 'some/path' is malformed

I'm using Cocoapods and KIF to run Continuous Integration on an Xcode server. I have successfully set this up for one project to report on each commit. I'm now using a second project and get the error:
Bot Issue: warning. Build Service Error.
Issue: archive at path '/Library/Developer/XcodeServer/Integrations/Integration-81d42936b22a04037fd4aebed1074e5e/Archive.xcarchive' is malformed.
Integration Number: 1.
Description: archive at path '/Library/Developer/XcodeServer/Integrations/Integration-81d42936b22a04037fd4aebed1074e5e/Archive.xcarchive' is malformed.
The tests passed when ran on the Xcode server machine using Xcode. I tried downloading Provisioning Profiles etc via Xcode but that didn't help. I deleted the Bot and created a new one but that also did't help.
Any help is welcome
At least in my case (and there may be multiple causes), this was caused by having "Skip Install" set on every target, which causes you to end up with an empty archive (but only on Xcode Server).
Basically, xcodebuild (the command-line tool) has lots of critical differences from Xcode in the way it handles archiving. It builds targets that aren't listed in the scheme, and it obeys the Skip Archive flag even for targets listed in the scheme. By contrast, when building locally, Xcode ignores the Skip Archive flag and archives any targets in the scheme (and only the targets listed in the scheme).
I would encourage you to file a bug every time you run into situations where a project builds locally but fails on the server. If everyone did this, perhaps these differences would eventually get fixed....

Resources