How can I debounce a method call in Swift 4?

Debouncing calls is great for situations where a repeating user action can cause network requests to happen. The problem is that the user’s actions can generate many requests in a short period of time, which can be slow to respond on a cellular network.

This also applies to other types of wireless communication, such as BLE.

Here is an implementation of a Debouncer class in Swift 4. Github Gist link

import Foundation

class Debouncer {

    /**
     Create a new Debouncer instance with the provided time interval.

     - parameter timeInterval: The time interval of the debounce window.
    */
    init(timeInterval: TimeInterval) {
        self.timeInterval = timeInterval
    }

    typealias Handler = () -> Void

    /// Closure to be debounced.
    /// Perform the work you would like to be debounced in this handler.
    var handler: Handler?

    /// Time interval of the debounce window.
    private let timeInterval: TimeInterval

    private var timer: Timer?

    /// Indicate that the handler should be invoked.
    /// Begins the debounce window with the duration of the time interval parameter.
    func renewInterval() {
        // Invalidate existing timer if there is one
        timer?.invalidate()
        // Begin a new timer from now
        timer = Timer.scheduledTimer(withTimeInterval: timeInterval, repeats: false, block: { [weak self] timer in
            self?.handleTimer(timer)
        })
    }

    private func handleTimer(_ timer: Timer) {
        guard timer.isValid else {
            return
        }
        handler?()
        handler = nil
    }

}

The Debounce class is straight forward to use:

// Create a Debouncer with a half-second time interval
let debouncer = Debouncer(timeInterval: 0.5)

debouncer.handler = {
    // Send the debounced network request here
    print("Send network request")
}

func textDidChangeDelegateMethod() {
    // When the user performs a repeating action, such as entering text, invoke the `renewInterval` method
    debouncer.renewInterval()
}

PS: Interestingly, the term debounce comes from electrical engineering. “Bouncing is the tendency of any two metal contacts in an electronic device to generate multiple signals as the contacts close or open.” (http://whatis.techtarget.com/definition/debouncing) So a de-bouncing circuit cleans up this bouncing between the signals, by providing a single signal.


Subscribe to the newsletter to stay up to date with new articles.


Should I be worried about accidentally invalidating all my provisioning profiles?

“I’m trying to add Push Notifications to an App ID and someone higher up is telling me that in the past, flipping a switch in an App ID, like Push Notifications, will invalidate it’s provisioning profile.”

Especially if you come from a web background, things like “revoked certificates” and “invalid profiles” sound scary. However in the context of iOS development, these are common and necessary management tasks in the app creation workflow. So there is no need to be worried. In this article I will explain what is actually happening when you see the “invalid” marker on your provisioning profile, and run through a common scenario where this would occur.

Just to reassure you a bit up front: it might feel less scary if you think of the profiles as “outdated” instead of “invalid.” And “outdated” is also an accurate description. This is because the old profile has not expired or been revoked. But it no longer has the most up-to-date and correct settings.

Why is a provisioning profile marked “invalid” at all?

When any of the attributes of a provisioning profile change, the profile is marked “invalid” with the yellow yield icon. What it is actually informing you is that the attributes of the profile are now out of date. It is crucial that the all the attributes in the provisioning profile match the attributes of the app.

When your app is launched in iOS, the system checks all the attributes of the provisioning profile included with your app. One of the pieces of information it gets from that provisioning profile is which capabilities the system should enable for your app. Therefore if you want the Push Notifications feature of your app to work properly, it is a requirement that the provisioning profile bundled with the app include the Push Notification entitlement.

In this way iOS checks the provisioning profile bundled into your app file to determine what capabilities the system should grant to your app. Invalid provisioning profiles represent the situations where the attributes of that profile no longer match the latest settings.

A Common Scenario

For example, say you are adding Push Notifications to your app as a new feature. You quickly discover that one of the first steps is to modify the App ID for your app by adding the Push Notifications entitlement. Once you perform that step, you then might be concerned to discover that all the provisioning profiles related to that App ID have been marked invalid. But this is actually completely necessary and expected.

When you enable the Push Notifications capability on your App ID using the developer site, this will modify the App ID. Because the App ID is one of the attributes of a provisioning profile, it means the existing profile you have downloaded on your computer is out of date or “invalid.”

The Apple Developer site is actually providing you with a helpful indication: “Hey, you just changed the capabilities on your App ID. That means all the existing profiles that rely on that App ID should not be used anymore. If you try to use the existing ones, your app will not work as expected.” (That’s one way to get the dreaded “mismatched entitlements” error, btw.)

If you were to try running the app build to test your Push Notification feature with that existing profile, the push notifications will not work. iOS will look at the app’s provisioning profile, check that the Push Notification entitlement is not there, and therefore disallow Push Notifications capabilities for your app.

Hopefully this (very common) example gives you a bit of insight about how the invalid markers are actually helpful indicators, saving you from the time it takes to guess and check which provisioning profiles need to be re-generated.

Solution

The solution is to generate a new (replacement) provisioning profile. The new profile will include the modified App ID information, including that new Push Notifications entitlement. Once that new profile has been downloaded to your computer, and Xcode includes it in the next build of your app, then the app will have the provisioning needed for iOS to allow Push Notifications for that app.

In this way it is actually a requirement that the existing provisioning profiles become invalidated when adding the Push Notifications entitlement to your app. The same can be said for any of the attributes of a provisioning profile. If you need to make a change, the existing profile will be marked “invalid” to let you know that a new one should be generated that has all the updated attributes.

Attributes of a Provisioning Profile

If you’ve made it this far, you understand what happened in the Push Notification example. Now you might be wondering: What exactly are the attributes of a provisioning profile anyway?

The attributes that make up a provisioning profile are:

  • App ID
    • Entitlements and Services (e.g. Push Notifications, CloudKit, Apple Pay, etc.)
    • The app identifier’s suffix string (whether explicit or wildcard)
  • Signing certificate
    • iOS uses this certificate to check the code signing on the app’s compiled code.
  • List of Devices
    • A list of devices onto which the app can be installed. If the device is not in the list, it will not run.
    • Note that the Device List is for Development and Ad Hoc provisioning profiles, but not App Store Distribution profiles.

If any of the above change, the existing profile is now out of date and will be marked as “invalid.” Generate a new one that includes the updated attributes. The old one has not expired, but it is no longer useful to you because it contains outdated attributes.

Summary

The invalid marker on provisioning profiles is actually a very useful and helpful tool. It informs you at a glance that the attributes of your provisioning profile have changed without the need to manually inspect all the components yourself. No need to be worried next time you see that invalid marker.


Subscribe to the newsletter to stay up to date with new articles.


Why am I getting errors when trying to test a release build with Xcode 8 Automatic Signing?

Xcode 8 introduces a new default way to manage provisioning profiles and signing certificates called Automatic Signing. Automatic Signing can make managing provisioning profiles much easier, but for some developers it can be a frustrating experience at first.

“I suppose I could try and go back to the manual signing, but I thought the whole point of this Automatic signing would be that it would make my life easier.”

Especially for developers who have been using Xcode before automatic signing, it can be confusing to get the Xcode project configured correctly, and to understand what Xcode is now doing at each step in the new workflow.

The most fundamental change that happened alongside Automatic Signing is that archived builds should now be code signed with the Development Signing Identity, instead of the Distribution Signing Identity. So to take advantage of Automatic Signing, you must use your Developer signing identity for both Debug and Release configurations. (This is where some developers get confused, because previously this was not the case. In the past the Debug configuration would be code signed with the Developer Identity, but the Release configuration would be the Distribution Identity. Now both Debug and Release should use the Developer Identity for code signing.)

If the release build configuration incorrectly specifies a Distribution Signing Identity, Automatic Signing will no longer be able to operate, and Xcode will produce a build error informing you to fix the configuration. Just update the top-level “Code Signing Identity” to “iOS Developer” to correctly configure the project.

When archiving the app, it will be signed with the Developer Identity. The Xcode Organizer now has the ability to re-sign the archive with the Distribution Identity when needed. For example, when you use the Xcode Organizer to upload an archive to iTunes Connect, Xcode will include the Production provisioning profile and re-sign the build with the Distribution Identity. In this way, iTunes Connect will receive your app build with the correct provisioning profile and code signing.

However, this new workflow presents a problem for certain testing scenarios. Specifically, if you need to test a feature such as Push Notifications in the fully production environment, the build you test must be provisioned for distribution, unlike what happens during a normal “build-and-run” development cycle.

“I sometimes would switch to the Release config in the ‘run’ part of the scheme to test parts of the app that needed to be signed with a Distribution profile (in our case, testing push notifications or IAP). But having trouble with Xcode 8.”

This is still possible with Automatic Signing, but there is a new workflow for testing release builds. Use the export archive feature of the Xcode Organizer window to create an app that can be tested on device. Here’s the new workflow to test a production build while using Xcode 8’s Automatic Signing:

  1. First create the archive. Xcode will create a release version of the build and code sign it with the Development Signing Identity. The archive will appear in the Xcode Organizer window.
  2. Click the “Export…” button to allow this archived release version of the app to be deployed on different devices for testing.
  3. Choose the Ad Hoc option. Xcode will re-sign the build with an Ad Hoc Distribution Provisioning Profile and Production Signing Identity.

Once the Ad Hoc export has been tested, you can then use the exact same archive to upload to iTunes Connect. This workflow has the benefit of ensuring that you are testing the same compiled code as what is submitted to iTunes Connect. That means the archived code is the same between testing and what is delivered to the App Store. Likewise, if you need to test a build that has previously been sold on the App Store, you can use the archive for that build to generate an app file you can install on your test device.


Subscribe to the newsletter to stay up to date with new articles.


The Most Important Things to Understand About Certificates & Provisioning Profiles

“Finally, the provisioning profile is for testing only, right? The distribution cert is what allows me to get the app released?”

Certificates and Provisioning Profiles have been a perennial source of developer confusion and frustration. A lack of easy-to-understand documentation from Apple on this topic adds to the problem. But it is still very important to learn about these topics as an iOS developer.

“I know this is a lot of questions but I feel overwhelmed and don’t know where to start, I’m currently trying to read through the documentation but there’s so much I don’t understand. Any help would be greatly appreciated.”

All developers will eventually run into needing to use and understand these, it is a requirement. You will save yourself a lot of frustration and make sure you don’t delay submitting your app by understanding the purposes for certificates and provisioning profiles.

“This is frustrating as it is holding my app’s launch back”

One of the worst things about these issues is that if they appear, it is almost guaranteed to happen at a stressful time: submitting your app to the store, trying to meet that important launch deadline, or delivering a crucial bug fix to your customers. This is the time when issues with your certificates or provisioning profiles might appear.

So save your future self from all that stress and worry by getting an understanding of these now, and you can thank yourself later 😇

Notes: This article will focus on regular Apple Developer Program accounts. The Enterprise Program is a different story. The focus will also be on apps for iOS (and therefore watchOS). Apps for tvOS are very similar. Apps for macOS have some important distinctions, but much of the understanding still applies.

Certificates

Certificates provide many assurances for the app builds you create. There are two that are important to point out here:

  1. Certificates assure that your app was built by you or a team member. It is therefore important to protect the Signing Identity (private key) for your Certificates.
  2. Certificates are used to guard against the code of your app being changed after you build it. This is known as code signing. If the executable code of your app is modified after code signing, the signature will no longer be valid, and iOS devices will know not to run the code.

iOS App Development Certificate

Also known as the “Developer” or “Development” certificate.

This certificate is used to sign code in order to run it on the testing device connected directly to your Mac. Each developer on a team will get their own certificate. If that developer has multiple Macs you can share the same Developer certificate between those computers.

Because you will use this daily in your testing, it will immediately be brought to your attention if anything is wrong. Developer certificates expire one year after creation. When it expires, it doesn’t have any impact on your apps in the store or your ability to submit apps to iTunes Connect. You will need to create a new one to continue testing on your development devices, but it is fairly straightforward to do so. Xcode now even includes a one-click button to do it for you you.

App Store and Ad Hoc Production Certificate

Most commonly known as the “Distribution” certificate.

This certificate is used in a couple situations: for testing your app builds in an Ad Hoc manner; and for submitting builds to iTunes Connect for both testing on TestFlight and submitting for review to be approved for sale on the App Store. (More info on both Ad Hoc and submitting to iTunes Connect below.) Just like a Developer Certificate, a Distribution Certificate will expire one year after it is created. It is a good idea to stay on top of your Distribution Certificate before it expires. You will get a scary-sounding email from Apple 30 days before that happens, but don’t worry. More information on that here: http://bradfol.com/ios-distribution-certificate-is-expiring-what-do-i-do/

Distribution Certificates are shared by the entire team. Most of the time you will have a single Distribution Certificate that is used for all apps and all developers that have permission to submit builds to iTunes Connect.

Provisioning Profiles

Provisioning profiles store a configuration of settings that allow your app to launch in certain circumstances. Depending on which stage of app creation you are in, different provisioning profiles will be needed.

In most cases Xcode now has the ability to create or update provisioning profiles for you. It is still important to understand what is happening. When Xcode does perform an action on your profiles, I would recommend that you log into the Certificates, IDs, & Profiles tool in the Developer Account website and take a look at the result. That tool will allow you to see and inspect all profiles created by Xcode (in addition to the ones created manually).

iOS App Development Provisioning Profile

This essential provisioning profile is used for the day-to-day development process of build and running your app on a device connected to your Mac.

Use this provisioning profile to specify which development devices you will be using to sign and run development builds of your app. This is used when you are running a development build while connected directly to your Mac. Xcode will maintain a debug connection to the app, proving live logs and further inspection tools of your running app.

The provisioning profile must match three things to be correct: the Developer Certificate that matches what is on your Mac, the App ID for the app you are trying to build, and the devices you want to run that app on. Note that for two of those requirements (certificates and devices), this type of Provisioning Profile allows for multiple selections. For example, you could have a single Development provisioning profile that specifies the Development Certificate for two developers, as well as all the iOS testing devices that the team uses. If any of those three areas of requirement change, a new provisioning profile will need to be generated. The most common example is wanting to test the app on a new development iOS device. If you get a new device you want to test, you will need to edit the provisioning profile and include that new device. The newly generated profile effectively replaces the previous one. In many cases, Xcode can automatically manage the process of generating new profiles for you. It is performing these same steps for you, and the same requirements apply.

App Store Distribution Provisioning Profile

This is a very important Provisioning Profile. It is used each time you upload a build to iTunes Connect. That includes uploading for both the purposes of testing using TestFlight, and submitting to App Store review.

There are two requirements that go into this provisioning profile: the App ID, and the Distribution Certificate. When Xcode uploads your app build to iTunes Connect, it includes a copy of this provisioning profile. The iTunes Connect system then checks that the App ID and code signing of your app build match what is specified in this provisioning profile. Additionally, that certificate must be a Production (a.k.a. “Distribution”) certificate, not a Development Certificate, and match what is specified in the provisioning profile.

Ad Hoc Distribution Provisioning Profile

The purpose of this Provision Profile was to allow developers to send their app out to a group of testers to receive feedback on the app before it is made available publicly on the App Store. However, this method of testing pre-release app builds has seen reduced importance over the last few years, due to the integration of TestFlight into iTunes Connect. TestFlight meets these testing needs for most developers, and takes much less time to manage than Ad Hoc Distribution.

As the name might suggest, “Ad Hoc Distribution” allows your app to be distributed in an ad hoc manner. To be more specific, the app build can be distributed to only the list of devices included in this Provisioning Profile, and only for the App ID specified in the profile. The build must be code signed using your Distribution certificate, also matched to this provisioning profile. Anyone with experience doing this type of app testing knows how much headache and difficulty it caused. Again, for most developers, it is now a better idea to use TestFlight. But this option still exists if you need it.


Subscribe to the newsletter to stay up to date with new articles.


I just received an email that my iOS Distribution Certificate is expiring. What do I do?

First of all, don’t panic. If your app is already for sale on the App Store, this email has no impact on that. Your app will remain up for sale even if your Distribution Certificate expires. It’s going to be OK.

It’s a scary email, but it won’t cause anything to break with your existing apps on the App Store.

What is the iOS Distribution Certificate for?

The purpose of the iOS Distribution Certificate is actually pretty narrow, it is just used for submitting a build of your app to Apple’s iTunes Connect system so that it can be reviewed and processed for sale on the App Store. The time it is needed is just for the submission and review of an app build by Apple. Once Apple approves the app, and it is made available for sale on the App Store, it doesn’t matter if your iOS Distribution Certificate has expired.

What do I need to do?

So while the email sounds extremely urgent, it only really impacts your ability to submit new builds of your app. Obviously this is important, but it does not change what is already on the App Store.

What needs to be done is to create a new iOS Distribution Certificate on the computer that you use to submit app builds. There are two options to create it: using Xcode, or using the Member Center web tool.

Xcode now has an automated way to do this that handles all the details for you.

  1. Open Xcode preferences, select the Accounts tab.
  2. In the left column, choose the Apple ID for the account that you would like to create an iOS Distribution certificate.
  3. In the right column, select the team for the account. (If your legal entity is a company instead of an individual, there might be more than one option. Choose the one with the “Agent” role.)
  4. Click the “View Details…” button.
  5. Under Signing Identities, there will be list of certificates you can create for that account and role.
  6. Click the “Create” button next to “iOS Distribution”.

If the Create button is grayed out, go back to steps 2 and 3 to make sure you have selected the appropriate account and role for the expired certificate.

If you prefer to do it manually, use the Member Center and follow the steps to create a Production App Store and Ad Hoc certificate.

  1. Go to the Apple Developer certificate management site: https://developer.apple.com/account/ios/certificate/ (You can also use this site to view and manage existing certificates.)
  2. Click the plus button on the top left.
  3. Under the Production section, choose “App Store and Ad Hoc”.
  4. Follow the instructions to use the Keychain Access app on your Mac to create a Certificate Signing Request and upload it to the site.

Subscribe to the newsletter to stay up to date with new articles.


How can I debounce a method call in Swift 3?

NOTE: There is an updated version of this article for Swift 4.

Debouncing calls is great for situations where a repeating user action can cause network requests to happen. The problem is that the user’s actions can generate many requests in a short period of time, which can be slow to respond on a cellular network.

This also applies to other types of wireless communication, such as BLE.

Here is an implementation of a Debouncer class in Swift 3. Github Gist link

import Foundation

class Debouncer {

    // Callback to be debounced
    // Perform the work you would like to be debounced in this callback.
    var callback: (() -> Void)?

    private let interval: TimeInterval // Time interval of the debounce window

    init(interval: TimeInterval) {
        self.interval = interval
    }

    private var timer: Timer?

    // Indicate that the callback should be called. Begins the debounce window.
    func call() {
        // Invalidate existing timer if there is one
        timer?.invalidate()
        // Begin a new timer from now
        timer = Timer.scheduledTimer(timeInterval: interval, target: self, selector: #selector(handleTimer), userInfo: nil, repeats: false)
    }

    @objc private func handleTimer(_ timer: Timer) {
        if callback == nil {
            NSLog("Debouncer timer fired, but callback was nil")
        } else {
            NSLog("Debouncer timer fired")
        }
        callback?()
        callback = nil
    }

}

The Debounce class is straight forward to use:

// Create a Debouncer with a half-second time interval
let debouncer = Debouncer(interval: 0.5)

debouncer.callback = {
    // Send the debounced network request here
    print("Send network request")
}

func textDidChangeDelegateMethod() {
    // When the user performs a repeating action, such as entering text, invoke the `call` method
    debouncer.call()
}

PS: Interestingly, the term debounce comes from electrical engineering. “Bouncing is the tendency of any two metal contacts in an electronic device to generate multiple signals as the contacts close or open.” (http://whatis.techtarget.com/definition/debouncing) So a de-bouncing circuit cleans up this bouncing between the signals, by providing a single signal.


Subscribe to the newsletter to stay up to date with new articles.


How to calculate tax in Swift

When performing any type of financial calculation, it is best not to use floating point numbers. Performing arithmetic in base 10 will allow you to avoid unexpected errors in how floats represent some decimals. Fortunately, Apple provides the NSDecimalNumber class to handle calculations using base 10 arithmetic.

Tax calculation example:

let price: Int = 15 // $15
let priceDecimalNumber = NSDecimalNumber(integer: price)

let taxPercentage = NSDecimalNumber(string: "0.09") // 9%

let tax = priceDecimalNumber.decimalNumberByMultiplyingBy(taxPercentage)
let taxDouble = tax.doubleValue // Retrieve the double value

More information about floating point arithmetic:
http://floating-point-gui.de/basic/


Subscribe to the newsletter to stay up to date with new articles.