<?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 Rostyslav Dovhaliuk on Medium]]></title>
        <description><![CDATA[Stories by Rostyslav Dovhaliuk on Medium]]></description>
        <link>https://medium.com/@rdovhaliuk?source=rss-eb30806e2170------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*MOl7dg5kqCZzWTXeYowXUg.png</url>
            <title>Stories by Rostyslav Dovhaliuk on Medium</title>
            <link>https://medium.com/@rdovhaliuk?source=rss-eb30806e2170------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Thu, 01 Oct 2026 22:08:22 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@rdovhaliuk/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 14 UISplitViewController: 5 Issues That You May Run Into]]></title>
            <link>https://medium.com/swlh/ios-14-uisplitviewcontroller-5-issues-that-you-may-run-into-65b09601b3fb?source=rss-eb30806e2170------2</link>
            <guid isPermaLink="false">https://medium.com/p/65b09601b3fb</guid>
            <category><![CDATA[uisplitviewcontroller]]></category>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[ios-14]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[uikit]]></category>
            <dc:creator><![CDATA[Rostyslav Dovhaliuk]]></dc:creator>
            <pubDate>Thu, 03 Sep 2020 06:41:14 GMT</pubDate>
            <atom:updated>2020-10-30T08:46:18.101Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*RfJPQRWOURHGmf8B7jAHTQ.png" /></figure><p>The final build of iOS 14.0 will be released soon, and it’s about time to make sure our apps are running great on iOS 14. This year Apple introduced major changes in <em>UISplitViewController</em>, which are mostly dedicated to a new three-column layout and a sidebar. While the new sidebar UI looks great, in this post I will only focus on changes to existing functionality that we already use in our apps and show what can go wrong when your existing app is run on iOS 14. With that said let’s dive in.</p><h3>New style property and why there is an unspecified style type</h3><p>Probably the first thing that you’ll notice when looking at the <em>UISplitViewController</em> API exclusive to iOS 14 will be a new initializer that accepts <em>UISplitViewController.Style</em> as a single argument. While <em>doubleColumn</em> and <em>tripleColumn</em> styles are fairly self-explanatory, there is a third mysterious option called <em>unspecified</em>. After some testing, it became clear that <em>unspecified</em> style is a way to tell UIKit that you want iOS 13 behavior, so if you don’t want to deal right now with all the issues described next, you can enjoy the old behavior even when running on iOS 14, if you’ll use the <em>unspecified</em> style. The only issue with this scenario is that it is a bit tricky to set this specific style. Next, I’ll quickly summarize solutions that do and don’t work for such a task.</p><h4>What does not work</h4><ol><li>Calling new initializer with <em>unspecified</em> style. The most obvious approach, however, it triggers runtime exception with a message</li></ol><blockquote>API misuse. -initWithStyle: may not be used with UISplitViewControllerStyleUnspecified.</blockquote><p>2. Performing <em>setStyle:</em> selector. Leads to exception too with a message</p><blockquote>SPI misuse. -setStyle: should be used by IB to set up UISplitViewController for column-style behavior using UISplitViewControllerStyleDoubleColumn or -TripleColumn <em>(yep, there is a typo in that message).</em></blockquote><h4>What does work</h4><ol><li>If you instantiate your <em>UISplitViewController</em> in code, just call the default <em>NSObject</em> initializer: <em>UISplitViewController()</em>.</li><li>Thankfully, there is also a solution for those who instantiate their <em>UISplitViewController</em> from the storyboard. In the 5th beta of Xcode 12, Apple allowed us to set the unspecified style directly from the Interface Builder.</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/564/1*TGH08o4eAYAh6mIKiXZxsQ.png" /></figure><p>Want to use the modern API instead? Great, stay tuned to see what breaks as soon as you’ll pick the <em>doubleColumn</em> style.</p><h3>Clipped master view controller’s view</h3><p>After choosing the <em>doubleColumn</em> style in Interface Builder and running my app I noticed that for some reason the whole master view controller was clipped.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*EBvV_1n882k883gCvB3uew.png" /></figure><p>The layout of the main menu view controller was created years ago when Safe Area layout guides were not present. Hence, the collection view was constrained to its superview, instead of Safe Area, which caused this weird clipping.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/568/1*RqZYZIlQVTLOJ6ntD01lyQ.png" /></figure><p>After enabling Safe Area layout guides in File inspector everything went back to normal.</p><p>As <a href="https://twitter.com/geoffhackworth">Geoff Hackworth</a> explained in his <a href="https://twitter.com/geoffhackworth/status/1283802290613354498">Tweet</a> the primary view controller is wider than its visible area to support the edge swipe when the primary view controller is hidden. Make sure you have “Show Device Bezel” enabled in Simulator to perform the edge swipe in it.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fimgur.com%2F23Pzmd1%2Fembed%3Fpub%3Dtrue%26ref%3Dhttps%253A%252F%252Fembed.ly%26w%3D900&amp;display_name=Imgur&amp;url=https%3A%2F%2Fimgur.com%2F23Pzmd1&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=imgur" width="900" height="842" frameborder="0" scrolling="no"><a href="https://medium.com/media/38302d5bdac6dc5d8fe8fffa62be9196/href">https://medium.com/media/38302d5bdac6dc5d8fe8fffa62be9196/href</a></iframe><h3>DisplayModeButtonItem is no longer accessible</h3><p>After navigating a bit through the app I noticed the following message in the console</p><blockquote>[Assert] displayModeButtonItem is internally managed and not exposed for DoubleColumn style. Returning an empty, disconnected UIBarButtonItem to fulfill the non-null contract.</blockquote><p>This message showed up right after I tried to set <em>leftBarButtonItem</em> of a detail view controller, which was about to be presented:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ceab3ccdfded765e9dfc69bdfda414c3/href">https://medium.com/media/ceab3ccdfded765e9dfc69bdfda414c3/href</a></iframe><p>Previously this solution allowed me to show a button at the detail view controller that could expand the view controller to the full width of an iPad.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fimgur.com%2F9okfaCZ%2Fembed%3Fpub%3Dtrue%26ref%3Dhttps%253A%252F%252Fembed.ly%26w%3D900&amp;display_name=Imgur&amp;url=https%3A%2F%2Fimgur.com%2F9okfaCZ&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=imgur" width="900" height="688" frameborder="0" scrolling="no"><a href="https://medium.com/media/00ad9929200fb8de5e962a7f76a7099a/href">https://medium.com/media/00ad9929200fb8de5e962a7f76a7099a/href</a></iframe><p>However, on iOS 14 similar functionality is provided by default with a new button displayed on top of master and detail view controllers, so the legacy solution should be executed only on older iOS versions.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fimgur.com%2F2kH1fLQ%2Fembed%3Fpub%3Dtrue%26ref%3Dhttps%253A%252F%252Fembed.ly%26w%3D900&amp;display_name=Imgur&amp;url=https%3A%2F%2Fimgur.com%2F2kH1fLQ&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=imgur" width="900" height="675" frameborder="0" scrolling="no"><a href="https://medium.com/media/e5742bfd30e4474c3439b838f46c4421/href">https://medium.com/media/e5742bfd30e4474c3439b838f46c4421/href</a></iframe><h3>Tint color of expand &amp; collapse button during the transition</h3><p>If you look closely at the last gif, you’ll probably notice that the color of the button changes to standard iOS blue while the transition is going on while <em>UINavigationBar.appearance().tintColor</em> is used at other times. After inspecting the view hierarchy it turned out that there are 3 of such buttons.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*a30QND9GzwMLgR05VGp9Mw.png" /></figure><p>Most likely one of them is shown only when the transition is in progress. After trying several approaches I figured out that the color of that button is defined by <em>UISplitViewController’s</em> view tint color.</p><h3>Nonworking delegate callback</h3><p>After fixing previous flaws I decided to see if everything is good when the app is run on an iPhone. Unfortunately, after launching the app I saw the placeholder view controller instead of the main menu and a message in the console saying</p><blockquote>[UISplitViewController] Skipping delegate callback, splitViewController:collapseSecondaryViewController:ontoPrimaryViewController:. Unsupported for UISplitViewController style DoubleColumn</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*xQQsYtXVwbxvdD_xpAojFw.png" /></figure><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c4c3bfbb61da3354b41d7a8424712054/href">https://medium.com/media/c4c3bfbb61da3354b41d7a8424712054/href</a></iframe><p>Thankfully, there is a new callback introduced in iOS 14, which we can use for the very same purpose:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/22f3e2c90f7b5d184301798a206e3160/href">https://medium.com/media/22f3e2c90f7b5d184301798a206e3160/href</a></iframe><p>Still, the warning about skipped delegate callback will be printed in your console (assuming that you’ve kept the previous callback to support the pre-iOS 14 systems).</p><h3>Final thoughts</h3><p>Overall I’m glad that this year’s migration to the latest iOS turned out to be not complicated at all. Hope you’ll update your apps without issues as well. If you enjoyed this post, please check out <a href="https://apps.apple.com/app/apple-store/id896429646?pt=96439821&amp;ct=Medium&amp;mt=8">my app in the AppStore</a>. That’s all, and thanks for reading!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=65b09601b3fb" width="1" height="1" alt=""><hr><p><a href="https://medium.com/swlh/ios-14-uisplitviewcontroller-5-issues-that-you-may-run-into-65b09601b3fb">iOS 14 UISplitViewController: 5 Issues That You May Run Into</a> was originally published in <a href="https://medium.com/swlh">The Startup</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[iOS 13 UISegmentedControl: 3 important changes]]></title>
            <link>https://rdovhaliuk.medium.com/ios-13-uisegmentedcontrol-3-important-changes-d3a94fdd6763?source=rss-eb30806e2170------2</link>
            <guid isPermaLink="false">https://medium.com/p/d3a94fdd6763</guid>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[ios-app-development]]></category>
            <category><![CDATA[mobile]]></category>
            <category><![CDATA[mobile-app-development]]></category>
            <category><![CDATA[swift]]></category>
            <dc:creator><![CDATA[Rostyslav Dovhaliuk]]></dc:creator>
            <pubDate>Sat, 14 Sep 2019 08:22:16 GMT</pubDate>
            <atom:updated>2020-10-30T08:47:22.239Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*lE2BhFZpBP0w4AVBXk-MKw.png" /></figure><p>iOS 13 brought quite a list of new features: SwiftUI, Combine, Dark Mode, RealityKit, iPad OS, etc. But several things were left almost unnoticed. Among them is a new appearance of some UIKit components. UISegmentedControl alongside with UISwitch, UIStepper, and UISlider got a new look.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/727/1*RYn1f1xmUQ0lR28-MiZwSA.png" /></figure><p>Unfortunately, in the case of UISegmentedControl, those changes caused several issues which I describe next.</p><h4>1. Tint color does not work anymore</h4><p>The “tintColor” property introduced in iOS 7 allowed to change the appearance of UISegmentedControl.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*W8PBkuTxM5zD1bpv8uOpuQ.png" /></figure><p>Starting with iOS 13 “tintColor” does nothing. No matter what color you will assign, the appearance of UISegmentedControl won’t change. To make things even more unintuitive, Apple did not mark this property as deprecated. To give us at least some way to customize colors of UISegmentedControl besides the “backgroundColor” Apple introduced a new property called “selectedSegmentTintColor”. Using this property we can change the color of sliding control.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7gFCdgdD9PSfgCDDVM8y2w.png" /></figure><h4>2. Default background images</h4><p>While trying to pick a good background color for segmented controls in my app I noticed that the color I saw was a bit dull. After inspecting the view hierarchy, I found out that when custom background images are not set, UISegmentedControl uses some default images.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*hlVGZt1hE9Vpk5eKUAjtFg.png" /></figure><p>The fill color of those images can be replicated with black color with 6% opacity. What’s interesting is that we can’t get access to default background image as “backgroundImage(for: .normal, barMetrics: .default)” method returns nil in this case. What’s even worse is that if we set an empty background image (UIImage(), or any image technically) the white image with shadow beneath the sliding control disappears making resulting segmented control unusable.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*0RR8P-yz0untxxhX8m2RrA.png" /></figure><p>Such behavior makes it impossible to use some pure background colors, e.g. white. Sure, we can assign it, but in the end, it will appear slightly gray due to blending with default background images.</p><h4>3. Default rounded corners</h4><p>Another problem arises when background images that cover all frame of segmented control are used. Starting with iOS 13 a corner radius is set no matter if custom background images are used or not which leads to clipped corners:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/858/1*-S98jN3Y9-fyCVSc1aF4AA.png" /></figure><p>Fortunately, this issue can be fixed using the custom subclass of UISegmentedControl with overridden “layoutSubviews” method:</p><pre>class SquareSegmentedControl: UISegmentedControl {<br>    override func layoutSubviews() {<br>        super.layoutSubviews()<br>        layer.cornerRadius = 0    <br>    }<br>}</pre><h4>Final thoughts</h4><p>Overall I have mixed feelings about an update of UISegmentedControl in this iOS release. Sure the new look is interesting, but it may force us to adapt the design of other sections of our apps for them to look more natural alongside new UISegmentedControl, and there is no way to get complete iOS 12 appearance back to win some additional time necessary for app redesign.</p><p>There is a way to get partial iOS 12 style back, described at <a href="https://stackoverflow.com/a/56458794">https://stackoverflow.com/a/56458794</a>. But it will only work for solid color backgrounds, because in iOS 12 you could see the background view through the text of selected segment or uncolored portion of the unselected segment.</p><p>If you enjoyed this post, please check out <a href="https://apps.apple.com/app/apple-store/id896429646?pt=96439821&amp;ct=Medium&amp;mt=8">my app in the AppStore</a>. That’s all, thanks for reading!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d3a94fdd6763" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Implementing In-App purchases without Keychain and UserDefaults]]></title>
            <link>https://rdovhaliuk.medium.com/implementing-in-app-purchases-without-keychain-and-userdefaults-52a43c0f76e8?source=rss-eb30806e2170------2</link>
            <guid isPermaLink="false">https://medium.com/p/52a43c0f76e8</guid>
            <category><![CDATA[in-app-purchase]]></category>
            <category><![CDATA[ios-development]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[swift]]></category>
            <dc:creator><![CDATA[Rostyslav Dovhaliuk]]></dc:creator>
            <pubDate>Mon, 11 Feb 2019 08:48:23 GMT</pubDate>
            <atom:updated>2020-10-30T08:48:17.335Z</atom:updated>
            <content:encoded><![CDATA[<h3>Implementing In-App Purchases without Keychain and UserDefaults (Updated for Xcode 12)</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*fMPfHv24SUxPYxY-Uql4tw.png" /></figure><blockquote>This post has been updated to include the recent additions in Xcode 12 dedicated to In-App purchases testing.</blockquote><p>One of the In-App purchases implementation steps that every developer eventually faces is a choice of a suitable purchase record persistence strategy which will make possible to give access to paid content after app relaunch.</p><p>The most obvious way of persisting the purchase is to store some value in UserDefaults that will indicate whether or not some content has been unlocked. Such approach is shown in two tutorials at raywenderlich.com written by <a href="https://www.raywenderlich.com/754-in-app-purchases-non-renewing-subscriptions-tutorial">Owen Brown</a> and <a href="https://www.raywenderlich.com/5456-in-app-purchase-tutorial-getting-started">Pietro Rea</a>, where UserDefaults are used to store a boolean flag to indicate non-consumable products purchase status as well as Date instance to persist the subscription expiration date. Such a solution is often criticized due to lack of data integrity protection, as content present in UserDefaults is stored as an ordinary binary plist in the Preferences folder of app&#39;s bundle and thus can be edited by the user using software like iMazing, iFunBox or iExplorer as shown by Andrés Ibañez in his <a href="https://www.andyibanez.com/nsuserdefaults-not-for-sensitive-data/">2014 post</a>.</p><p>While this is true, I would like to mention that since iOS 8.3 <a href="https://support.imazing.com/hc/en-us/articles/206140907-iOS-8-3-File-Sharing">Apple introduced serious permission restrictions</a> in file system access, which eliminated access to application’s internal files from outside on non-jailbroken devices. Speaking about Jailbreak, it is worth reminding that its popularity has been decreasing over last years to the point that its pioneers say that <a href="https://www.cultofmac.com/490594/jailbreaking-pioneers-say-iphone-jailbreaking-dead/">jailbreaking is dead</a>. From personal observations, I can say that it takes more and more effort to release an untethered jailbreak for the newest iOS version. Starting with iOS 10 it takes at least 6 months for hackers to release a jailbreak, which can be used by an average iOS user. It is why I think that the chances are pretty low that any significant portion of the app’s users would tamper with app’s files.</p><p>Still, it doesn’t take much effort to use a Keychain instead of UserDefaults as shown by Axel Kee in his <a href="https://fluffy.es/check-purchased-iap-using-keychain/">post</a>. The principle is the same — store a string like “purchased” for identifiers of purchased products. It is worth mentioning that in iOS 10.3 betas, Apple started to remove all app-related records in Keychain <a href="https://forums.developer.apple.com/message/210531#210531">after app uninstallation</a>. However, as it turned out, many people relied on the previous behavior of Keychain even though it wasn’t documented, and Apple had to <a href="https://developer.apple.com/forums/thread/36442">revert this change</a> in iOS 11+. The bottom line is that if you want to persist In-App purchases between app installations, you can use the Keychain, but Apple may change its behavior once again in the future.</p><p>There is, however, an alternative approach to check if a user has purchased something without relying on UserDefaults or Keychain by using a receipt, which is automatically updated by the OS on every purchase. Even though the idea of receipt usage for this purpose is clearly documented in Apple’s <a href="https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Chapters/DeliverProduct.html#//apple_ref/doc/uid/TP40008267-CH5-SW3">In-App Purchase Programming Guide</a>, it seems like this approach lacks attention in 3rd party tutorials. One reason for that might be that this persistence strategy is applicable only for non-consumable products and auto-renewable subscriptions. If you are implementing either consumable or non-renewing subscriptions, then you are left with Keychain, iCloud, or your own backend. The second obstacle of app receipt usage is its complex structure that requires a good amount of tricks to read the necessary information. The <a href="https://www.raywenderlich.com/9257-in-app-purchases-receipt-validation-tutorial">tutorial by Bill Morefield</a> does a good job in showcasing what it takes to read an app receipt in Swift without 3rd party dependencies. Thankfully, folks from Cocoanetics created a <a href="https://github.com/Cocoanetics/Kvitto">Kvitto</a> library, which makes work with an app receipt a breathe. Alternatively, you can also use a <a href="https://github.com/tikhop/TPInAppReceipt/">TPInAppReceipt</a> library by Pavel Tikhonenko for the same purpose.</p><p>Recently I successfully implemented both non-consumable purchase and auto-renewable subscription in my app called <a href="https://itunes.apple.com/ua/app/electronics-engineer-helper/id896429646?mt=8">Electronics Engineer Helper</a> using app receipt as a persistent record of the purchase. The method of InAppPurchaseManager that reads the receipt looks like this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/3c449a398efc0c679d96690593b2e4cf/href">https://medium.com/media/3c449a398efc0c679d96690593b2e4cf/href</a></iframe><p>The method simply parses receipt to find relevant entries by comparing the product identifier and uses tuples inside of the switch statement along with ternary operations to return appropriate purchases status.</p><p>Another method worth checking out is a paymentQueue(_:updatedTransactions:) of SKProductsRequestDelegate:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d7e35aae8367d92b371051697a46e7d6/href">https://medium.com/media/d7e35aae8367d92b371051697a46e7d6/href</a></iframe><p>In this method I simply forward events to BehaviorRelay (a class from RxSwift library) and read purchase status from app receipt when all transactions have been handled.</p><p>In Xcode 12, Apple introduced a new In-App purchases environment called Xcode and <a href="https://developer.apple.com/documentation/xcode/setting_up_storekit_testing_in_xcode">StoreKit configuration files</a>. By adding such a configuration (File &gt; New &gt; File … &gt; StoreKit Configuration File) you can now test In-App purchases both in a simulator and physical device without resorting to workarounds like specifying purchases status via the environment variable.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*N1E7rIxE-4ts5RDDoWZWDw.png" /></figure><p>What’s also great with StoreKit testing is that not only your code is called in exactly the same way as in the production environment, but you also see a production-like purchasing dialogs.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/750/1*fjcEMJ5x31eK6_QTPe40FA.png" /></figure><p>With a new Transactions Manager, you can easily remove purchases from the receipt and simulate edge cases like interrupted or deferred purchases.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*OeCRbJvAovP_HirgAorbiQ.png" /></figure><p>You can check out the full code of my InAppPurchaseManager in <a href="https://gist.github.com/RenGate/261dd84a02b0a17e18aaa69254923355">the gist</a>. By leveraging RxSwift, Kvitto, and app receipt an implementation of In-App purchases didn&#39;t cause much trouble.</p><p>If you enjoyed this post, please check out <a href="https://apps.apple.com/app/apple-store/id896429646?pt=96439821&amp;ct=Medium&amp;mt=8">my app in the AppStore</a>, and thank’s for reading.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=52a43c0f76e8" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Spectre and Meltdown fixes influence on iOS apps build time]]></title>
            <link>https://rdovhaliuk.medium.com/spectre-and-meltdown-fixes-influence-on-ios-apps-build-time-40b3f7b4bca6?source=rss-eb30806e2170------2</link>
            <guid isPermaLink="false">https://medium.com/p/40b3f7b4bca6</guid>
            <category><![CDATA[respect]]></category>
            <category><![CDATA[mac]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[meltdown]]></category>
            <dc:creator><![CDATA[Rostyslav Dovhaliuk]]></dc:creator>
            <pubDate>Wed, 07 Feb 2018 09:16:24 GMT</pubDate>
            <atom:updated>2018-02-07T09:16:24.300Z</atom:updated>
            <content:encoded><![CDATA[<p>At the beginning of 2018, a public report about Spectre and Meltdown vulnerabilities has been revealed to the general public. Since that day, a number of hardware and software vendors released various patches to eliminate a possibility to exploit mentioned vulnerabilities. <br>Due to hardware nature of both vulnerabilities, software workarounds were required to mitigate the risk. However, despite its convenience for end users, such solution came at a price. As soon as first fixed were deployed, some reports about decreased system performance started to show up around the Internet, with some of them claiming up to 5% slowdown for typical use cases [<a href="https://lwn.net/Articles/738997/">1</a>]. Apple addressed Spectre and Meltdown in 10.13.2 and 10.13.3 releases of macOS High Sierra [<a href="https://www.macrumors.com/2018/01/23/macos-sierra-el-capitan-spectre-meltdown-fixes/">2</a>], and it remains to be seen how those patches will affect our productivity as developers who use Xcode to build software. A number of benchmarks were published at [<a href="https://reverse.put.as/2018/01/07/measuring-osx-meltdown-patches-performance/">3</a>] describing Geekbench 4 score and XNU kernel build time difference between all High Sierra releases except 10.13.3 and newer. The performance loss of 2% to 9% has been reported for XNU kernel compilation.</p><p>In this post, I would like to focus specifically on the evaluation of potential slowdown during iOS apps compilation.</p><h3>Spectre and Meltdown fixes aftermath</h3><p>To find out whether there is any significant difference between build time on macOS versions with and without fixed vulnerabilities, I used 3 apps written in Swift: <a href="https://github.com/mozilla-mobile/firefox-ios">Firefox</a> (master, 4cd9bcd), <a href="https://github.com/kickstarter/ios-oss">Kickstarter</a> (master, 445373b) as well as my own free app <a href="https://itunes.apple.com/app/apple-store/id896429646?pt=96439821&amp;ct=medium&amp;mt=8">Electronics Engineer Helper</a>. Each project was compiled 16 times on each macOS version using a simple bash script</p><pre>#! /bin/bash</pre><pre>PROJECT_NAME=$1<br>SCHEME_NAME=$2<br>CONFIGURATION=$3</pre><pre>for ((n=0;n&lt;16;n++));<br>do<br>    rm -rf ~/Library/Developer/Xcode/DerivedData/*<br>    /usr/bin/time -p xcodebuild -project $PROJECT_NAME -scheme $SCHEME_NAME -configuration $CONFIGURATION -sdk iphonesimulator build &gt; /dev/null<br>    sleep 10<br>done</pre><p>…which was used with following input arguments</p><pre>./profile.sh Kickstarter.xcodeproj Kickstarter-iOS Release<br>./profile.sh Client.xcodeproj Fennec Firefox<br>./profile.sh “Electronics Engineer Helper.xcodeproj” “Electronics Engineer Helper” Release</pre><p>It’s important to manually clean DerivedData folder before each run, as simply passing clean command to xcodebuild will not remove the ModuleCache, and so the duration of a first and all following builds will be slightly different.</p><p>All apps were compiled using Xcode 9.2 (9C40b) on a Hackintosh featuring Core i7 6700K CPU (4 cores, 4 GHz), 32 GB of RAM (DDR4, 2400 MHz) and Kingston KC1000 SSD (NVMe, 240 GB, PCIe 3, 4 Lanes). DerivedData was located on a RAM disk created using the <a href="https://www.magnesium-app.com">iRamDisk</a> app.</p><p>With all data collected, a mean build time as well as <a href="https://en.wikipedia.org/wiki/Margin_of_error">margin of error at 95% confidence level</a> was calculated. The calculation of margin of error will help us to better understand whether any difference between two OS releases is just a random fluctuation or not.</p><p>With that said, let’s see the results.</p><pre>                                        Build time, seconds<br>          Application            ---------------------------------<br>                                     10.13.1           10.13.3      <br> -----------------------------   ---------------   --------------- <br>  Kickstarter                    302.776 ± 0.299   308.541 ± 1.344  <br>  Firefox                        146.935 ± 1.297   151.014 ± 0.949  <br>  Electronics Engineer Helper    165.211 ± 0.525   171.021 ± 0.537</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*vt_yK7vNwFxl3R5jCcOjuw.png" /></figure><h3>Conclusion</h3><p>The slowdown due to Spectre and Meltdown fixes is definitely present, but the good news is that it is barely noticeable. For mentioned projects, the build time increased on average from 1.9% to 3.5%, which is similar to the results of other benchmarks posted on the web.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=40b3f7b4bca6" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>