Tag: programming

Using a Swift PropertyWrapper to ensure a closure is only called once

Learn: how to write a property wrapper that avoids boilerplate for your asynchronous callback code.

The Solution Code

Want to skip to the answer? Variables marked with this property wrapper will be destroyed after they are read once. Use with caution!

@propertyWrapper
struct ReadableOnce<T> {
    var wrappedValue: T? {
        mutating get {
            defer { self._value = nil }
            return self._value
        }
        set {
            self._value = newValue
        }
    }
    private var _value: T? = nil
}

Now lets see how we got here.


Avoiding multiple invocations of a completion block

Let’s say we have a class that does some work, and then invokes its completion block.

class NumberChecker {
    private var completion: ((Error?) -> Void)
    
    init(completion: @escaping ((Error?) -> Void)) {
        self.completion = completion
    }
    
    public func check() {
        if someCondition {
            handleFailure(NSError(domain: "MyDomain", code: 1))
        }
        handleSuccess()
    }
    
    private func handleSuccess() {
        self.completion(nil)
    }
    private func handleFailure(_ error: Error) {
        self.completion(error)
    }
}

This code has a secret bug in its check method. Did you notice it?

    public func check() {
        if someCondition {
            handleFailure(NSError(domain: "MyDomain", code: 1))
        }
        handleSuccess()
    }

If someCondition gets evaluated as false, the completion block will be invoked twice – once by handleFailure(), and again by handleSuccess(). This is a bug – the completion block should only get called once.

Now obviously in this trivial example you could fix this by just using an else statement. But in The Real World, your code may be much more complicated, and it may be harder to make the calls of the completion block mutually exclusive.

Perhaps your code is asynchronous, and completes when the first of two operations returns a result, for example.

I’m not judging how you have gotten yourself into this problem – just providing a neat solution.

How to solve this problem

Our approach here is going to be to ensure the completion block can only be called once by destroying it once it has been used. One perfectly reasonable approach to this solution is as follows:

class NumberChecker {
    // Make the completion closure optional
    private var completion: ((Error?) -> Void)?
    
    init(completion: @escaping ((Error?) -> Void)) {
        self.completion = completion
    }
    
    public func check() {
        if someCondition {
            handleFailure(NSError(domain: "MyDomain", code: 1))
        }
        handleSuccess()
    }
    
    private func handleSuccess() {
        self.completion?(nil)
        self.completion = nil
    }
    private func handleFailure(_ error: Error) {
        self.completion?(error)
        self.completion = nil
    }
}

Here we are simply setting the completion closure to nil after we use it. This is fine, but requires us to add extra boilerplate around each usage of the callback. It is also error-prone, since we could easily forget to include the self.completion = nil and end up with a partial solution.

So instead, lets create a property wrapper that changes the behaviour of the getter for that variable.

What is a property wrapper?

Property wrappers are structs that use Generics to define extra behaviour around the usage of some arbitrary property. They are defined separately from the property they act on, and can be re-used easily for different properties, even of different types.

NSHipster has a great write-up on the background and purpose of this Swift feature if you haven’t seen it before so I won’t go into more of those details here.

The ReadableOnce property wrapper:

I included this at the top, but lets look in more detail at our property wrapper:

@propertyWrapper
struct ReadableOnce<T> {
    var wrappedValue: T? {
        mutating get {
            // This defer is the magic. It lets us 
            // erase the value AFTER it is returned.
            defer { self._value = nil }
            return self._value
        }
        set {
            self._value = newValue
        }
    }
    // Use a private backing variable that we can modify here.
    private var _value: T? = nil
}

The property wrapper definition is just a struct marked with @propertyWrapper. It has a special var called wrappedValue, which is the place we have to implement whatever our custom logic is.

In our case, we want to put our magic into the get method of the value, so that the value is destroyed after being returned the first time. The set method should behave as normal, so we just add a private backing variable, here _value.

The defer keyword

Deferred closures are executed at the end of the scope they are declared in. In our case, the defer keyword allows us to execute our cleanup code after the return value is returned.

Using @ReadableOnce in the NumberChecker

Here’s what our NumberChecker looks like if we use our new property wrapper:

class NumberChecker {
    @ReadableOnce private var completion: ((Error?) -> Void)?
    
    init(completion: @escaping ((Error?) -> Void)) {
        self.completion = completion
    }
    
    public func check() {
        if someCondition {
            handleFailure(NSError(domain: "MyDomain", code: 1))
        }
        handleSuccess()
    }
    
    private func handleSuccess() {
        self.completion?(nil)
    }
    private func handleFailure(_ error: Error) {
        self.completion?(error)
    }
}

It would be a good idea to fix that secret bug, but even with it this code will now work as expected.

Downsides of this approach

The biggest concern with this is precisely the magic that makes it useful. It is unintuitive that you can only read once, and that reading could mutate the value.

The following code demonstrates the most likely pitfall:

private func handleSuccessPoorly() {
    if self.completion != nil {
        // The completion was just read (and set to nil).
        // So the next line will silently do nothing!
        self.completion?(nil)
    }
}

Overall, I think this property wrapper is very useful, as long as it is clear to the developer that it is being used.

So basically:

With great power comes great responsibility.

Uncle ben. yes. from spiderman.

Possible Improvements

There are a number of things you might continue to experiment with to improve this solution:

  • Use a different property wrapper to accomplish the same task
  • Implement something like a callThenDestroy() method on the type you want to store
  • Try @dynamicCallable (see this Hacking With Swift post for info)
  • Thread safety has not been considered in this implementation. It would be possible for two threads to both get access to the variable before either of them set it to nil.

This article is based on a code sample shared with me by Josh Caswell (https://github.com/woolsweater)


Have you tried any of the above? Do you have a better solution? Please leave a comment below!


If you liked this post you might also like my guide on how to do high-bar code review without being a jerk.

When is it *good* for your App to crash?

Most of the time, a crashing app is the very last thing you want. Obviously.

But sometimes you really do want your app to crash to enforce correct usage of your APIs.

What’s worse than a crash?

Crashes are obviously bad – it’s disruptive to your user, they might lose data or work in progress, it makes them feel frustrated and less likely to open your app again, and it just smells like bad quality.

But there’s something worse than a crash: undefined behaviour.

Our programs are carefully thought through, and crafted so that the right input data is manipulated, used for calculations, stored, outputted, and otherwise trusted. But this also makes them brittle. Whether you realize it or not, all of these complex behaviours only work when you constrain your code to be used with some predefined, known range of inputs.

When your code is given unexpected types of data, you can’t control what will happen – it’s outside of what you designed and tested for. You could end up accidentally corrupting user data, opening security holes, or (the most likely) providing inaccurate and confusing information to the user.

In some cases, these things are worse than crashing.

  • What if your banking app tells the user they have more money than they really have and then they suddenly can’t pay rent!
  • What if your app ends up in a state where none of the buttons do anything and you can’t navigate out of that screen?

There are of course others, but these user experiences might actually be *worse* than crashing. So crash! The user knows something went wrong, and needs to restart the app to fix it.

Crashing as a Development Tool

Crashing is also extremely useful in teaching developers how to use your APIs.

A (contrived) example

Lets say you’re writing the official calculator app for a university. It’s very important that it do math correctly, because all of this university’s students will be forced to use this app for all of their exams.

Ok so your inputs are numbers and operators.

Let’s imagine you had some calculator UI, with logic that looks something like this:

We could write a custom UITextField subclass that only supported numbers that could be converted into a float.

class CalculatorUI {
    @IBOutlet var input1: NumericTextField!
    @IBOutlet var input2: NumericTextField!
    @IBOutlet var result: NumericTextField!
    
    /// Takes the inputs, adds them, and updates the result TextField.
    @IBAction func didPressAddButton() {
        result.floatValue = input1.floatValue + input2.floatValue
    }
}

This super clean, simple class relies on pushing some of the complication into the NumericTextField:

// Basic Implementation
class NumericTextField: UITextField {

    var floatValue: Float {
        get {
            if let acceptableValue = self.text as? Float {
                return acceptableValue
            } else {
                // What do we return here?
                return 0
            }
        }
        set { self.text = "\(newValue)" }
    }
}

There are a couple problems with our basic implementation:

  1. We always return 0 if the text can’t be converted into a float. If a student somehow types non-float values like "two" and "two" as their inputs, they might not realize this isn’t supported, and actually believe that their answer is 0! This answer is not correct! AHH
  2. The NumericTextField class design encourages misuse! There is nothing preventing us from trying to access the .text property directly, but the whole point of this custom text field is to restrict the types to be floats.

Clearly, the real solution here is to show some error message that tells the user to only type numbers, or better yet to use a numeric keyboard style so enforce that they can’t enter alphabetical characters.

But we still want to improve this text field’s implementation.

Crashing is a hint to the developer!

The key thing here is that both of the problems described above are developer errors. They are misusing the API. We want to catch these mistakes as early into the development process as possible. And the best way to call attention to them is to crash.

Yep. We’re going to crash. On purpose.

Solution #1: Catch the invalid text field values

If the text field’s getter method is unable to convert the text to a Float, that is because the developer has allowed the user to input letters.

class NumericTextField: UITextField {

    var floatValue: Float {
        get {
            guard let acceptableValue = self.text as? Float else {
                fatalError("The NumericTextField assumes that is always has a text value that can be converted to a Float.")
            }
                
            return acceptableValue
        }
        set { self.text = "\(newValue)" }
    }
}

Using Swift’s fatalError lets us supply a crash message, which is much clearer than enforcing this behaviour via a force-unwrap:

class NumericTextField: UITextField {

    var floatValue: Float {
        get {
            // BAD!!  Don't use ! (force-unwrap)
            return self.text as! Float
        }
        set { self.text = "\(newValue)" }
    }
}

Solution #2: Prevent usage of the superclass’s API

The second thing we’ll prevent is usage of the UITextField.text property.

We can do this by overriding it and crashing.

class NumericTextField: UITextField {
    
    override var text: String? {
        set { fatalError("Use `floatValue` instead.") }
        get { fatalError("Use `floatValue` instead.") }
    }

    var floatValue: Float {
        get {
            guard let acceptableValue = super.text as? Float else {
                fatalError("Our error message...")
            }
                
            return acceptableValue
        }
        set { super.text = "\(newValue)" }
    }
}

Notice that we’ve also changed the floatValue getter and setter to use the .text property from the super class rather than self, since calling self.text will now crash.

We’ve now made it clear to the developer (or our future self) what the allowable usages of our class are.

Crashing in development is better than undefined behaviour in production.

With these two changes, we’ve made is easier for developers to use our API correctly.

This isn’t something you want to do on all of your APIs. You don’t want to allow anything external (such as user input or server responses) to be able to crash your app.

But the case above shows how you can use crashing as a tool to make sure that your code is using your other code correctly.

11 Habits of an Effective Developer

Being a developer is hard – and being an effective developer demands that you juggle many responsibilities at the same time – from writing and reviewing code to mentoring others and communicating with stakeholders.

How are you supposed to be good at all of these things? Each one is hard even just on its own!

The answer – build good habits.

Then you don’t have to actually remember to do the things, you just stick with your habits.

So here are some habits that I believe can make you a more effective developer. Practice these, and you will be the most valuable member of your team.

1. Read

Reading makes you smarter. There’s just something about it. Obviously you learn information from the content you are reading, but its also exercise for your brain.

I’ve been back in the habit of reading for the past year or so, and I feel it making my mind a little fresher – a little sharper.

Set yourself a reading goal to hold yourself accountable – this year my reading goal is to read 15 books – 7 books for fun, 5 books for personal development, and 3 books for work (books about software).

2. Log Your Daily Standup

You’re probably already doing regular standup meetings at work. These are ubiquitous in the software industry now.

But I also find it beneficial to write down my plan for the day every day. This has at least three benefits.

First, I can keep that in front of me all day to help stay focused and on-task.

Second, I can refer to it the next morning while I struggle to remember what I did the day before 😂.

Third, I can refer to it at the end of the year when I’m asked to reflect on my work for an annual review (or to help brainstorm for the day you eventually need to update your resumĂ©.

3. Keep the main thing the main thing

This is a great quote:

To succeed, always remember that the main thing is to keep the main thing the main thing.

Brendon Burchard, High performance Habits

And its true.

It is too easy to get lost in the weeds as a developer – you can spend a huge amount of time on something that is in some ways productive and helpful, but might not be actually delivering value to your employer, or related to the high priority task you need to get done before some deadline.

Writing unit tests is a great goal; but writing unit tests for a component that’s not used probably isn’t the main thing you’re supposed to be working on. You just found yourself in that code and noticed it needed cleaning up.

Keep the main thing the main thing. Stay focused.

4. Use your daily commute time for something productive

This is as important as your commute is long. In my case my commute to work is about 2 hours.

Yep, 2 hours. Each way.

Luckily I’m not driving, but it is all too easy to spend 4 hours a day playing Angry Birds, or scrolling through Instagram. And that would be a colossal waste of time.

I spend one of those trips doing something for myself, like reading (see #1), or writing (see #11). And I spend the other trip doing work for my employer, who allows me to end my work day on the commute to avoid getting home suuuuper late.

But it’s a game changer.

Suddenly you have time – already carved into your schedule – to tackle that thing you’ve been meaning to do. Do it on your commute!

5. Attend tech talks or meetups regularly

If you’re not constantly learning in this industry you’re falling behind. It is one of the greatest things about working as a developer that you get to keep learning throughout your career, but it is hard to know where you should be focusing your learning.

Public tech talks and meetups expose you to industry trends and technologies you haven’t seen before. They also are great opportunities to slowly and casually build a network of likeminded (and potentially useful) connections with others in your industry.

You can also accomplish some of this by joining public Slack groups – but there’s still no substitute for chatting face-to-face – IRL.

6. Document your accomplishments, and make quantitative measurements

I learned this from the Manager Tools/Career Tools podcasts. In an episode where they are discussing building a resumĂ©, they recommend keeping a career file – a document where you keep extensive detailed notes on accomplishments you’ve had at your job.

The career file can include a wide variety of things, but they should be quantitative, and should demonstrate the skills you have. Imagine if you could show your usage of these skills, instead of just listing them on your resumĂ© – it’s much more compelling.

Did you increase the performance of a critical component of code? By what percentage? And in how many days/weeks? Was it ahead of schedule? Did this cut costs for the business? Did customer complaints reduce as a result of your work? Did it enable sales to land a big deal?

These are all quantifiable evidence of how great you are for the company you work for – and an effective developer knows why they are valuable.

7. Keep your computer organized

This is as simple as it sounds.

Your job is complex enough – don’t add another layer of complexity by making your computer hard to use. Know where things are – have a system for naming files or organizing directories.

8. Review your own pull requests

Whenever you submit a pull request and ask your peers for review, you are asking for a bit of their time to double-check your work. You should be confident that it is as good as you could make it.

Don’t be that developer that submits a half-done pull request (unless you’re just asking for early feedback and in that case state that intent explicitly).

I like the interface of a pull request to look over my work, so sometimes I’ll create the pull request but not add any reviewers until I’ve reviewed it myself. I can even make comments to myself there, or go through file by file to make sure I’m not leaving little debug messages for myself in my final commits.

9. Commit early and often

Git will save your life some day. Well ok, maybe not literally. But it will be your safety net and allow you to quickly revert back to a working version, or refer to that intermediate step you made while working through a problem.

But only if you committed your work while you went.

There is no reason not to commit often – even if you want to avoid cluttering up git history you can squash commits together at the end.

At a minimum you need to commit your work at the end of every day before you go home, and push to the remote. If your computer implodes, or gets eaten by a lion, your work will be safe, and you won’t have to scramble to remember exactly how you solved that difficult problem so elegantly last week.

10. Schedule exercise into your daily routine

Our job is very sedentary. This is terrible for your health over the long term, and makes you feel sluggish and depressed in the short term.

This is a simple life hack. When you get exercise you have more energy. Fact.

So ensure you have exercise in your routine. At least half an hour. Every. Single. Day.

Personally, I choose to use a rental bicycle for the last leg of my commute instead of taking the bus. It is often actually faster than transit, plus I feel awake and fresh when I arrive at the office.

You can also find yoga videos on YouTube in the morning/evening, or even just go for a walk at lunch every day.

There’s no excuse, and you’ll feel SO much more powered up to accomplish all the things in your busy life.

11. Write when you learn a new thing

Remember how when you were in school and your teacher taught a lesson, you had to write down what you learned and submit assignments demonstrating your new knowledge?

That’s not just so the teacher can mark you.

More importantly, it helps you internalize that learning, and commit it to long term memory.

Maybe you can start a blog, or maybe you just keep a journal or some notes. But writing (either by hand, or on the computer) can help take your learning to the next level.

So Many Habits!

You can’t take all of these on at once – overreaching on too many things at once is a recipe for failure. But start with one of these behaviours, and do it every day. Then after a month, once that behaviour has ingrained itself into you as a habit, start the next one.

After a year, you’ll have all of these working for you, powering you to be a more effective developer version of yourself!

Go get it!

Font Awesome Doesn’t Work with Firefox – SOLVED

Font Awesome is awesome, except that it doesn’t work with Mozilla Firefox or Google Chrome out of the box (see what I did there?). So if you’re seeing little squares instead of the icons you’re expecting, here’s the solution.

Open the .htaccess file for your site and add the following code:

<FilesMatch ".(ttf|otf|eot|woff)$">
  <IfModule mod_headers.c>
    Header set Access-Control-Allow-Origin "*"
  </IfModule>
</FilesMatch>

This is a great snippet that I found here.

If you don’t already have an .htaccess file, create one in the root directory of your site. It is a plain text file and must be called exactly “.htaccess” (no that’s not just the file extension). I’m using WordPress so this is what my .htaccess file looks like now:

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

<FilesMatch ".(ttf|otf|eot|woff)$">
 <IfModule mod_headers.c>
 Header set Access-Control-Allow-Origin "*"
 </IfModule>
</FilesMatch>
# END WordPress

Refresh your browser and your icons should now appear.

If this doesn’t work, make sure you don’t have another copy of font awesome installed. This could happen, for example, if you are using WordPress and you installed a fontawesome plugin, or if you tried uploading a newer version in some previous frustrated attempt to fix this.

Powered by WordPress & Theme by Anders Norén