<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Pete Smith on Medium]]></title>
        <description><![CDATA[Stories by Pete Smith on Medium]]></description>
        <link>https://medium.com/@superpeteblaze?source=rss-d0ff76ca6320------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/2*iPgqUkrz3CH1DqwvK6TLIw.jpeg</url>
            <title>Stories by Pete Smith on Medium</title>
            <link>https://medium.com/@superpeteblaze?source=rss-d0ff76ca6320------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Wed, 29 Apr 2026 01:00:55 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@superpeteblaze/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[iOS How-to — Capture Touch Events Outside UIView Bounds]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://zendesk.engineering/ios-how-to-capture-touch-events-outside-uiview-bounds-bc7461970788?source=rss-d0ff76ca6320------2"><img src="https://cdn-images-1.medium.com/max/2600/1*OQSQeosWV3W6plmLYoPNWw.png" width="3751"></a></p><p class="medium-feed-snippet">Learn how the iOS UIKit handles touch events, and then use this knowledge to provide an implementation that achieves the desired behaviour</p><p class="medium-feed-link"><a href="https://zendesk.engineering/ios-how-to-capture-touch-events-outside-uiview-bounds-bc7461970788?source=rss-d0ff76ca6320------2">Continue reading on Zendesk Engineering »</a></p></div>]]></description>
            <link>https://zendesk.engineering/ios-how-to-capture-touch-events-outside-uiview-bounds-bc7461970788?source=rss-d0ff76ca6320------2</link>
            <guid isPermaLink="false">https://medium.com/p/bc7461970788</guid>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[swift-programming]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[ios-app-development]]></category>
            <dc:creator><![CDATA[Pete Smith]]></dc:creator>
            <pubDate>Tue, 26 Oct 2021 03:11:16 GMT</pubDate>
            <atom:updated>2021-12-03T11:40:31.613Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[Swift Concurrency: An Introduction]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://zendesk.engineering/swift-concurrency-an-introduction-47e3bbe5ec66?source=rss-d0ff76ca6320------2"><img src="https://cdn-images-1.medium.com/max/2600/1*ROPDHaqTZpy5eSeLZjYk_g.jpeg" width="5360"></a></p><p class="medium-feed-snippet">Why is a new concurrency model is being introduced to Swift? Learn about some key language features which support the new model.</p><p class="medium-feed-link"><a href="https://zendesk.engineering/swift-concurrency-an-introduction-47e3bbe5ec66?source=rss-d0ff76ca6320------2">Continue reading on Zendesk Engineering »</a></p></div>]]></description>
            <link>https://zendesk.engineering/swift-concurrency-an-introduction-47e3bbe5ec66?source=rss-d0ff76ca6320------2</link>
            <guid isPermaLink="false">https://medium.com/p/47e3bbe5ec66</guid>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[asynchronous]]></category>
            <category><![CDATA[swift-programming]]></category>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[concurrency]]></category>
            <dc:creator><![CDATA[Pete Smith]]></dc:creator>
            <pubDate>Tue, 31 Aug 2021 07:03:40 GMT</pubDate>
            <atom:updated>2021-12-03T11:44:15.007Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[UI Testing iOS Apps with the Robot Pattern]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://zendesk.engineering/ui-testing-ios-apps-with-the-robot-pattern-dd839b59fed1?source=rss-d0ff76ca6320------2"><img src="https://cdn-images-1.medium.com/max/2600/1*W6KXfNvtf_o9jQE1MScZWw.jpeg" width="4460"></a></p><p class="medium-feed-snippet">In his book Succeeding with Agile, Mike Cohn defined the concept of a test pyramid.</p><p class="medium-feed-link"><a href="https://zendesk.engineering/ui-testing-ios-apps-with-the-robot-pattern-dd839b59fed1?source=rss-d0ff76ca6320------2">Continue reading on Zendesk Engineering »</a></p></div>]]></description>
            <link>https://zendesk.engineering/ui-testing-ios-apps-with-the-robot-pattern-dd839b59fed1?source=rss-d0ff76ca6320------2</link>
            <guid isPermaLink="false">https://medium.com/p/dd839b59fed1</guid>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[robot-framework]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[swiftui]]></category>
            <category><![CDATA[testing]]></category>
            <dc:creator><![CDATA[Pete Smith]]></dc:creator>
            <pubDate>Mon, 05 Jul 2021 10:29:10 GMT</pubDate>
            <atom:updated>2021-12-03T11:44:33.258Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[Covid-19: How My Symptoms Progressed]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://superpeteblaze.medium.com/covid-19-how-my-symptoms-progressed-de457ed2afbc?source=rss-d0ff76ca6320------2"><img src="https://cdn-images-1.medium.com/max/2600/1*olOJOTbxPS3CAQxSpHQp2g.jpeg" width="4032"></a></p><p class="medium-feed-snippet">Covid-19: How My Symptoms Progressed</p><p class="medium-feed-link"><a href="https://superpeteblaze.medium.com/covid-19-how-my-symptoms-progressed-de457ed2afbc?source=rss-d0ff76ca6320------2">Continue reading on Medium »</a></p></div>]]></description>
            <link>https://superpeteblaze.medium.com/covid-19-how-my-symptoms-progressed-de457ed2afbc?source=rss-d0ff76ca6320------2</link>
            <guid isPermaLink="false">https://medium.com/p/de457ed2afbc</guid>
            <category><![CDATA[coronavirus]]></category>
            <category><![CDATA[symptoms]]></category>
            <category><![CDATA[covid19]]></category>
            <category><![CDATA[covid-19-diaries]]></category>
            <category><![CDATA[covid-19-symptoms]]></category>
            <dc:creator><![CDATA[Pete Smith]]></dc:creator>
            <pubDate>Sat, 30 Jan 2021 13:03:16 GMT</pubDate>
            <atom:updated>2021-03-17T10:33:06.986Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[App Onboarding with SwiftUI]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://zendesk.engineering/app-onboarding-with-swiftui-23d970ab24d4?source=rss-d0ff76ca6320------2"><img src="https://cdn-images-1.medium.com/max/2600/1*FcC4wvLui5xtmUX8HRHCRA.jpeg" width="4460"></a></p><p class="medium-feed-snippet">Onboarding is the process of helping users to understand an app, and hopefully, encouraging them to continue to use it. Onboarding flows&#x2026;</p><p class="medium-feed-link"><a href="https://zendesk.engineering/app-onboarding-with-swiftui-23d970ab24d4?source=rss-d0ff76ca6320------2">Continue reading on Zendesk Engineering »</a></p></div>]]></description>
            <link>https://zendesk.engineering/app-onboarding-with-swiftui-23d970ab24d4?source=rss-d0ff76ca6320------2</link>
            <guid isPermaLink="false">https://medium.com/p/23d970ab24d4</guid>
            <dc:creator><![CDATA[Pete Smith]]></dc:creator>
            <pubDate>Tue, 22 Sep 2020 23:47:42 GMT</pubDate>
            <atom:updated>2021-12-03T11:45:11.399Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[SwiftUI & UIView — A Simple Mistake]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://zendesk.engineering/swiftui-uiview-a-simple-mistake-b794bd8c5678?source=rss-d0ff76ca6320------2"><img src="https://cdn-images-1.medium.com/max/734/1*WAfK5y2RKs7KH9cvTEDybg.png" width="734"></a></p><p class="medium-feed-snippet">&#x201C;Experience is simply the name we give our mistakes.&#x201D; The destination is not what&#x2019;s important&#x2026;it&#x2019;s the experience we gain along the way.</p><p class="medium-feed-link"><a href="https://zendesk.engineering/swiftui-uiview-a-simple-mistake-b794bd8c5678?source=rss-d0ff76ca6320------2">Continue reading on Zendesk Engineering »</a></p></div>]]></description>
            <link>https://zendesk.engineering/swiftui-uiview-a-simple-mistake-b794bd8c5678?source=rss-d0ff76ca6320------2</link>
            <guid isPermaLink="false">https://medium.com/p/b794bd8c5678</guid>
            <category><![CDATA[apple]]></category>
            <category><![CDATA[uikit]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[swiftui]]></category>
            <category><![CDATA[swift]]></category>
            <dc:creator><![CDATA[Pete Smith]]></dc:creator>
            <pubDate>Wed, 15 Jul 2020 00:23:28 GMT</pubDate>
            <atom:updated>2021-12-03T11:45:27.870Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[A Github Actions Workflow to Generate & Publish your Hugo Website]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://zendesk.engineering/a-github-actions-workflow-to-generate-publish-your-hugo-website-f36375e56cf7?source=rss-d0ff76ca6320------2"><img src="https://cdn-images-1.medium.com/max/2600/1*5sRmSdOXgJcEGawWmSf15A.jpeg" width="6016"></a></p><p class="medium-feed-snippet">This short post describes a Github Actions workflow to generate your Hugo-based website and publish it to Github Pages.</p><p class="medium-feed-link"><a href="https://zendesk.engineering/a-github-actions-workflow-to-generate-publish-your-hugo-website-f36375e56cf7?source=rss-d0ff76ca6320------2">Continue reading on Zendesk Engineering »</a></p></div>]]></description>
            <link>https://zendesk.engineering/a-github-actions-workflow-to-generate-publish-your-hugo-website-f36375e56cf7?source=rss-d0ff76ca6320------2</link>
            <guid isPermaLink="false">https://medium.com/p/f36375e56cf7</guid>
            <dc:creator><![CDATA[Pete Smith]]></dc:creator>
            <pubDate>Thu, 04 Jun 2020 00:04:36 GMT</pubDate>
            <atom:updated>2021-12-03T11:46:08.111Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[Xcode 10’s build system and Code Generation (R.swift)]]></title>
            <link>https://zendesk.engineering/xcode-10s-build-system-and-code-generation-r-swift-f8d520e28875?source=rss-d0ff76ca6320------2</link>
            <guid isPermaLink="false">https://medium.com/p/f8d520e28875</guid>
            <category><![CDATA[xcode]]></category>
            <category><![CDATA[swift]]></category>
            <dc:creator><![CDATA[Pete Smith]]></dc:creator>
            <pubDate>Wed, 05 Sep 2018 00:21:16 GMT</pubDate>
            <atom:updated>2018-09-05T00:21:16.358Z</atom:updated>
            <content:encoded><![CDATA[<p>Xcode 10 includes a <a href="https://developer.apple.com/xcode/whats-new/">new build system</a>, enabled by default, which improves build performance. This is a very welcome improvement.</p><p><a href="https://github.com/mac-cain13/R.swift">R.swift</a> is an open source library which makes it both easier and type-safe to use resources such as images, fonts, and segues. It’s a really cool library, and we have used it successfully at Zendesk for quite a while now.</p><p>However…</p><h3>The Problem</h3><p>When building a project which uses R.swift with Xcode 10, the build will fail with the following error:</p><pre>error: Build input file cannot be found: /LOCATION/R.generated.swift</pre><h3>Why This Happens</h3><p>R.swift is integrated into projects using an Xcode build script phase. This phase generates a Swift file, R.generated.swift, which is compiled when the project is built.</p><p>The build fails because Xcode 10, with its new parallelizing build system, is trying to locate the R.generated.swift file <em>before </em>it has been created.</p><h3>The Solution</h3><p>Xcode 10 allows us to specify an output file for a build script phase. We can add our R.generated.swift file as an output file as follows:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*52BETSDgvSUR8-Bp7a60ww.png" /><figcaption>Adding our R.generated.swift file as an output file in our Xcode build script phase</figcaption></figure><p>This results in a successful build. Awesome! 🎉</p><h4>Additional</h4><p>When we encountered this initially, we opened a <a href="https://github.com/mac-cain13/R.swift/issues/438">bug</a> with R.swift. However, as shown above, the issue is due to changes in Xcode’s build system.</p><p>That’s it! 📱🚀👍🏽</p><p>Also available on <a href="http://petethedeveloper.com"><em>petethedeveloper.com</em></a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f8d520e28875" width="1" height="1" alt=""><hr><p><a href="https://zendesk.engineering/xcode-10s-build-system-and-code-generation-r-swift-f8d520e28875">Xcode 10’s build system and Code Generation (R.swift)</a> was originally published in <a href="https://zendesk.engineering">Zendesk Engineering</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[iOS How-to — Add Adaptive constraints to support a Universal App]]></title>
            <link>https://zendesk.engineering/ios-how-to-add-adaptive-constraints-to-support-a-universal-app-273663475b12?source=rss-d0ff76ca6320------2</link>
            <guid isPermaLink="false">https://medium.com/p/273663475b12</guid>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[universal-app]]></category>
            <category><![CDATA[interface-builder]]></category>
            <category><![CDATA[xcode]]></category>
            <dc:creator><![CDATA[Pete Smith]]></dc:creator>
            <pubDate>Mon, 18 Jun 2018 23:29:31 GMT</pubDate>
            <atom:updated>2021-12-03T11:38:26.934Z</atom:updated>
            <content:encoded><![CDATA[<p>Xcode’s interface builder allows us to configure layouts which will automatically change shape and size based on a range of environment variables, such as:</p><ul><li>Device screen size (e.g iPhone or iPad)</li><li>Device Orientation (portrait or landscape)</li><li>Adaptation (multi-tasking on iPad)</li></ul><p>In this post, we will learn how to add NSLayoutConstraints in interface builder which adapt to changes in these variables, allowing us to build universal apps which run on both iPhone and iPad.</p><h4>Terminology</h4><p>First, some useful terminology.</p><p><strong>Trait — </strong>Each of the environment variables described above is a trait; screen size, orientation, and adaptation.</p><p><strong>Device configuration — </strong>A devices configuration is a combination of the three traits mentioned above; screen size, orientation (portrait or landscape), and adaptation (iPads running in multitasking mode display in a split-screen, referred to as an adaptation).</p><p><strong>Size class — </strong>A size class is a trait identifies the <em>relative</em> amount of width (horizontal) or height (vertical) available for a view. Size classes depend on the three traits already described. There are two size classes defined by interface builder; compact (in portrait mode, iPhone width is compact, iPhone height is regular), and regular (in landscape mode, iPhone width is regular, iPhone height is compact).</p><h4>Adding adaptive constraints</h4><p>To demonstrate how to add adaptive constraints, we will use the following simple (and slightly contrived!) example of adding a single UIView to another view.</p><p>Our goal is to add constraints which adapt and change based on environment variables. This will result in three layout variations:</p><ol><li><strong>iPhone, portrait</strong> — Our added view should be rectangular, pinned to the left side of the device, and centered vertically.</li><li><strong>iPhone, landscape</strong> — Our added view should be square, pinned to the top of the device, and centered horizontally.</li><li><strong>iPad, portrait or landscape</strong> — Our added view should be rectangular, pinned to the right of the device, and centered vertically.</li></ol><p><em>Note: We are only adapting our constraints for two of the three traits mentioned at the beginning of this post. We are not adapting based on iPad adaptation (mulit-tasking split-screen). In other words, we are dealing only with full screen mode on iPad. This is purely for conciseness. The steps described below can easily be applied to this trait.</em></p><ul><li>We start in interface builder with a UIViewController which contains only it’s default UIView.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*MDwNZvWXn2o4D76j4zxmzw.png" /><figcaption>UIViewController with it’s default UIView</figcaption></figure><ul><li>We add a new UIView as a subview, and change its background color to make it easily identifiable.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*UfnVCV2Mq744KDQCoUXZbA.png" /><figcaption>Subview added as a child view of the default UIView</figcaption></figure><ul><li>Now, open the device configuration pane by clicking the ‘View as:…’ button at the bottom left of the interface builder.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*1zqiGTYDFMfahptSLVvw0Q.png" /><figcaption>Interface builder’s device configuration pane</figcaption></figure><ul><li>The device configuration pane, shown above, allows us to select a device, orientation, and adaptation (if an iPad device is selected). In the image above, the selected device is an iPhone 8 Plus, and the orientation is portrait. The device configuation pane also shows us the size classes for the selected device configuration. In this case the width size class is compact, and the height size class is regular. This is indicated by the ‘(wC hR)’ text at the top of the device configuration pane.</li><li>We will now add constraints for our first layout variation, iPhone in portrait orientation. Click the ‘Vary for Traits’ button at the bottom right. A popover appears, allowing us to select which size class traits we want to create a layout variation for, e.g width, height, or both. Selecting a size class trait creates a variation based on the size class for the currently selected device configuration. e.g If we select width, the variation will be for all compact widths, as that is the width size class for the currently selected device configuration. In our case, we want to create a variation based on both the width and height size classes of the selected device configuration. Select both of these in the popover.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*iest5JxHfMddEfoipwiVwA.png" /><figcaption>Both width and height size classes selected</figcaption></figure><ul><li>Click outside the popover to remove it, and we will now add our constraints for this layout variation. Remember, on iPhone in portrait, our added view should be rectangular, pinned to the left side of the device, and centered vertically. Add a width constraint of 100 to our added view, and a height constraint of 600. Then constrain the view’s leading edge to the safe-area’s leading edge, and constrain the view’s center Y value to the safe-area’s center Y value. Once we have added the constraint, click the ‘Done Varying’ button in the bottom right. The added constraints and resulting layout are shown below.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*mjzMiGebWfvFDy1L8UYPtw.png" /><figcaption>Active constraints for our compact width, regular height (portrait iPhone) device configuration</figcaption></figure><ul><li>Now we move on to our second layout variation, iPhone in landscape orientation. Our currently selected device configuration is iPhone 8 in portrait, so in the device configuration pane, change the orientation to landscape. Interface builder will update to reflect this change in a number of places. First, the interface builder Canvas updates to show the outline of an iPhone in landscape orientation. Second, the text at the top of the device configuration pane updates to show the new size classes. In this case, the new size classes are regular width and compact height, ‘(wR hC)’. Third, the constraints we previously added for our first device configuration are now shown disabled, appearing faded in the interface builder Document Outline. All of these changes are shown in the image below.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ohgFAdrf_jEFLZYBHErGLw.png" /><figcaption>Interface builder changes caused by a change in device configuration</figcaption></figure><ul><li>As before, we click the ‘Vary for Traits’ button. In the popover that appears, select both the width and height size classes. This particular configuration applies only to iPhones in landscape orientation. Next, we add the constraints. Remember, for this configuration, our view should be square, pinned to the top of the device, and centered horizontally. Add a width constraint of 300 to our added view, and a height constraint of 300. Then constrain the view’s top edge to the safe-area’s top edge, and constrain the view’s center X value to the safe-area’s center X value. Once we have added the constraint, click the ‘Done Varying’ button in the bottom right. The constraints we added for this configuration will appear active, while the constraints we added for the previous configuration will appear faded, indicating they are inactive. See the image below.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*V1eJGh7p1rjuYUP-gGsFDw.png" /><figcaption>Active constraints for our regular width, compact height (landscape iPhone) device configuration</figcaption></figure><ul><li>Lastly, our third layout variation, iPad in portrait or landscape orientations. But wait… why are we using one layout variation for both landscape and portrait? Well, the reason is that both the portrait and landscape configurations of an iPad have regular width and regular height size classes (ignoring the Adaptation i.e only considering full-screen iPad configurations). This means that any constraint variations we add for regular width and regular height configurations will apply to both portrait and landscape orientations on iPad. Awesome, we continue. Use the device configuration pane to select the device configuration, selecting either portrait or landscape (ignore the ‘Adaptation’ options, as we said we are only considering full-screen iPad configurations), and click the ‘Vary for Traits’ button. As before, select both width and height size classes from the popover, and add constraints which will result in our view being rectangular, pinned to the right of the device, and centered vertically. Once we have added the constraints click the ‘Done Varying’ button. The constraints and the resulting layouts are shown in the images below.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*9h96zccED10cQCDgk56f5g.png" /><figcaption>Active constraints for our regular width, regular height (portrait iPad) device configuration</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*BgnmXnN2ZznOyJS1DlAjtA.png" /><figcaption>Active constraints for our regular width, regular height (landscape iPad) device configuration</figcaption></figure><ul><li>We have now added constraints for our three device configurations. To quickly check that the constraints we added are correct, we can again select each device configuration, and observe whether the relevant constraints in the Document Outline are active. Also, it’s worth checking the Canvas as we to note how the layout appears.</li></ul><h4>Summary</h4><p>So what have we learned?</p><ul><li>We learned that Xcode and interface builder enable us to adapt our layouts based on a number of <strong>traits.</strong></li><li>We learned how we can use interface builder to select a particular <strong>device configuration</strong>, and then add constraints which only apply to that configuration.</li><li>We also learned that of particular important when creating such layout variations is the configuriaton’s <strong>size classes</strong>, which are based on width and height.</li><li>Using all of these, we learned how to adapt an example layout based on the device configuration, varying a UIView’s position and size depending on whether the device was iPhone or iPad, and whether the orientation was portrait or landscape.</li></ul><p>Awesome! We can now build apps which are universal, running and looking great on both iPhone and iPad. 🎉</p><p>The Xcode project for this post is <a href="https://github.com/superpeteblaze/BlogPost_AdaptiveConstraints">here</a>.</p><p>If you enjoy reading posts like these, consider signing up to become a Medium member. If you sign up using <a href="https://superpeteblaze.medium.com/membership">my link</a>, I’ll earn a small commission.</p><p><a href="https://superpeteblaze.medium.com/membership">https://superpeteblaze.medium.com/membership</a></p><p>That’s it! 📱🚀👍🏽</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=273663475b12" width="1" height="1" alt=""><hr><p><a href="https://zendesk.engineering/ios-how-to-add-adaptive-constraints-to-support-a-universal-app-273663475b12">iOS How-to — Add Adaptive constraints to support a Universal App</a> was originally published in <a href="https://zendesk.engineering">Zendesk Engineering</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Xcode Quick Tip – Testing your layout for localization]]></title>
            <link>https://zendesk.engineering/xcode-quick-tip-testing-your-layout-for-localization-152063dfd7ce?source=rss-d0ff76ca6320------2</link>
            <guid isPermaLink="false">https://medium.com/p/152063dfd7ce</guid>
            <category><![CDATA[testing]]></category>
            <category><![CDATA[l10n]]></category>
            <category><![CDATA[xcode]]></category>
            <category><![CDATA[localization]]></category>
            <category><![CDATA[ios]]></category>
            <dc:creator><![CDATA[Pete Smith]]></dc:creator>
            <pubDate>Tue, 10 Apr 2018 14:09:52 GMT</pubDate>
            <atom:updated>2018-04-10T15:50:47.696Z</atom:updated>
            <content:encoded><![CDATA[<p>The Zendesk <a href="https://itunes.apple.com/us/app/zendesk-support/id1174276185?mt=8">Support</a> app supports a number of languages, meaning that the strings we display in the app change, depending on the device language set.</p><p>Recently we encountered buggy UI component positioning when the device language was changed from the default language (English). This is shown below with Dutch.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/405/1*Wl4vC9iR9TB5d7VHeZy1Lg.png" /><figcaption>UI component (UISwitch) incorrectly positioned due to ambiguous constraints</figcaption></figure><p>Due to some ambiguous auto-layout constraints, the UILabel containing the string increases in size when the string grows in length, causing the next UI element, a UISwitch, to be pushed outside the bounds of the containing view.</p><p>We needed to repeatedly reproduce the issue as we investigated and resolved this bug. Rather than changing the device language, which is cumbersome, we stumbled upon a testing method known as <a href="https://en.wikipedia.org/wiki/Pseudolocalization">pseudolocalization</a>.</p><p>Pseudolocalization is a testing method used to test internationalization which involves replacing the default language strings with altered versions. For exmaple, we might replace “Login” with “Login Login Login Login”.</p><p>We then discovered a very useful option in the Xcode scheme editor which enabled us use pseudolocalization to test our layout, shown below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*veP-G704WdhY_3gyUrRKDw.png" /><figcaption>Xcode scheme setting allowing us to use pseudolocalization to test layout</figcaption></figure><p>Using this setting, all strings in the app are replaced with pseudo-translations consisting of the original string repeated twice. Shown below is the app running with this setting enabled, which results in the default strings being replaced by pseudo-translations.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/405/1*x3cnhM-x9FEMimpXEoOLBw.png" /><figcaption>Pseudo-translations being displayed, highlighting an auto-layout bug</figcaption></figure><p>Using the pseudolocalization Xcode scheme setting, we were able to reproduce the reported issue quickly and implement a fix! 🎉 Our updated UI is shown below.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/405/1*m1wRStvh6YG_5qP--e5e7Q.png" /><figcaption>Pseudo-translations being displayed with the auto-layout bug fixed!</figcaption></figure><h4>In Summary</h4><ul><li>Pseudolocalization is a testing method used to test internationalization which involves replacing the default language strings with altered versions.</li><li>Xcode includes a scheme setting which allows us to test our UI layouts using pseudolocalization.</li><li>Pseudolocalization should be part of normal feature development.</li></ul><p>That’s it! 📱🚀👍🏽</p><p>Also available on <a href="http://petethedeveloper.com"><em>petethedeveloper.com</em></a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=152063dfd7ce" width="1" height="1" alt=""><hr><p><a href="https://zendesk.engineering/xcode-quick-tip-testing-your-layout-for-localization-152063dfd7ce">Xcode Quick Tip – Testing your layout for localization</a> was originally published in <a href="https://zendesk.engineering">Zendesk Engineering</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>