Launch iOS applications from the console on the device and simulator

The article will briefly describe how to assemble the application with console commands and run it on a real device and simulator without any need to open xcode for this.

In general, it’s worth starting with the fact that my company has an ios development department of> 10 people who work on a bundle of applications. To automate the routine work, we had to deploy a CI server (so far self-written, due to special historical reasons (well, like everyone else), we plan to migrate to jenkins). I consider routine things - assembling projects, running tests (if, of course, you write them), creating ipashka for testers and for laying out in the app store. In general, I wanted all this to work by pressing a button or hook in a gita. While everything works for us at the click of a button by the developer, the prog is so far only in plans. In this article, I will only touch on the topic of compiling a project and packing it into an ipa file. The functionality for launching projects on devices on the CI server side is still under development,

What are we planning:

  • assemble the application and run on the simulator
  • let's collect ipa and run it on a real device
  • let's collect ipa for upload to the market
  • a little bit of assembly errors

We have:

  • OS X 10.10.5
  • Xcode 7.1

For the frequency of the experiment, we will use a third-party application so that dear readers can repeat what is described in the article. We use a test application for the open source Apple-based ResearchKit framework.

git clone https://github.com/ResearchKit/ResearchKit.git ~/Downloads/researchkit

cd ~/Downloads/researchkit

Before compiling the project, you must install the apple doc generator github.com/tomaz/appledoc (there is a description of how to install it).
We pass to the downloaded project. The root project is the ResearchKit framework itself, the test application itself is in a different place, we go there:

cd samples/ORKCatalog/

We are trying to compile the application. We collect for the simulator, since to build a project for the simulator, certificates are not needed / files are provided.

xcodebuild -project ORKCatalog.xcodeproj -scheme ORKCatalog -arch x86_64 VALID_ARCHS=x86_64 -sdk iphonesimulator

We



get the error: The build crashes because there is no ORKCatalog scheme. Since the scheme in the original project was not marked as shared, then after the “drain” from the git, xcode still does not know anything about this scheme, so that it snows it, you just need to open the project. So just open the project:

open ORKCatalog.xcodeproj

And immediately close, after our scheme appears, you can check the scheme through xcodebuild -list . We try to collect again:

xcodebuild -project ORKCatalog.xcodeproj -scheme ORKCatalog -arch x86_64 VALID_ARCHS=x86_64 -sdk iphonesimulator

After we see the long-awaited ** BUILD SUCCEEDED ** . Great, everything works.

Run the project on the simulator


We compile under the simulator, architectures can be i386 / x86_64. Using SYMROOT, set the path of the build result:

 xcodebuild -project ORKCatalog.xcodeproj -scheme ORKCatalog ARCHS='x86_64 i386' VALID_ARCHS='x86_64 i386' -sdk iphonesimulator -configuration Debug SYMROOT=$(pwd)/build build

(Thoughts aloud: when I wrote the article, the compilation in Release mode worked, before publishing the article I checked all the steps again and the compilation stopped working in this mode, so we are collecting it in Debug, some of the last commits broke this.)

After the successful assembly, we got ORKCatalog.app file in build / Debug-iphonesimulator / . It remains to run this on the simulator. To do this, we will use the ios-sim utility github.com/phonegap/ios-sim . Using it is quite simple.

We get a list of available simulators:

ios-sim showdevicetypes



From the list I selected, 'iPhone-6-Plus'. Run the application on it:

ios-sim --devicetypeid iPhone-6-Plus launch build/Debug-iphonesimulator/ORKCatalog.app

If everything is done correctly, then the simulator with the application should start (use ctrl + C to enter the input mode in the console).



Creating an ipa file and launching on a real device


Here it’s a bit more complicated, we need a mobileprovision file for development (developer) and a certificate on the machine (p12 file), and you don’t need an account in xcode. When signing / packaging applications from the console, there is no need to add an account in xcode, this helps a lot, for example, on the CI server you can only store p12 files.

We will assume that your machine has an appropriate certificate. After we generate the developer mobileprovision through developer.apple.com in your account and download it to the machine (give it the name test.mobileprovision, and the bundle id will be ru.habrahabr.test). After copying it to a directory where xcode can pick it up:

cp test.mobileprovision ~/Library/MobileDevice/Provisioning Profiles/

We collect the archive for the device (this is the architecture of arm64 / armv7):

xcodebuild -project ORKCatalog.xcodeproj -scheme ORKCatalog ARCHS='arm64 armv7' VALID_ARCHS='arm64 armv7' -sdk iphoneos -configuration Debug archive -archivePath build/archive

Compilation will fail, since we have not yet registered our bundle id in the application and have not linked mobileprovision, the error will look like this:



We will pass the bundle id from the console + we need to register it in the Info.plist file. Also through the console we will transfer the link to our mobileprovision. We find the Plist file along the path ORKCatalog / Supporting Files / Info.plist, in which we set the value for the CFBundleIdentifier key to ru.habrahabr.test. Bundle id is passed through the key with the value of our id PRODUCT_BUNDLE_IDENTIFIER = en.habrahabr.test. We pass the link to mobileprovision through the PROVISIONIG_PROFILE key, with the UUIDs, which is registered in mobileprovision.

Get the UUID:

security cms -D -i test.mobileprovision  | grep -o "\w\{8\}-\w\{4\}-\w\{4\}-\w\{4\}-\w\{12\}"

The value will be like 87b0df89-793a-4a0f-92bf-c5f9c35f1405 . We collect again:

xcodebuild -project ORKCatalog.xcodeproj -scheme ORKCatalog ARCHS='arm64 armv7' VALID_ARCHS='arm64 armv7' -sdk iphoneos -configuration Debug archive -archivePath build/archive PRODUCT_BUNDLE_IDENTIFIER=ru.habrahabr.test PROVISIONING_PROFILE=87b0df89-793a-4a0f-92bf-c5f9c35f1405

As a result, we get the build / archive.xcarchive archive , which remains to be packaged in ipa. Xcode 7 introduced a new packaging method, and we will use it. Before that, create the config file options.plist with the following contents:

methoddevelopmentuploadSymbols

Trying to build ipa:

xcodebuild -exportArchive -exportOptionsPlist options.plist -archivePath build/archive.xcarchive -exportPath build/dev-ipa/

The assembly crashes, by the logs you can understand that there is something with entitlements:



By mistake it is clear that the application is signing entitlements, the values ​​in which do not correspond to the values ​​in our mobileprovision, namely com.apple.developer.healthkit . We are looking for a reason. We look at what entitlements the application is signed:

codesign -d --entitlements - build/archive.xcarchive/Products/Applications/ORKCatalog.app

We get:

application-identifierXXXXX.ru.habrahabr.testbeta-reports-activecom.apple.developer.healthkitcom.apple.developer.team-identifierXXXXXget-task-allow

We see that everything is ok, except for this:

com.apple.developer.healthkit

We do not have this option in mobileprovision, we need to find out where it came from:

find ORKCatalog/ -name "*.entitlements" -type f

The search gave us ORKCatalog / Supporitng Files / ORKCatalog.entitlements . We look inside:

cat ORKCatalog/Supporting Files/ORKCatalog.entitlements

There is only one value:

com.apple.developer.healthkit

Logically, we need to reassign mobileprovision to which we need to add this value, but we are lazy and for the test it is not necessary, we just need to re-sign the application with entitlements without this value.

We have at least two options:

1. Just edit the existing entitlements (ORKCatalog / Supporitng Files / ORKCatalog.entitlements) and rebuild again (via archive).
2. Without rebuilding, we ourselves will re-sign ORKCatalog.app with the necessary entitlements.

We choose the first option as simpler. Therefore, we simply delete the lines from the file ORKCatalog / Supporitng Files / ORKCatalog.entitlements :

com.apple.developer.healthkit

and rebuild the archive again:

xcodebuild -project ORKCatalog.xcodeproj -scheme ORKCatalog ARCHS='arm64 armv7' VALID_ARCHS='arm64 armv7' -sdk iphoneos -configuration Debug archive -archivePath build/archive PRODUCT_BUNDLE_IDENTIFIER=ru.habrahabr.test PROVISIONING_PROFILE=87b0df89-793a-4a0f-92bf-c5f9c35f1405

After we create ipa:

xcodebuild -exportArchive -exportOptionsPlist options.plist -archivePath build/archive.xcarchive -exportPath build/dev-ipa/

We see the long-awaited message ** EXPORT SUCCEEDED ** . Under build / dev-ipa / an ipa file will appear, which we will install on the device. We will install on the device using ios-deploy github.com/phonegap/ios-deploy . We cling the device to the car, we get the device id through:

ios-deploy -c

Deploy on the device:

ios-deploy -i  -b build/dev-ipa/ORKCatalog.ipa

We collect the ipa file for the market


Everything is the same as for the develop version, just change the link to the release mobileprovision, in the options.plist we put the app-store instead of development (for other options you can add see the xcodebuild -help help).

Total


Without using xcode, they were able to collect ipa files for tests and for laying out in the app store. All this can be easily automated on the CI server to make life easier for developers.

PS: It is worth noting that for the process of compiling / signing applications with a complex structure, when several targets and each requires its own separate mobileprovision file (applications with extension, clocks, embedded frameworks), the above process will not work without a file.

Also popular now: