How to create a QR code widget

Yes, the long-awaited widgets for iOS devices are finally here!

After the big announcement made at Worldwide Developers Conference in June 2020, Apple has released its biggest update regarding the iOS operating system in September 2020 – iOS 14, with the amazing feature that allows its users to create and add widgets to the home screen of their device.

Hoping that we are not joining the party too late, we decided to try it out ourselves and share our thoughts on the way. In this example, we’ll cover how to add a QR code to the widget that can, later on, be used to present any type of data, be it a link or a plain string message.

But wait. Before you sit down and start developing your widget, there are two requirements you need to know about.

  1. Your device or simulator has to run the iOS 14 operating system
  2. Your Xcode has to be updated to version 12.1

Also, note that we used a third-party library to generate the QR code.

Said that, let’s get started on the widget.


First things first, you will need to add a new target to the project, by clicking on File > New > Target and choose Widget Extension in the iOS tab, as done in the photo below.

After creating the new target it’s time to add the QR code library to the widget extension. I found that the best way to do that was to add the library using the Swift Package Manager. To do so, select your project in the project navigator and switch to the Swift Packages tab. By clicking the + button you will be asked to add the package repository URL (that can be found on the library’s GitHub in the installation section). The last step to incorporate the QR code library to the widget extension is to go to its target, click the + button in the Frameworks and Libraries section and choose it from the suggested list of libraries. 


Moving on, we’ll go to the Widget.swift file where we’ll implement the presentation of the QR code on the widget itself. The first thing you may notice about this class is that the code is written in SwiftUI. Keep in mind that even if you haven’t had a chance to cross paths with SwiftUI before, you won’t need to make big changes to the code.

At the top of the class import your QR code library. Find the WidgetEntryView struct and delete the entire code leaving only the entry property and body view. For this example, we used the EFQRCode library for QR code generation. The QR code library creates image of type cgImage, so we created an additional method that allows us to generate the QR code and parse it to the type of UIImage, making it easier to work with and therefore show on the widget.

The last, but not least step is to use the newly generated QR Code image in the body. The resulting code is shown below.


It’s time to see what we’ve done! 

Run your app on the simulator or device, and once it’s running, close it. Press and hold the screen until the apps on your home screen start to jiggle and the subtle + button appears in one of the top corners. Click on it and the new screen will be presented to you, holding all of the disposable widgets on the phone. Find the widget with the QR code, or in case it is not there find the name of your app, choose the size that fits your screen, and voilà! Your widget is done and ready to use.


Why we chose Texture to layout our UI elements

I remember the first time I heard about Texture. It was introduced to me at an early stage in my career as an iOS developer, and just at the moment when I finally got my head wrapped around the idea of how to work with UIKit and its storyboards. Was I excited to try out something new? Yes. Did I think I was ready for such a challenge at the moment? I don’t think I did. But was it worth it? It most definitely was!

Now, let me introduce you to the library we chose to incorporate into our layout routine.


Each method of building your UI has its advantages and disadvantages, and this one is no exception. One thing I can tell you straight away is that if you are looking for something that will fast forward the process of creating your app’s layout, or make your project smaller, this is not a solution for you. Anyways, you might get a little bit disappointed at first, but I promise you, it pays off later.

Texture requires you to build your layout just like you are building everything else when developing a mobile app – by writing code.  Yes, you read that right. So instead of dragging and dropping your components to the view, you will define them and arrange them in the class.

It is an iOS framework whose main purpose is to optimize your app by making user interfaces thread-safe. What this means is that you will be able to move all your views and view hierarchies on background threads, where you will prepare them before presenting them. This is the main reason why we love using it, as they make our apps faster, and leave the main thread available to focus on the execution of the app’s logic and data management, as well as to immediately respond to user interaction events.

However, Texture is not the only library that’s been developed to set up your layout programmatically. SnapKit is another example of such a library and the idea behind it was to simplify auto layout in iOS app development. Then why did we still chose Texture? Because, even though SnapKit is a library for itself, and it is not an integral part of Swift programing language, it still works with UIViews and uses UIKit to layout its components, thus throws off the app’s performance which is the exact thing we want to avoid.

Texture vs UIKit

Let’s start this comparison with the most obvious difference.

As you probably already know, storyboards let you build your layout by dragging the components onto the view itself, so the most noticeable difference between Texture and storyboards is that, when developing your app with Texture, there is no way to know how your layout will look until you run the app itself. At least at the beginning. 

However, when it comes to the components that Texture works with, there are a lot of similarities with the UIKit. Let me explain why.

Texture’s basic unit is node, from which all other nodes inherit. It represents an abstract over the UIView which is an abstract over the CALayer. Therefore if you know how to work with views, then you already know how to use nodes as well. Of course, in case you want to access node’s view or layer itself, you can do so by calling node.view or node.layer, since they are underlying views, just keep in mind that you have to perform those calls on the main thread.

Here are some examples of nodes and node containers and their equivalents in UIKit.

ASCellNodeUITableViewCell and UICollectionViewCell

Texture vs SwiftUI

SwiftUI is an innovative way to build the UI of your app that uses a flexible box layout system and allows you to see the changes you make instantly on the preview as you type, as well as to see the change you make to preview immediately in your code. Many of its parts directly build on top of the existing UIKit components, but many other parts don’t, as they are new controls rendered by SwiftUI.

When compared to Texture and UIKit, SwiftUI seems to offer the best of both worlds, since it combines the technique of writing your layout through the code and previewing the changes you made so you can keep track of your UI elements the whole time.

Still, the main question remains: Is the advantage of the preview that SwiftUI brings to the table worth sacrificing the overall performance of the app since it also builds and runs its UI on the main thread?

What does this difference mean to us?

Using Texture has allowed us to bring out the quality of the apps we offer, making them more responsive and faster. It has taught us how to think beyond the fact that we have to lay out a bunch of elements on the screen. Also, it made us visualize our work, and see the components before they are put onto the screen. In the end, it showed us how to become more precise and focused, especially when it comes to details we did not think mattered as much.

When it comes to user interaction, now we can make our apps run more smoothly and we have the tool to customize all sorts of things meeting our or client’s likings.


One of the main things I learned while using Texture is that patience and creativity are the keys to improving layout. In case you were asking yourself why these two of all things, it’s because Google doesn’t know everything. Sure, it will help you in 95% of the time, but those 5% will also occur. And when that moment comes, you’ll need to combine your knowledge and the creative side of your brain to come up with a unique solution for your problem. On your way to finding the solution the patience will join the game as you will need it throughout your journey. 

Of course, if you prefer, you can always add a third party library and solve the problem, but trust me, it will feel much better if you come up with the solution on your own. Considering how adding another library may slow the app down, the result will be more satisfying, especially for the client.

All in all, I hope you found this post interesting and that it taught you something new. I urge you to give it a shot. Try it out and see if it fits your style of app development. Even if you don’t end up liking it, you will for sure learn something new and acquire new experience.