<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Paulo&#39;s Blog | Programming, technology, running a business and everything else</title>
    <link>https://pfandrade.me/</link>
    <description>Recent content on Paulo&#39;s Blog | Programming, technology, running a business and everything else</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Mon, 07 Mar 2022 13:35:25 +0000</lastBuildDate><atom:link href="https://pfandrade.me/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Mixing Swift, Objective-C, SPM and Static Frameworks</title>
      <link>https://pfandrade.me/blog/mixing-swift-objective-c-spm-and-static-frameworks/</link>
      <pubDate>Mon, 07 Mar 2022 13:35:25 +0000</pubDate>
      
      <guid>https://pfandrade.me/blog/mixing-swift-objective-c-spm-and-static-frameworks/</guid>
      <description>There&amp;rsquo;s always something new in a developer&amp;rsquo;s world: a new framework, a new IDE, a new CPU architecture, a new language, a new dependency management system, etc. For any moderately large project it&amp;rsquo;s impossible to keep up. Nor should you even try, or you&amp;rsquo;d just spend your time rewriting code.
I&amp;rsquo;ve been working on Secrets for the past 10 years. There are parts of it that were written before ARC. You can still find retain and release calls today!</description>
    </item>
    
    <item>
      <title>Pitfalls When Validating App Store Receipts on macOS</title>
      <link>https://pfandrade.me/blog/pitfalls-when-validating-app-store-receipts-on-macos/</link>
      <pubDate>Thu, 23 Sep 2021 13:23:25 +0000</pubDate>
      
      <guid>https://pfandrade.me/blog/pitfalls-when-validating-app-store-receipts-on-macos/</guid>
      <description>To activate paid features in the app, Secrets has always done local receipt validation.
Succinctly validation involves two steps:
 Checking the signature on the receipt is valid. Checking if that receipt was generated for the current device.  For the second step you need a device identifier which must match the one the App Store used to generate the receipt. And here lies the problem.
On iOS getting a device identifier is very simple, you just call identifierForVendor on UIDevice.</description>
    </item>
    
    <item>
      <title>Tweaking Animation Timing</title>
      <link>https://pfandrade.me/blog/tweaking-animation-timing/</link>
      <pubDate>Thu, 22 Jul 2021 13:00:25 +0000</pubDate>
      
      <guid>https://pfandrade.me/blog/tweaking-animation-timing/</guid>
      <description>Recently I found myself wanting to change the timing of an animation. The standard easy-in, easy-out timing functions just weren&amp;rsquo;t &amp;ldquo;feeling&amp;rdquo; right. In this particular case I felt the animation needed to be more spring-like.
More precisely, I wanted this view to accerelate faster and brake slowly at the end. Not necessarily overshooting. &amp;ldquo;I&amp;rsquo;ll just use an overdamped spring animation.&amp;rdquo; &amp;mdash; I thought.
Trouble is, this view was animating along a path &amp;mdash; an arc.</description>
    </item>
    
    <item>
      <title>Firefox Add-ons Review Madness</title>
      <link>https://pfandrade.me/blog/firefox-add-ons-review-madness/</link>
      <pubDate>Mon, 22 Mar 2021 14:54:25 +0000</pubDate>
      
      <guid>https://pfandrade.me/blog/firefox-add-ons-review-madness/</guid>
      <description>I&amp;rsquo;ve been dealing with Apple&amp;rsquo;s App Review team for so many years now I could probably write a book with the stories I have from it. But little did I know the most ridiculous story would not come from Apple, but from Mozilla&amp;rsquo;s Add-ons review team.
And do note I got some pretty ridiculous stories from Apple.
Secrets for Firefox Last week I launched Secrets 3.6 and with it comes a new feature that required updates to the browser extensions.</description>
    </item>
    
    <item>
      <title>Generic View Controllers with Storyboards</title>
      <link>https://pfandrade.me/blog/generic-view-controllers-with-storyboards/</link>
      <pubDate>Fri, 05 Feb 2021 18:10:25 +0000</pubDate>
      
      <guid>https://pfandrade.me/blog/generic-view-controllers-with-storyboards/</guid>
      <description>Trying to use storyboards with generic view controllers as always been problematic. The problem is the storyboard also encodes the class of the view controller for each &amp;ldquo;scene&amp;rdquo;. But you don&amp;rsquo;t know the class beforehand since it can it&amp;rsquo;s a generic class and can be parameterised with various types. For example, take this class:
class Foo&amp;lt;V: Equatable&amp;gt;: UIViewController { // outlets, actions, business logic } What would write for &amp;ldquo;Custom Class&amp;rdquo; in the storyboard?</description>
    </item>
    
    <item>
      <title>Hey Siri, I&#39;m Arriving Home</title>
      <link>https://pfandrade.me/blog/hey-siri-im-arriving-home/</link>
      <pubDate>Thu, 10 Dec 2020 09:43:25 +0000</pubDate>
      
      <guid>https://pfandrade.me/blog/hey-siri-im-arriving-home/</guid>
      <description>Last year, I used an old Raspberry Pi and some simple circuitry to add my garage door to HomeKit. And for the past year that&amp;rsquo;s been working surprisingly well for something that looks like this:
   Raspberry Pi and related circuitry to control the garage door.
   I was using it daily and I believe it only failed 3 or 4 times. After some investigation I figured out that for some reason my relay would sometimes stop responding.</description>
    </item>
    
    <item>
      <title>AnyDecodable</title>
      <link>https://pfandrade.me/blog/anydecodable/</link>
      <pubDate>Wed, 12 Feb 2020 15:40:25 +0000</pubDate>
      
      <guid>https://pfandrade.me/blog/anydecodable/</guid>
      <description>Swift&amp;rsquo;s Codable is great, but sometimes the type-safety can get in the way. There are cases when decoding JSON where you don&amp;rsquo;t know beforehand what is it that you are decoding.
In my case, the JSON had a type field that disambiguated what it represents. Intuitively, I felt like I needed to peek into the JSON to figure out what the type is and then call decoder.decode(Foo.self, jsonData). After playing around with this a bit, I figured that instead of &amp;ldquo;peeking&amp;rdquo; into the JSON I might just as well try and decode whatever types I was expecting.</description>
    </item>
    
    <item>
      <title>Xconfig</title>
      <link>https://pfandrade.me/blog/xconfig/</link>
      <pubDate>Mon, 10 Feb 2020 15:03:25 +0000</pubDate>
      
      <guid>https://pfandrade.me/blog/xconfig/</guid>
      <description>If you&amp;rsquo;re like me, when working with .xcconfig files or building your shell script to include in a &amp;ldquo;Run Script&amp;rdquo; phase, you&amp;rsquo;ll keep running to the Terminal to run this:
xcodebuild -project &amp;lt;Project&amp;gt;.xcodeproj -target &amp;lt;Target&amp;gt; -showBuildSettings
But this means, opening the terminal, cd&amp;rsquo;ing to your project&amp;rsquo;s folder, remembering and typing all of that, and then piping that to a grep to figure out which build setting you want.
So I&amp;rsquo;ve build Xconfig, a simple Mac app to display build settings for the currently open Xcode projects.</description>
    </item>
    
    <item>
      <title>Splitting Your Xcode Project into Modules</title>
      <link>https://pfandrade.me/blog/splitting-your-xcode-project-into-modules/</link>
      <pubDate>Thu, 06 Feb 2020 14:08:25 +0000</pubDate>
      
      <guid>https://pfandrade.me/blog/splitting-your-xcode-project-into-modules/</guid>
      <description>Update on 2020-03-05
Apparently the -undefined dynamic_lookup flag I mention at the bottom of this post is incompatible with bitcode. If you use that flag on a dynamic framework that has bitcode enabled you&amp;rsquo;ll get a build error with the latest version of Xcode.
-undefined and -bitcode_bundle (Xcode setting ENABLE_BITCODE=YES) cannot be used together The obvious solution would be to disable bitcode. But Apple already mandates this for watchOS and tvOS apps.</description>
    </item>
    
    <item>
      <title>Unsafe Swift</title>
      <link>https://pfandrade.me/blog/unsafe-swift/</link>
      <pubDate>Tue, 07 Jan 2020 15:24:25 +0000</pubDate>
      
      <guid>https://pfandrade.me/blog/unsafe-swift/</guid>
      <description>Swift Aveiro&amp;rsquo;s 2020 event was just announced and I thought now would be a good time to convert my workshop from last year&amp;rsquo;s event to a blog post.
The workshop was divided in two parts: working with pointers and interacting with C libraries. This post covers the first part.
If you&amp;rsquo;ve ever encountered the dreadful UnsafeMutableRawBufferPointer or one of its friends and ran to stackoverflow… then this post is for you!</description>
    </item>
    
    <item>
      <title>The Missing &#34;k&#34; Bug</title>
      <link>https://pfandrade.me/blog/the-missing-k-bug/</link>
      <pubDate>Thu, 28 Nov 2019 14:28:25 +0000</pubDate>
      
      <guid>https://pfandrade.me/blog/the-missing-k-bug/</guid>
      <description>Coding can be a lot of fun. And one of the things you can have fun with is fixing bugs1.
Getting a list of symptoms, formulating hypothesis and narrowing those down with tests, arriving at a diagnosis, and ultimately, fixing the bug. The entire process is very similar to what Doctors do and can be very interesting.
Now… some bugs are more interesting than others hence the reason for this blog post.</description>
    </item>
    
    <item>
      <title>@DynamicFont</title>
      <link>https://pfandrade.me/blog/dynamicfont/</link>
      <pubDate>Wed, 18 Sep 2019 10:30:25 +0000</pubDate>
      
      <guid>https://pfandrade.me/blog/dynamicfont/</guid>
      <description>Undoubtedly one of the biggest features developers need to tackle for iOS 13 is Dark Mode. Needless to say I’ve been hard at work to bring that to Secrets. Not only that but, since I’m reviewing all app screens I&amp;rsquo;m also adding support for Dynamic Type. To that effect I’ve been working on a new UI component written in Swift.
This component (technically a framework) should contain all presentation related code.</description>
    </item>
    
    <item>
      <title>Hey Siri, Open My Garage Door</title>
      <link>https://pfandrade.me/blog/hey-siri-open-my-garage-door/</link>
      <pubDate>Tue, 03 Sep 2019 10:30:25 +0000</pubDate>
      
      <guid>https://pfandrade.me/blog/hey-siri-open-my-garage-door/</guid>
      <description>I&amp;rsquo;ve been meaning to add my garage door to HomeKit for quite some time. And not just for fun. There are some good reasons why this would improve my quality of life:
 My wife has already lost two garage door remotes. Her iPhone, however, fortunately never gets lost. If you&amp;rsquo;re like me you&amp;rsquo;ll never remember if you actually pressed the button to close the garage on the way out. And this doubt will only pop up when you&amp;rsquo;re already at the end of the street.</description>
    </item>
    
    <item>
      <title>The Alert Hammer</title>
      <link>https://pfandrade.me/blog/the-alert-hammer/</link>
      <pubDate>Wed, 31 Jul 2019 15:30:25 +0000</pubDate>
      
      <guid>https://pfandrade.me/blog/the-alert-hammer/</guid>
      <description>To a man with a hammer, everything looks like a nail.
 There has been a lot of discussion about the increasing number of security alerts Apple has been adding to macOS, both with Mojave (10.14) and the upcoming Catalina (10.15). Michael Tsai has collected a large portion of that on his blog. So much has been said that I almost gave up on writing this… but seeing Apple go this route is so frustrating that I needed to vent.</description>
    </item>
    
    <item>
      <title>Bootstrapping your indie business</title>
      <link>https://pfandrade.me/blog/bootstrapping-your-indie-business/</link>
      <pubDate>Mon, 24 Jun 2019 15:50:25 +0000</pubDate>
      
      <guid>https://pfandrade.me/blog/bootstrapping-your-indie-business/</guid>
      <description>A few months ago I gave my first pubic talk at Pixels Camp v3.0 where I gave some tips on starting your own business.
The lessons I shared were based on my own experience and the talk ended up being a lot more personal than I originally anticipated. For a conference heavily centered in technology I wasn&amp;rsquo;t sure how this was going to be received but the feedback was actually pretty good.</description>
    </item>
    
    <item>
      <title>Thoughts on WWDC 19</title>
      <link>https://pfandrade.me/blog/thoughts-on-wwdc-19/</link>
      <pubDate>Fri, 07 Jun 2019 15:10:25 +0000</pubDate>
      
      <guid>https://pfandrade.me/blog/thoughts-on-wwdc-19/</guid>
      <description>I&amp;rsquo;ve always enjoyed the days after a WWDC Keynote. It&amp;rsquo;s a mix of excitement and anxiety over the new refinements/features/frameworks and all the learning and work those entail. This year is no different… except those feelings are amped up to 11!
   This year&amp;#39;s &amp;#34;blow minds&amp;#34; artwork really seems on point
   The keynote was pretty good over all with solid incremental updates on all platforms. Standalone watch apps, Dark Mode and the new Photos.</description>
    </item>
    
    <item>
      <title>UI Testing and NSScrollView</title>
      <link>https://pfandrade.me/blog/ui-testing-and-nsscrollview/</link>
      <pubDate>Tue, 30 Apr 2019 19:10:25 +0000</pubDate>
      
      <guid>https://pfandrade.me/blog/ui-testing-and-nsscrollview/</guid>
      <description>If your Mac app uses NSScrollViews and you&amp;rsquo;re writing UI tests, eventually you&amp;rsquo;ll have the need to click a cell, button or view that is outside the scrollview&amp;rsquo;s view port.
Turns out the solution is quite simple but since this is a fairly common problem I felt it was worthy of a blog post.1.
@implementation XCUIElement (Additions) - (BOOL)scrollRevealing:(XCUIElement *)element { if(self.elementType != XCUIElementTypeScrollView){ return NO; } CGRect scrollFrame = [self frame]; CGRect elementFrame = [element frame]; // figure out if we need to scroll up or down  CGFloat direction = elementFrame.</description>
    </item>
    
    <item>
      <title>Search Scopes in Xcode</title>
      <link>https://pfandrade.me/blog/search-scopes-in-xcode/</link>
      <pubDate>Wed, 03 Apr 2019 14:10:25 +0000</pubDate>
      
      <guid>https://pfandrade.me/blog/search-scopes-in-xcode/</guid>
      <description>On first use, Xcode&amp;rsquo;s Find In Project… feature may appear basic. After all it fits on this little rectangle space inside Xcode&amp;rsquo;s UI.
 But beneath that apparently simply interface there&amp;rsquo;re a ton of features besides a simple find: regular expression searches, find &amp;amp; replace, symbol search, caller search… Another one of those features is search scopes. I&amp;rsquo;ve been using this more and more lately and that&amp;rsquo;s what this post is all about.</description>
    </item>
    
    <item>
      <title>Late Responders — Sidestepping The Responder Chain</title>
      <link>https://pfandrade.me/blog/late-responders-sidestepping-the-responder-chain/</link>
      <pubDate>Wed, 13 Mar 2019 17:07:08 +0100</pubDate>
      
      <guid>https://pfandrade.me/blog/late-responders-sidestepping-the-responder-chain/</guid>
      <description>The responder chain is a simple but powerful concept present in any Cocoa/Cocoa Touch app. Simply put, the responder chain is a linked list of responders (most commonly views and view controllers) to which an event or action is applied. When a responder doesn’t handle a particular message, it simply passes the message up the chain.
But this post isn&amp;rsquo;t about how the responder chain works, the documentation already does an excellent job at that.</description>
    </item>
    
    <item>
      <title>Inverted Expectations</title>
      <link>https://pfandrade.me/blog/inverted-expectations/</link>
      <pubDate>Thu, 14 Feb 2019 15:53:25 +0000</pubDate>
      
      <guid>https://pfandrade.me/blog/inverted-expectations/</guid>
      <description>While writing some unit tests I needed to assert a notification did not get sent after calling a method.
The usual pattern for testing the sending of notifications is to use the existing XCTNSNotificationExpectation like so:
let notificationExpectation = expectation(forNotification: NSNotification.Name.SomeNotification, object: obj, handler: nil) // exercise your code and wait for the expectation wait(for: [notificationExpectation], timeout: 1.0) But what about asserting a notification isn&amp;rsquo;t sent? Waiting for an expectation that&amp;rsquo;s not fulfilled will always result in an error… So I started browsing the headers of XCTest and I came across isInverted property on XCTestExpectation.</description>
    </item>
    
    <item>
      <title>Xcode: Comparing Build Settings</title>
      <link>https://pfandrade.me/blog/xcode-comparing-build-settings/</link>
      <pubDate>Thu, 31 Jan 2019 10:36:25 +0000</pubDate>
      
      <guid>https://pfandrade.me/blog/xcode-comparing-build-settings/</guid>
      <description>❡ I&amp;rsquo;ve been using Xcode since about 2004, I believe I started on version 1.5. It&amp;rsquo;s easily the IDE I&amp;rsquo;ve worked with the most… and probably the app I&amp;rsquo;ve spent more time on.
Other IDE&amp;rsquo;s I&amp;rsquo;ve used include Eclipse, IDEA and more recently Visual Studio Code. All of them have their pros &amp;amp; cons but, understandably, Xcode is still where I&amp;rsquo;m most confortable.
Based on my experience, I think Xcode gets some undeserved bad rep… Thus, I&amp;rsquo;m starting an &amp;ldquo;Xcode Tips&amp;rdquo; series to share some of the not so obvious features I&amp;rsquo;ve picked up along the way.</description>
    </item>
    
    <item>
      <title>iPad Pro — First Impressions</title>
      <link>https://pfandrade.me/blog/ipad-pro-first-impressions/</link>
      <pubDate>Sat, 05 Jan 2019 20:08:25 +0000</pubDate>
      
      <guid>https://pfandrade.me/blog/ipad-pro-first-impressions/</guid>
      <description>After spending a few weeks with the new iPad Pro I felt it was time to write down my first impressions. So lets get to it!
The Good The machine is definitely fast, which shouldn&amp;rsquo;t be a surprise based on all the reviews but it is. Everything feels snappy and responsive.
Having the Smart Keyboard really makes a difference on your productivity. Typing is much faster, switching between apps with command+tab feels super natural and many other shortcuts such as command+space to invoke Spotlight or command+shift+4 to take a screenshot work as expected.</description>
    </item>
    
    <item>
      <title>Building Expectations</title>
      <link>https://pfandrade.me/blog/building-expectations/</link>
      <pubDate>Mon, 17 Dec 2018 14:59:25 +0000</pubDate>
      
      <guid>https://pfandrade.me/blog/building-expectations/</guid>
      <description>Nowadays most of our asynchronous code is handled via callbacks. But there are times where it&amp;rsquo;s a lot easier to simply wait for an asynchronous task to finish. My latest example of this was an NSOperation subclass that needed to do some network communication before it could finish. I could have made that custom operation asynchronous but it was a lot simpler to just override -main and wait for the network result.</description>
    </item>
    
    <item>
      <title>The 2018 iPad Pro</title>
      <link>https://pfandrade.me/blog/the-2018-ipad-pro/</link>
      <pubDate>Wed, 14 Nov 2018 15:36:25 +0000</pubDate>
      
      <guid>https://pfandrade.me/blog/the-2018-ipad-pro/</guid>
      <description>I&amp;rsquo;m not an iPad user. I have a 4th generation iPad I won in a hackathon years ago but I&amp;rsquo;ve never actually used it… It lives its life as a test device for Secrets and, occasionally, as a canvas for my 3 year old son&amp;rsquo;s finger drawings.
I just bought this year&amp;rsquo;s 12.9-inch iPad Pro and I want to tell you why.
The original iPad When Steve introduced the iPad back in 2010 he introduced a new device category.</description>
    </item>
    
    <item>
      <title>Quick TCP Server Using NSSocketPort</title>
      <link>https://pfandrade.me/blog/quick-tcp-server-using-nssocketport/</link>
      <pubDate>Mon, 22 Oct 2018 13:23:25 +0100</pubDate>
      
      <guid>https://pfandrade.me/blog/quick-tcp-server-using-nssocketport/</guid>
      <description>For several occasions now, I&amp;rsquo;ve found myself in the need to spin up a simple TCP server when writing tests. Usually my needs are very simple, I just need to accept some connection and stub some responses.
There are plenty of libraries out there that serve this purpose but it feels such an overkill to add another dependency just for running my tests. So I usually just end up calling socket, bind and listen even though that&amp;rsquo;s still a lot of code for something so simple and feels out of place in Cocoa.</description>
    </item>
    
    <item>
      <title>Is There Hope for the Mac App Store?</title>
      <link>https://pfandrade.me/blog/is-there-hope-for-the-mac-app-store/</link>
      <pubDate>Fri, 12 Oct 2018 10:21:25 +0100</pubDate>
      
      <guid>https://pfandrade.me/blog/is-there-hope-for-the-mac-app-store/</guid>
      <description>As a user and as the family tech support I believe a curated App Store provides imense value. A user should be able to install an app with confidence and not fear it messing with their device or their private data. Honestly, this should&amp;rsquo;ve always been the case. There&amp;rsquo;s a tendency for us geeks to look at the internet as our playground, and forget about those who don&amp;rsquo;t work with computers for a living.</description>
    </item>
    
    <item>
      <title>Rewinding Animations</title>
      <link>https://pfandrade.me/blog/rewinding-animations/</link>
      <pubDate>Tue, 09 Oct 2018 12:38:43 +0100</pubDate>
      
      <guid>https://pfandrade.me/blog/rewinding-animations/</guid>
      <description>When Apple introduced iOS 7 and its flat design, it also changed the animations throughout the system to give UI elements a more natural feel when they move. They did this by changing the animation&amp;rsquo;s timing curve to a spring, instead of the usual ease-in or ease-out.
I&amp;rsquo;ve adopted the spring animations in some of Secrets&amp;rsquo;s UI elements, and a while back I wanted to run an animation in reverse, as if the user was undoing what had just happened.</description>
    </item>
    
    <item>
      <title>Apple Events and the State of macOS Automation</title>
      <link>https://pfandrade.me/blog/apple-events-and-the-state-of-macos-automation/</link>
      <pubDate>Mon, 03 Sep 2018 14:41:53 +0100</pubDate>
      
      <guid>https://pfandrade.me/blog/apple-events-and-the-state-of-macos-automation/</guid>
      <description>The Mac continues its path towards buttoning down the application sandbox on Mojave. High Sierra &amp;mdash; Mojave&amp;rsquo;s predecessor &amp;mdash; already presented user authorization prompts the first time an app accessed Contacts, Photos, Calendars, etc. Mojave builds upon that by adding other categories such as Camera and Mail, and making the prompt unavoidable even if going directly to the file system.
The goal is simple and noble: ensure the user has knowledge and control over which apps are accessing his data.</description>
    </item>
    
    <item>
      <title>Adopting Dark Mode and Older Macs</title>
      <link>https://pfandrade.me/blog/adopting-dark-mode-and-older-macs/</link>
      <pubDate>Wed, 13 Jun 2018 21:37:58 +0100</pubDate>
      
      <guid>https://pfandrade.me/blog/adopting-dark-mode-and-older-macs/</guid>
      <description>Update on 2019-08-06
Apple has added new API to NSColor on macOS Catalina (10.15) that provides the same functionality described on this post. If you&amp;rsquo;re able to, you should use that.
let color = NSColor(name: &amp;#34;myColor&amp;#34;) { appearance in switch appeareance.bestMatch(from: [.aqua, .darkAqua]) { case .darkAqua: return darkAquaColor case .aqua, default: return aquaColor } } Update on 2019-11-02
Matt Masciotte wrote a small framework implementing this idea.
 Mac OS Mojave was announced at this year&amp;rsquo;s WWDC, and with it Apple introduced Dark Mode &amp;mdash; a new look for Apple&amp;rsquo;s apps and all third party apps willing to adopt it.</description>
    </item>
    
    <item>
      <title>NSOperation KVO Pitfall</title>
      <link>https://pfandrade.me/blog/nsoperation-kvo-pitfall/</link>
      <pubDate>Fri, 01 Jun 2018 09:43:42 +0100</pubDate>
      
      <guid>https://pfandrade.me/blog/nsoperation-kvo-pitfall/</guid>
      <description>Recently, I encountered a bug while testing Secrets on one my older test devices running iOS 9. Apparently one of my NSOperation subclasses never finished on this device, and only on this device.
NSOperationQueue relies heavily on Key-Value Observing (KVO), it observes various keys of NSOperation to manage its lifecycle. Namely a queue will observe the values of isFinished, isExecuting, isCancelled and react accordingly.
In this case, the offending NSOperation subclass was asynchronous, so it was responsible for updating those properties and sending the necessary KVO notifications.</description>
    </item>
    
    <item>
      <title>The Developers Union</title>
      <link>https://pfandrade.me/blog/the-developers-union/</link>
      <pubDate>Tue, 22 May 2018 10:20:18 +0100</pubDate>
      
      <guid>https://pfandrade.me/blog/the-developers-union/</guid>
      <description>A few days ago The Developers Union launched its first campaign advocating for free trials on the App Store. I want to acknowledge the 4-person team behind it for taking the initiative.
If we, developers, want to do something about sustainability on the App Store1 I can&amp;rsquo;t think of a better way than to band together and ask Apple for changes in a single voice.
There are plenty of articles and papers suggesting that unions played an important role in reducing wage inequality in the past.</description>
    </item>
    
    <item>
      <title>Taming Build Variants With Xcode Configuration Files</title>
      <link>https://pfandrade.me/blog/taming-build-variants-with-xcode-configuration-files/</link>
      <pubDate>Tue, 10 Apr 2018 12:01:38 +0100</pubDate>
      
      <guid>https://pfandrade.me/blog/taming-build-variants-with-xcode-configuration-files/</guid>
      <description>Currently, Secrets has six different build configurations: Debug, Beta, Staging, Testing, App Store and Setapp1. All of these use a different set of parameters to customize the build. For example, whether or not In-App Purchases are included, what&amp;rsquo;s the API token to report crashes, should debug logging be enabled, what&amp;rsquo;s the bundle identifier, should the app check for updates, etc. For so many build configurations and parameters, sifting through the Xcode&amp;rsquo;s build settings view quickly becomes cumbersome.</description>
    </item>
    
    <item>
      <title>Rate Limiting Using a Token Bucket in Swift</title>
      <link>https://pfandrade.me/blog/rate-limiting-using-a-token-bucket-in-swift/</link>
      <pubDate>Fri, 16 Mar 2018 10:30:24 +0000</pubDate>
      
      <guid>https://pfandrade.me/blog/rate-limiting-using-a-token-bucket-in-swift/</guid>
      <description>This week I had to rate limit the calls I was making to a web service. In the past I&amp;rsquo;ve done this successfully with a Timer, but it&amp;rsquo;s still a bit cumbersome to schedule/unschedule the timer to keep it from ticking when I&amp;rsquo;m not making requests, and control everything from its callback. Also, these calls were being done on background threads and I did not want the dependency on the RunLoop.</description>
    </item>
    
    <item>
      <title>Managing iOS UI Testing Fixtures</title>
      <link>https://pfandrade.me/blog/managing-ios-ui-testing-fixtures/</link>
      <pubDate>Sun, 22 Oct 2017 17:31:37 +0000</pubDate>
      
      <guid>https://pfandrade.me/blog/managing-ios-ui-testing-fixtures/</guid>
      <description>A common problem when developing UI tests for iOS (and tests in general) is controlling the state before running each test. Having a well known and fixed environment to run tests is paramount.
If a test fails sporadically due to an external event such as side-effects from other tests or networking issues, you’ll not only lose trust on the outcome of that test but also waste your time investigating the failure.</description>
    </item>
    
  </channel>
</rss>
