<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Instabug</title>
    <description>The latest articles on DEV Community by Instabug (@instabug).</description>
    <link>https://dev.to/instabug</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F32964%2Fac1e31b2-36f2-496a-8e45-c0013e22c304.png</url>
      <title>DEV Community: Instabug</title>
      <link>https://dev.to/instabug</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/instabug"/>
    <language>en</language>
    <item>
      <title>How We Automate Our iOS Workflow at Instabug Using CircleCI</title>
      <dc:creator>Instabug</dc:creator>
      <pubDate>Wed, 12 Sep 2018 12:00:03 +0000</pubDate>
      <link>https://dev.to/instabug/how-we-automate-our-ios-workflow-at-instabug-using-circleci-50n3</link>
      <guid>https://dev.to/instabug/how-we-automate-our-ios-workflow-at-instabug-using-circleci-50n3</guid>
      <description>&lt;h4&gt;
  
  
  Written by &lt;a href="https://twitter.com/heshammegid"&gt;Hesham Abd-Elmegid&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;At Instabug we build an SDK for mobile apps. Building an SDK often means that most tools created for automating tasks around development and deployment of iOS apps don't work for us, so we usually need to develop our own bespoke solutions.&lt;/p&gt;

&lt;p&gt;To increase our productivity and keep thing moving fast, we like to automate things. One crucial component of automating many parts of our workflow is continuous integration.&lt;/p&gt;

&lt;p&gt;This post goes through what our workflow is and how we automate it using &lt;a href="https://instabug.com/blog/continuous-integration-tools/?utm_source=devto&amp;amp;utm_medium=referral&amp;amp;utm_content=circleci"&gt;CircleCI&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;With &lt;a href="https://circleci.com/"&gt;CircleCI 2.0&lt;/a&gt;, we can create multiple jobs under one workflow, with the ability to define dependencies between jobs and run some of them in parallel, which is great.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;workflows&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
  &lt;span class="na"&gt;build-test-and-generate-binary&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;unit-tests&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uitests-analyzer&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;filters&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;only&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
                &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;master&lt;/span&gt;
                &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/fix\/.*/&lt;/span&gt;
                &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/release\/.*/&lt;/span&gt;
                &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/Release\/.*/&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;hold&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;approval&lt;/span&gt;
          &lt;span class="na"&gt;requires&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;unit-tests&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;uitests-analyzer&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;generate-binary&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;requires&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;hold&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;release&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;requires&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;generate-binary&lt;/span&gt;
          &lt;span class="na"&gt;filters&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;only&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
                &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;master&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Our workflow has 4 jobs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Running unit tests, integration tests and Danger&lt;/li&gt;
&lt;li&gt;Running UI tests and static analyzer&lt;/li&gt;
&lt;li&gt;Generating binary&lt;/li&gt;
&lt;li&gt;Releasing the SDK&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's go through each one in detail.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Running Unit Tests, Integration Tests and Danger
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;unit-tests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;macos&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;xcode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;9.3.1"&lt;/span&gt;
  &lt;span class="na"&gt;working_directory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/Users/distiller/project&lt;/span&gt;
  &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;BUNDLE_PATH&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;vendor/bundle&lt;/span&gt;  &lt;span class="c1"&gt;# path to install gems and use for caching&lt;/span&gt;
    &lt;span class="na"&gt;ARTIFACTS_DIRECTORY&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/Users/distiller/project/artifacts&lt;/span&gt;
  &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;checkout&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;restore_cache&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;keys&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;gems-{{ checksum "Gemfile.lock" }}&lt;/span&gt;
        &lt;span class="c1"&gt;# Fall back to using the latest cache if no exact match is found.&lt;/span&gt;
        &lt;span class="c1"&gt;# - v1-gems-&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Create artifacts directory&lt;/span&gt;
        &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mkdir $ARTIFACTS_DIRECTORY&lt;/span&gt;
    &lt;span class="c1"&gt;# Install gems.&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Bundle install&lt;/span&gt;
        &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bundle check || bundle install&lt;/span&gt;
        &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;BUNDLE_JOBS&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;
          &lt;span class="na"&gt;BUNDLE_RETRY&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;save_cache&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gems-{{ checksum "Gemfile.lock" }}&lt;/span&gt;
        &lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;vendor/bundle&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Pre-start simulator&lt;/span&gt;
        &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;xcrun instruments -w "iPhone 8 (11.3) [" || &lt;/span&gt;&lt;span class="no"&gt;true&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run Instabug unit tests&lt;/span&gt;
        &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;set -o pipefail &amp;amp;&amp;amp; xcodebuild -workspace Instabug/Instabug.xcworkspace -scheme AllUnitTests -sdk iphonesimulator -destination 'platform=iOS Simulator,OS=11.3,name=iPhone 8' -enableCodeCoverage YES test | xcpretty --color --report junit --output $ARTIFACTS_DIRECTORY/AllTests_unittest_results.xml&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run Danger&lt;/span&gt;
        &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bundle exec Danger&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run integration tests&lt;/span&gt;
        &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;set -o pipefail &amp;amp;&amp;amp; xcodebuild -workspace Instabug/Instabug.xcworkspace -scheme InstabugIntegrationTests -sdk iphonesimulator -destination 'platform=iOS Simulator,OS=11.3,name=iPhone 8' -enableCodeCoverage YES test | xcpretty --color --report junit --output $ARTIFACTS_DIRECTORY/InstabugIntegrationTests_unittest_results.xml&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;First, we install all gems used by our project, like &lt;a href="http://danger.systems/"&gt;Danger&lt;/a&gt; and &lt;a href="https://fastlane.tools/"&gt;fastlane&lt;/a&gt; either by restoring the cache of a previous install, or by doing a fresh install.&lt;/p&gt;

&lt;p&gt;We then run our unit tests. Due to how our project is structured, we have around 15 framework targets, with a separate test target for each. To run all our unit tests at once, we have an &lt;code&gt;AllUnitTests&lt;/code&gt; scheme that runs all test targets.&lt;/p&gt;

&lt;p&gt;After running our unit tests, we run Danger, which is great tool to automate some of the chores around code reviews. Here's what we use it for right now.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Enforce having has a description and a link to a Jira issue for all pull requests&lt;/li&gt;
&lt;li&gt;Ensure that all pull requests that add new user-facing strings add localized versions of those strings.&lt;/li&gt;
&lt;li&gt;Run &lt;a href="https://github.com/nakiostudio/xcov"&gt;xcov&lt;/a&gt; to generate a report about our tests coverage, and post it as a comment on the pull request&lt;/li&gt;
&lt;li&gt;Ensure that all pull requests that modify any UI file run UI tests before merging the pull request.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;has_ui_changes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;modified_files&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;grep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/View Controllers/&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;empty?&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;modified_files&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;grep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/Views/&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;empty?&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="no"&gt;ENV&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'RUN_UI_TESTS'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;has_ui_changes&lt;/span&gt;
    &lt;span class="nb"&gt;fail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"UI has been changed but UI tests were not run. Please make sure to run them before merging the PR."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# Make sure PR has a description.&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;github&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pr_body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;git&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lines_of_code&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
    &lt;span class="nb"&gt;fail&lt;/span&gt; &lt;span class="s2"&gt;"Please provide a summary of the changes in the Pull Request description."&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# Check if PR title has reference to a Jira issue.&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;github&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pr_title&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;/\[[a-zA-Z]*-[0-9]*\]/&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nb"&gt;fail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Pull request should include Jira card number in the name. For example: [IBGProj-123]"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Last steps of this job is to run our integration tests, which is just a test target with a similar configuration to our unit test targets.&lt;/p&gt;

&lt;p&gt;This job runs on every pull request, so we have to make sure it contains all the essential checks/tests, and that it also runs in a reasonable time. It currently runs in around 8 minutes, with the majority of the time going to making a clean build of the SDK for running tests.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Running UI Tests and Static Analyzer
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;uitests-analyzer&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;macos&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;xcode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;9.3.1"&lt;/span&gt;
  &lt;span class="na"&gt;working_directory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/Users/distiller/project&lt;/span&gt;
  &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;BUNDLE_PATH&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;vendor/bundle&lt;/span&gt;  &lt;span class="c1"&gt;# path to install gems and use for caching&lt;/span&gt;
    &lt;span class="na"&gt;ARTIFACTS_DIRECTORY&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/Users/distiller/project/artifacts&lt;/span&gt;
  &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;checkout&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;restore_cache&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;keys&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;gems-{{ checksum "Gemfile.lock" }}&lt;/span&gt;
        &lt;span class="c1"&gt;# Fall back to using the latest cache if no exact match is found.&lt;/span&gt;
        &lt;span class="c1"&gt;# - v1-gems-&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Create artifacts directory&lt;/span&gt;
        &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mkdir $ARTIFACTS_DIRECTORY&lt;/span&gt;
    &lt;span class="c1"&gt;# Install gems.&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Bundle install&lt;/span&gt;
        &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bundle check || bundle install&lt;/span&gt;
        &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;BUNDLE_JOBS&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;
          &lt;span class="na"&gt;BUNDLE_RETRY&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Pre-start simulator&lt;/span&gt;
        &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;xcrun instruments -w "iPhone 8 (11.3) [" || &lt;/span&gt;&lt;span class="no"&gt;true&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run UI tests&lt;/span&gt;
        &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;if [[ -n "${RUN_UI_TESTS}" || $CIRCLE_BRANCH = 'master' ]]; then&lt;/span&gt;
            &lt;span class="s"&gt;set -o pipefail &amp;amp;&amp;amp; xcodebuild -workspace Instabug/Instabug.xcworkspace -scheme InstabugDemoUITests -sdk iphonesimulator -destination 'platform=iOS Simulator,OS=11.3,name=iPhone 8' -only-testing:InstabugDemoUITests/AlertsUITests -only-testing:InstabugDemoUITests/BugReportingDisabledAttachmentsUITests -only-testing:InstabugDemoUITests/BugReportingUITests -only-testing:InstabugDemoUITests/IBGAnnotationUITests -only-testing:InstabugDemoUITests/IBGChatBasicUITests -only-testing:InstabugDemoUITests/IBGPromptVCUITests -only-testing:InstabugDemoUITests/IBGStatusBarTests test | xcpretty --color --report junit --output $ARTIFACTS_DIRECTORY/xcode/uitest_results_1.xml&lt;/span&gt;
            &lt;span class="s"&gt;set -o pipefail &amp;amp;&amp;amp; xcodebuild -workspace Instabug/Instabug.xcworkspace -scheme InstabugDemoUITests -sdk iphonesimulator -destination 'platform=iOS Simulator,OS=11.3,name=iPhone 8' -only-testing:InstabugDemoUITests/IBGSurveysFlowUITests -only-testing:InstabugDemoUITests/IBGSurveysUITests -only-testing:InstabugDemoUITests/InstabugUITests -only-testing:InstabugDemoUITests/IBGFeatureRequestUITests test | xcpretty --color --report junit --output $ARTIFACTS_DIRECTORY/xcode/uitest_results_2.xml&lt;/span&gt;
          &lt;span class="s"&gt;else&lt;/span&gt;
            &lt;span class="s"&gt;echo 'Skipping running UI Tests.'&lt;/span&gt;
          &lt;span class="s"&gt;fi&lt;/span&gt;
        &lt;span class="na"&gt;no_output_timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;15m&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run static analyzer on other frameworks&lt;/span&gt;
        &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;sh ./Scripts/analyze_Instabug.sh&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This job is very similar to what we do in the first job, but it instead runs a UI tests target and the static analyzer using &lt;code&gt;xcodebuild analyze&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This job only runs on master, and fix/release branches, so we're okay with it taking a bit longer to run. It currently finishes in around 40 minutes and runs in parallel with the first job. It can also be run on demand on any pull request regardless of its branch by mentioning a simple GitHub bot we wrote that uses the CircleCI API to trigger a specific job.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Generating Binary
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;generate-binary&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
  &lt;span class="na"&gt;macos&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;xcode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;9.3.1"&lt;/span&gt;
  &lt;span class="na"&gt;working_directory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/Users/distiller/project&lt;/span&gt;
  &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;BUNDLE_PATH&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;vendor/bundle&lt;/span&gt;  &lt;span class="c1"&gt;# path to install gems and use for caching&lt;/span&gt;
    &lt;span class="na"&gt;ARTIFACTS_DIRECTORY&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/Users/distiller/project/artifacts&lt;/span&gt;
  &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;checkout&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;restore_cache&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;keys&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;gems-{{ checksum "Gemfile.lock" }}&lt;/span&gt;
        &lt;span class="c1"&gt;# Fall back to using the latest cache if no exact match is found.&lt;/span&gt;
        &lt;span class="c1"&gt;# - v1-gems-&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; 
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Create artifacts directory&lt;/span&gt;
        &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mkdir $ARTIFACTS_DIRECTORY&lt;/span&gt;
    &lt;span class="c1"&gt;# Install gems.&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Bundle install&lt;/span&gt;
        &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bundle check || bundle install&lt;/span&gt;
        &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;BUNDLE_JOBS&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt;
          &lt;span class="na"&gt;BUNDLE_RETRY&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install signing identity&lt;/span&gt;
        &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;bundle exec fastlane setup_signing&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Increment version number&lt;/span&gt;
        &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;./Scripts/IncrementSDKVersion.swift&lt;/span&gt;
          &lt;span class="s"&gt;/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $CIRCLE_BUILD_NUM" "Instabug/InstabugI/Info.plist"&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Generate fat binary for Instabug static&lt;/span&gt;
        &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;xcodebuild -workspace Instabug/Instabug.xcworkspace -scheme Framework -sdk iphoneos -destination generic/platform=iOS clean build | xcpretty&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Link Instabug static with dynamic project&lt;/span&gt;
        &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;ruby ./Instabug-dynamic/linkInstabug.rb&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Generate fat binary for Instabug dynamic&lt;/span&gt;
        &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;xcodebuild -project Instabug-dynamic/Instabug.xcodeproj -scheme Framework -sdk iphoneos -destination generic/platform=iOS clean archive | xcpretty&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Generate appledoc&lt;/span&gt;
        &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;sh ./Scripts/generate_appledoc.sh&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Create framework archive&lt;/span&gt;
        &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;find ./Instabug/Instabug-SDK-Static -path '*/.*' -prune -o -type f -print | zip $ARTIFACTS_DIRECTORY/Instabug-static.zip -@&lt;/span&gt;
          &lt;span class="s"&gt;find ./Instabug-dynamic/Instabug-SDK -path '*/.*' -prune -o -type f -print | zip $ARTIFACTS_DIRECTORY/Instabug.zip -@&lt;/span&gt;
          &lt;span class="s"&gt;find ./Instabug-Docs -path '*/.*' -prune -o -type f -print | zip $ARTIFACTS_DIRECTORY/appledoc.zip -@&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Test Fat Binaries are not Corrupted&lt;/span&gt;
        &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;xcodebuild -project InstabugProductionDemo/InstabugProductionDemo.xcodeproj -scheme InstabugProductionDemoUITests -sdk iphonesimulator -destination 'platform=iOS Simulator,OS=11.3,name=iPhone 8' test | xcpretty&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;store_artifacts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;artifacts&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;persist_to_workspace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;root&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.&lt;/span&gt;
        &lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;After the first two jobs have finished, we can generate a binary of the SDK from any branch. This requires the approval of a hold from the CircleCI dashboard.&lt;/p&gt;

&lt;p&gt;This job will install our code signing identity, which we share across the team using &lt;a href="https://docs.fastlane.tools/actions/match/"&gt;fastlane&lt;/a&gt; . It then generates both static and dynamic variants of our framework. For more on building binary framework, check our previous &lt;a href="https://instabug.com/blog/ios-binary-framework/?utm_source=devto&amp;amp;utm_medium=referral&amp;amp;utm_content=circleci"&gt;blog post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It then bundles up both frameworks in a zip archive and stores it in the artifacts directory to be available for download.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Releasing the SDK
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;release&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;macos&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;xcode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;9.3.1"&lt;/span&gt;
  &lt;span class="na"&gt;working_directory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/Users/distiller/project&lt;/span&gt;
  &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;ARTIFACTS_DIRECTORY&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/Users/distiller/project/artifacts&lt;/span&gt;
  &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;attach_workspace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;at&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/Users/distiller/project&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Release&lt;/span&gt;
        &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./release&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The last job releases the SDK to the public. It runs Unleash, our homegrown CLI app for releasing the SDK.&lt;/p&gt;

&lt;p&gt;Unleash does the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create and push a new tag to our private repository&lt;/li&gt;
&lt;li&gt;Push the updated framework to &lt;a href="https://github.com/Instabug/Instabug-iOS/"&gt;https://github.com/Instabug/Instabug-iOS/&lt;/a&gt; and create a GitHub release&lt;/li&gt;
&lt;li&gt;Publish framework to CocoaPods&lt;/li&gt;
&lt;li&gt;Update our Carthage &lt;a href="https://github.com/Instabug/Instabug-iOS/blob/master/Instabug.json"&gt;JSON file&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Upload the release to our own API for consumption on the Instabug dashboard and website.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;We're pretty happy with the workflow we have so far. Having a reliable CI process makes us ship with confidence, and automating our release process saves a ton of time since we release once a week. &lt;/p&gt;

&lt;p&gt;CircleCI has been a great tool to use for our continuous integration, especially with CircleCI 2.0.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;em&gt;Learn more at &lt;a href="https://www.instabug.com/blog/?utm_source=devto&amp;amp;utm_medium=referral&amp;amp;utm_content=circleci"&gt;instabug.com/blog&lt;/a&gt;.&lt;/em&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ios</category>
      <category>sdk</category>
      <category>cicd</category>
      <category>ci</category>
    </item>
    <item>
      <title>Creating UIViews Constraints Programmatically Using PureLayout</title>
      <dc:creator>Instabug</dc:creator>
      <pubDate>Wed, 20 Dec 2017 00:57:28 +0000</pubDate>
      <link>https://dev.to/instabug/creating-uiviews-constraints-programmatically-using-purelayout-48am</link>
      <guid>https://dev.to/instabug/creating-uiviews-constraints-programmatically-using-purelayout-48am</guid>
      <description>&lt;h4&gt;
  
  
  Written by &lt;a href="https://dev.to/alyakan"&gt;Aly Yakan&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;Today, we’ll walk you through &lt;a href="https://blog.instabug.com/2017/12/nslayoutconstraint-programmatically/?utm_source=devto&amp;amp;utm_medium=referral&amp;amp;utm_content=nslayoutconstraint"&gt;creating constraints programmatically&lt;/a&gt; -- building a simple mobile application’s UI completely in code without the use of Storyboards or NIBs. I will not go into the debate of which is better because, simply, they all have their pros and cons, so I’ll just leave this link here which dives more into that matter: &lt;a href="https://www.toptal.com/ios/ios-user-interfaces-storyboards-vs-nibs-vs-custom-code"&gt;https://www.toptal.com/ios/ios-user-interfaces-storyboards-vs-nibs-vs-custom-code&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;This tutorial was written using Xcode 9 and Swift 4. I also assume that you’re familiar with Xcode, Swift, and CocoaPods.&lt;/p&gt;

&lt;p&gt;Without further delay, let’s start building our project: a simple Contact Card application. This tutorial aims to teach you how to build your application’s UI in code, and as such, it will not contain any logic about the application’s functionality unless it serves this tutorial’s purpose.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting up the project
&lt;/h3&gt;

&lt;p&gt;Start by firing up Xcode -&amp;gt; “Create a New Xcode Project”. Select “Single View App” and press “Next”.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CrtL2c2D--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i2.wp.com/blog.instabug.com/wp-content/uploads/2017/10/Screen-Shot-2017-10-22-at-5.31.15-PM.png%3Fw%3D2400%26ssl%3D1" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CrtL2c2D--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i2.wp.com/blog.instabug.com/wp-content/uploads/2017/10/Screen-Shot-2017-10-22-at-5.31.15-PM.png%3Fw%3D2400%26ssl%3D1" alt="create constraints programmatically"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Name the project anything you’d like, I chose to call it “ContactCard”, for no obvious reasons. Untick all three options below and, of course, choose Swift to be the programming language, then press “Next”.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xMFiVamz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i1.wp.com/blog.instabug.com/wp-content/uploads/2017/10/Screen-Shot-2017-10-22-at-5.31.53-PM.png%3Fw%3D2400%26ssl%3D1" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xMFiVamz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i1.wp.com/blog.instabug.com/wp-content/uploads/2017/10/Screen-Shot-2017-10-22-at-5.31.53-PM.png%3Fw%3D2400%26ssl%3D1" alt="create constraints programmatically"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Choose a location on your computer to save the project. Uncheck “Create Git Repository on my Mac” and press “Create”.&lt;/p&gt;

&lt;p&gt;Since we won’t be using Storyboards, or NIBs for that matter, go ahead and delete “Main.storyboard”, which can be found in the Project Navigator here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NFRwVy7C--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i0.wp.com/blog.instabug.com/wp-content/uploads/2017/10/Screen-Shot-2017-10-22-at-5.40.20-PM.png%3Fw%3D2400%26ssl%3D1" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NFRwVy7C--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i0.wp.com/blog.instabug.com/wp-content/uploads/2017/10/Screen-Shot-2017-10-22-at-5.40.20-PM.png%3Fw%3D2400%26ssl%3D1" alt="create constraints programmatically"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After that, click on the project in the Project Navigator and under the “General” tab find the section that says “Deployment Info” and delete whatever’s written next to “Main Interface”, usually it is the word “Main”. This is what tells Xcode which Storyboard file to load with the application startup, but since we just deleted “Main.storyboard”, leaving this line would crash the app since Xcode would not find the file.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0WgEAqlT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i2.wp.com/blog.instabug.com/wp-content/uploads/2017/10/Screen-Shot-2017-10-22-at-5.41.49-PM.png%3Fw%3D2400%26ssl%3D1" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0WgEAqlT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i2.wp.com/blog.instabug.com/wp-content/uploads/2017/10/Screen-Shot-2017-10-22-at-5.41.49-PM.png%3Fw%3D2400%26ssl%3D1" alt="create constraints programmatically"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So go ahead and delete the word “Main”.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating ViewController
&lt;/h3&gt;

&lt;p&gt;At this point, if you run the application, a black screen will appear as the application now does not have any source of UI to present for the user, so the next part is where we will provide it with one. Open “AppDelegate.swift” and inside    &lt;code&gt;application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?)&lt;/code&gt;, insert this snippet of code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;    &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;window&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;UIWindow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UIScreen&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bounds&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;viewController&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;ViewController&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; 
    &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rootViewController&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;viewController&lt;/span&gt;    
    &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;window&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;makeKeyAndVisible&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What this does is basically provide a window for the user’s interaction with the application. This window’s view controller is the one provided with the project on creation, which can be found in “ViewController.swift”. Just as a quick test that everything’s working, head to “ViewController.swift” and inside the &lt;code&gt;viewDidLoad()&lt;/code&gt; method, insert the following line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;    &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;backgroundColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;blue&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now run the application on your preferred simulator device.&lt;/p&gt;

&lt;p&gt;A useful shortcut to navigate between files in Xcode is “⇧⌘O” and then typing the file’s name or even a piece of code that you’re looking for and a list of files will come up on the screen from which you can choose.&lt;/p&gt;

&lt;p&gt;After running the application, this should be the result on your simulator’s screen:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--I5oauyNv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i0.wp.com/blog.instabug.com/wp-content/uploads/2017/10/Simulator-Screen-Shot-iPhone-7-2017-10-22-at-18.26.00.png%3Fw%3D638%26ssl%3D1" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--I5oauyNv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i0.wp.com/blog.instabug.com/wp-content/uploads/2017/10/Simulator-Screen-Shot-iPhone-7-2017-10-22-at-18.26.00.png%3Fw%3D638%26ssl%3D1" width="500" alt="create constraints programmatically"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Of course we won’t use that hideous blue so just turn the background back to white by replacing &lt;code&gt;.blue&lt;/code&gt; with &lt;code&gt;.white&lt;/code&gt; inside &lt;code&gt;viewDidLoad()&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Laying out the UI
&lt;/h3&gt;

&lt;p&gt;For laying out our UI, we’ll be using a very helpful library that will make our lives so much easier. Its repo can be found at &lt;a href="https://github.com/PureLayout/PureLayout"&gt;https://github.com/PureLayout/PureLayout&lt;/a&gt;. To install PureLayout, you should first open up your terminal and “cd” into the project’s directory. You can do this by typing &lt;code&gt;cd&lt;/code&gt;, then a space, then drag and drop your project’s folder into the terminal and press “Enter”. Now run the following commands inside the terminal:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pod init&lt;/code&gt;&lt;br&gt;
&lt;code&gt;pod install&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This should be the output of your terminal after running the second command:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sc0jJqT_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i1.wp.com/blog.instabug.com/wp-content/uploads/2017/10/Screen-Shot-2017-10-22-at-6.34.32-PM.png%3Fw%3D2400%26ssl%3D1" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sc0jJqT_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i1.wp.com/blog.instabug.com/wp-content/uploads/2017/10/Screen-Shot-2017-10-22-at-6.34.32-PM.png%3Fw%3D2400%26ssl%3D1" alt="create constraints programmatically"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After that, close Xcode, open the folder inside Finder, and you should find something called “.xcworkspace”. This is what we’ll be opening to access our application if we ever need to use CocoaPods. Now locate a file called “PodFile” and write the following line under the phrase &lt;code&gt;use_frameworks!&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pod “PureLayout”&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Run pod install in your terminal again and then build your project by pressing “Command + B”.&lt;/p&gt;
&lt;h3&gt;
  
  
  Coffee break
&lt;/h3&gt;

&lt;p&gt;Now that everything is set up, let’s start with the real work. Head over to “ViewController.swift” and grab a cup of coffee because here’s what the final result will look like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HrBgq_gb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/plomvfzwebnz62jf2qcp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HrBgq_gb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/plomvfzwebnz62jf2qcp.png" width="500" alt="create constraints programmatically"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Creating an ImageView
&lt;/h3&gt;

&lt;p&gt;Insert the line &lt;code&gt;import PureLayout&lt;/code&gt; underneath &lt;code&gt;import UIKit&lt;/code&gt; to be able to use the library in this file. Next, underneath the class declaration and outside of any function, we’ll start by creating the &lt;code&gt;Avatar ImageView&lt;/code&gt; lazy variable as follows with this snippet of code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;lazy&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;avatar&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UIImageView&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;imageView&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;UIImageView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UIImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;named&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"avatar.jpg"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;imageView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;autoSetDimensions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;CGSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;128.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;128.0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;imageView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;layer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;borderWidth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;3.0&lt;/span&gt;
    &lt;span class="n"&gt;imageView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;layer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;borderColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;UIColor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lightGray&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cgColor&lt;/span&gt;
    &lt;span class="n"&gt;imageView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;layer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cornerRadius&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;64.0&lt;/span&gt;
    &lt;span class="n"&gt;imageView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;clipsToBounds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;imageView&lt;/span&gt;
&lt;span class="p"&gt;}()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As for the image, get any image on your desktop that you’d like to use as an avatar, draw and drop it in Xcode under  folder, which in my case is “ContactCard”, and check on “Copy items if needed”.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--z_IwvZUE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i0.wp.com/blog.instabug.com/wp-content/uploads/2017/10/Screen-Shot-2017-10-23-at-10.06.50-PM.png%3Fw%3D2400%26ssl%3D1" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--z_IwvZUE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i0.wp.com/blog.instabug.com/wp-content/uploads/2017/10/Screen-Shot-2017-10-23-at-10.06.50-PM.png%3Fw%3D2400%26ssl%3D1" alt="create constraints programmatically"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then click “Finish”. After that, write that file’s name along with its extension inside the declaration of the &lt;code&gt;UIImage&lt;/code&gt; instead of “avatar.jpg”.&lt;/p&gt;

&lt;p&gt;For those of you who don’t know, lazy variables are like normal variables except they do not get initialized (or allocated any memory space) until they are needed, or being called, for the first time. This means that lazy variables don’t get initialized when the view controller is initialized, but rather they wait until a later point when they are actually needed, which saves processing power and memory space for other processes. These are especially useful in the case of initializing UI components.&lt;/p&gt;

&lt;h3&gt;
  
  
  PureLayout in action
&lt;/h3&gt;

&lt;p&gt;As you can see inside the initialization, this line &lt;code&gt;imageView.autoSetDimensions(to: CGSize(width: 128.0, height: 128.0))&lt;/code&gt; is PureLayout in action. With just a single line, we set a constraint for both the height and width of the &lt;code&gt;UIImageView&lt;/code&gt; and all the necessary &lt;code&gt;NSLayoutConstraint&lt;/code&gt; lines are created without the hassle of dealing with their huge function calls. If you’ve dealt with creating constraints programmatically, then you must have fallen in love by now with this brilliant library.&lt;/p&gt;

&lt;p&gt;To make this image view round, we set its corner radius to half its width, or height, which is 64.0 points. Also, for the image itself to respect the roundness of the image view, we set the &lt;code&gt;clipsToBounds&lt;/code&gt; property to true, which tells the image that it should clip anything outside the radius that we just set.&lt;/p&gt;

&lt;p&gt;We then move to creating a &lt;code&gt;UIView&lt;/code&gt; that will serve as the upper part of the view behind the avatar which is colored in gray. The following lazy var is a declaration for that view:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;lazy&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;upperView&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UIView&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;view&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;UIView&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;autoSetDimension&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;toSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;backgroundColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gray&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt;
&lt;span class="p"&gt;}()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Adding subviews
&lt;/h3&gt;

&lt;p&gt;Before we forget, let’s create a function called &lt;code&gt;func addSubviews()&lt;/code&gt; that adds the views we just created (and all the other views that we’re going to create) as subviews to the view controller’s view:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;addSubviews&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addSubview&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;avatar&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addSubview&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;upperView&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And now add the following line to &lt;code&gt;viewDidLoad(): self.addSubviews()&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting up constraints
&lt;/h3&gt;

&lt;p&gt;Just to get a picture of how far we are, let’s setup the constraints for these two views. Create another function called func setupConstraints() and insert the following constraints:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;setupConstraints&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;avatar&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;autoAlignAxis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;toSuperviewAxis&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;vertical&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;avatar&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;autoPinEdge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;toSuperviewEdge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;top&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;withInset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;64.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;upperView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;autoPinEdge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;toSuperviewEdge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;upperView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;autoPinEdge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;toSuperviewEdge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;upperView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;autoPinEdgesToSuperviewEdges&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;with&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;zero&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;excludingEdge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bottom&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now inside &lt;code&gt;viewDidLoad()&lt;/code&gt; call &lt;code&gt;setupConstraints()&lt;/code&gt; by adding its function call as follows: &lt;code&gt;self.setupConstraints()&lt;/code&gt;. Add this AFTER the call to &lt;code&gt;addSubviews()&lt;/code&gt;. This should be the final output:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JQ3I778S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/ob9e1fqa2xotpro2f4u8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JQ3I778S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/ob9e1fqa2xotpro2f4u8.png" width="500" alt="create constraints programmatically"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Bring to front
&lt;/h3&gt;

&lt;p&gt;Oops, that doesn’t seem right. As you can see, our &lt;code&gt;upperView&lt;/code&gt; lays on top of the &lt;code&gt;avatar&lt;/code&gt;. This is because we added &lt;code&gt;avatar&lt;/code&gt; as a subview before &lt;code&gt;upperView&lt;/code&gt;, and since those subviews are arranged in a stack of some sort, then it is only natural to see this result. To fix this, we can just replace those two lines with each other, but there is also another trick that I want to show you, which is: &lt;code&gt;self.view.bringSubview(toFront: avatar)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This method will bring the avatar all the way from the bottom of the stack right back to the top, no matter how many views there were above it. So choose whichever method you’d like. Of course for readability, it’s better to add the subviews in the order that they should appear above the other, if they would ever happen to intersect, while keeping in mind that the first added subview will be at the bottom of the stack and so any other intersecting view will appear on top of it.&lt;/p&gt;

&lt;p&gt;And this is how it should really look like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GOVO74Io--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/vlub2ygvfouxn5o85a6l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GOVO74Io--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/vlub2ygvfouxn5o85a6l.png" width="500" alt="create constraints programmatically"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating segmented control
&lt;/h3&gt;

&lt;p&gt;Moving on, we’ll now create the segmented control, which is the gray bar that contains three sections. Creating the segmented control is actually simple. Just do the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;lazy&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;segmentedControl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UISegmentedControl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;control&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;UISegmentedControl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"Personal"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Social"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Resumè"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="n"&gt;control&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;autoSetDimension&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;toSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;32.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;control&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;selectedSegmentIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="n"&gt;control&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;layer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;borderColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;UIColor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gray&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cgColor&lt;/span&gt;
    &lt;span class="n"&gt;control&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tintColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gray&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;control&lt;/span&gt;
&lt;span class="p"&gt;}()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I believe everything is clear, the only different thing is that upon initialization we provide it with an array of strings, each string representing one of our desired sections’ title. We also set the selectedSegmentIndex to 0, which tells the segmented control to highlight/choose the first segment upon initialization. The rest is just styling which you can play around with.&lt;/p&gt;

&lt;p&gt;Now let’s go ahead and add it as a subview by inserting the following line to the end of &lt;code&gt;func addSubviews(): self.view.addSubview(segmentedControl)&lt;/code&gt; and its constraints will be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;    &lt;span class="n"&gt;segmentedControl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;autoPinEdge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;toSuperviewEdge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;withInset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;8.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;segmentedControl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;autoPinEdge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;toSuperviewEdge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;withInset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;8.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;segmentedControl&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;autoPinEdge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;top&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bottom&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;of&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;avatar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;withOffset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;16.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Take a moment to wrap your head around these. We tell the segmented control that we want to pin it to the left side of its superview, however, we want a a little bit of spacing instead of sticking it directly to the edge of the screen. If you notice, I’m using what is called an eight-point grid where all spacings and sizes are a multiple of eight. I do the same to the right side of the segmented control. As for the last constraint, it simply says to pin its top to the bottom of avatar with a spacing of 16 points.&lt;/p&gt;

&lt;p&gt;After adding the constraints above to &lt;code&gt;func setupConstraints()&lt;/code&gt;, run the code and make sure that it looks like the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1EkJA6oh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/htbxlfdnywj4zhegvikr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1EkJA6oh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/htbxlfdnywj4zhegvikr.png" alt="create constraints programmatically" width="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding a button
&lt;/h3&gt;

&lt;p&gt;Now comes the last piece of UI for this small tutorial, which is the “Edit” button. Add the following lazy variable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;lazy&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;editButton&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UIButton&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;UIButton&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setTitle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Edit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;for&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;normal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setTitleColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gray&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;for&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;normal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;layer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cornerRadius&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;4.0&lt;/span&gt;
    &lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;layer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;borderColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;UIColor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gray&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cgColor&lt;/span&gt;
    &lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;layer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;borderWidth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;
    &lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tintColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gray&lt;/span&gt;
    &lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;backgroundColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;clear&lt;/span&gt;
    &lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;autoSetDimension&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;toSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;96.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;autoSetDimension&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;toSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;32.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;button&lt;/span&gt;
&lt;span class="p"&gt;}()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don’t be alarmed by how big the initialization is, but pay attention to how I set the title and its color by calling the function button.setTitle and button.setTitleColor. For certain reasons, we cannot set a button’s title by accessing its titleLabel directly and this is because there are different states for a button and many people would find it convenient to have different titles/colors for different states.&lt;/p&gt;

&lt;p&gt;Now add the button as a subview like the rest of the components and add the following constraints to have it appear where it is supposed to be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="n"&gt;editButton&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;autoPinEdge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;top&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bottom&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;of&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;upperView&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;withOffset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;16.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;editButton&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;autoPinEdge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;toSuperviewEdge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;withInset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;8.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we only set the right and top constraints for the button, and since we gave it a size, it won’t expand and will need nothing else. Now go ahead and run the project to see the final result:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--D_BLnZsD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/22x04slfiupxn7ykgkaa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--D_BLnZsD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/22x04slfiupxn7ykgkaa.png" alt="create constraints programmatically" width="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Some final notes
&lt;/h3&gt;

&lt;p&gt;Play around, add as many UI elements as you want. Try to re-create any application’s views that you see challenging. Start simple and build up from there. Try to draw the UI components on a piece of paper so you can imagine how they fit together.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;em&gt;Learn more at &lt;a href="https://blog.instabug.com/?utm_source=devto&amp;amp;utm_medium=referral&amp;amp;utm_content=nslayoutconstraint"&gt;blog.instabug.com&lt;/a&gt;.&lt;/em&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>swift</category>
      <category>ios</category>
      <category>mobile</category>
    </item>
    <item>
      <title>The Ultimate Beginner's Guide For Beta Testing Mobile Apps</title>
      <dc:creator>Instabug</dc:creator>
      <pubDate>Mon, 11 Sep 2017 19:42:41 +0000</pubDate>
      <link>https://dev.to/instabug/the-ultimate-beginners-guide-for-beta-testing-mobile-apps</link>
      <guid>https://dev.to/instabug/the-ultimate-beginners-guide-for-beta-testing-mobile-apps</guid>
      <description>&lt;p&gt;The majority of our 15,000 &lt;a href="https://instabug.com/customers?utm_source=devto&amp;amp;utm_medium=&amp;amp;utm_campaign=post&amp;amp;utm_content=betatestingslides" rel="noopener noreferrer"&gt;customers&lt;/a&gt; use us in the beta builds of their apps and we constantly get questions about beta testing. &lt;/p&gt;

&lt;p&gt;So we decided to put together a beginner's guide with tips, resources, and answers to the most common questions about beta testing mobile apps.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.slideshare.net/Instabug/the-ultimate-beginners-guide-for-beta-testing-mobile-apps-79634773?utm_source=devto&amp;amp;utm_medium=&amp;amp;utm_campaign=post&amp;amp;utm_content=betatestingslides" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fme64ghdbc3fdc0qneofe.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's what you'll learn in these 50+ slides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is beta testing?&lt;/li&gt;
&lt;li&gt;Why is it important?&lt;/li&gt;
&lt;li&gt;What types of beta tests are there?&lt;/li&gt;
&lt;li&gt;How long should a beta test take?&lt;/li&gt;
&lt;li&gt;What are the best places to distribute your app?&lt;/li&gt;
&lt;li&gt;What are the responsibilities of beta testers?&lt;/li&gt;
&lt;li&gt;What types of beta testers are there?&lt;/li&gt;
&lt;li&gt;How many beta testers do you need?&lt;/li&gt;
&lt;li&gt;Where can you find beta testers?&lt;/li&gt;
&lt;li&gt;How should you manage beta testers?&lt;/li&gt;
&lt;li&gt;How can you motivate your beta testers?&lt;/li&gt;
&lt;li&gt;Where can you learn more about beta testing?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;See the full presentation here: &lt;a href="https://www.slideshare.net/Instabug/the-ultimate-beginners-guide-for-beta-testing-mobile-apps-79634773?utm_source=devto&amp;amp;utm_medium=&amp;amp;utm_campaign=post&amp;amp;utm_content=betatestingslides" rel="noopener noreferrer"&gt;The Ultimate Guide For Beta Testing Mobile Apps&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We're all about feedback (user feedback lies at the heart of our company!), and we'd love to hear yours. Share your comments and beta testing questions with us at &lt;a href="mailto:content@instabug.com"&gt;content@instabug.com&lt;/a&gt; or ask us anything at &lt;a href="mailto:contactus@instabug.com"&gt;contactus@instabug.com&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ios</category>
      <category>android</category>
      <category>beginners</category>
      <category>testing</category>
    </item>
  </channel>
</rss>
