Newsletter of AppForce1 - Issue #33
You might need to click through to the Substack version of this message due to the sheer number of links.
Finally, I got some time for my newsletter again. The last time I sent a message was right before Do iOS, back in November 2022. Since then, a lot has happened, and it’s been busy.
I had a 2-week vacation, we went to Paris.
It was great.
Next to that, it was the holidays, so no work for me.
Counting what I did since Do iOS is wild.
7 Podcast episodes
With 26 article links!
10 blog posts
Again many thanks to my sponsor, Runway. They have been an amazing support in 2022.
Something new I am working on is some subscriber content for my podcast. I plan to do a full read of my book and release that to subscribers only.
I also have a few things in the works that will be pretty amazing. Hopefully, I can share more on that soon. One of them is a fun exploration of API integrations using Tuist.io.
Since there is already so much for you to explore in this delayed newsletter edition, I will keep my intro short.
My recommendation, this edition is packed to limit with amazing content from the iOS developer community. And I hope you will have a look at all of the links I shared with you today.
It’s been too long since my previous newsletter. I just had to step away for a while after Do iOS.
All the best,
Jeroen
Sponsored by Runway
Introducing Rollouts by Runway
Runway's Rollouts allows your team to easily keep tabs on release health in just one place instead of many, alerts you whenever configured metrics become unhealthy, and safeguards release health by automatically halting rollouts based on thresholds you define.
Rollouts by Runway: a single source of truth for release health, instantly understandable – and actionable
Released Content
Podcast episodes:
Episode 96: Recovering after a conference
Interview: Pol Piella Abadia, Senior software engineer at the BBC
Interview: Marin Todorov on 2022 and "dataTile"
Episode 97: New year, new microphone
Episode 98: Fake hardware, Makefiles, protocols and churn... Lots of iOS and Swift content too
Blog posts on AppForce1:
Blog posts on Stream
I did mention I have been busy. 😂
News Episode Links of episodes 96, 97 and 98 😅
(I would totally understand if you skim the remainder of this newsletter. On the other hand, all these links are amazing.)
Utilizing Makefiles for Swift projects
Make is a build automation software that you can use to automatically run various commands. If you want to run something, you have to specify your commands (more precisely: build targets) through Makefiles.
I love the Unix philosophy of building things using small simple tools. Make isn't a simple tool, but it is super powerful. You can do great things with it and it is a tool that fully reflects the Unix philosophy.
Tibor explains how he uses Makefiles for his Vapor coding. Just remember, iOS developers can also take a lot of advantage of Makefiles.
And if you are looking for a practical way a project could adopt a Makefile, look at the Swift Package Index sourcecode.
Shift in the protocol paradigm
From the origins of Swift, protocol (as a language feature) was always in between two completely different worlds: compile-time constraints and runtime flexibility.
From Objective-C protocols inherited their dynamic essence. In this meaning “protocol” is what called “interface” in most of other languages. It’s a capability to define some contract (variables, functions) which then will be implemented by specific data types. So the compiler doesn’t know about a specific type, and exact implementation of the contract is being “attached” only in runtime using dynamic method dispatch. It’s more flexible, but less specific and impossible to optimise by the compiler.
At the same time in Swift world protocol always played a big role in generics. Generics is a system that allows us to specify a set of requirements/constraints that can be later translated by a compiler into specific types. As the types are clear in compile time, the implementations are “connected” to the calls at that stage as well, so static method dispatch is being used. Hence the compiler can help you a lot here during development as well as optimising the code while compiling it.
This may not sound like an important thing, but there was a lot of confusion and frustration among the developers regarding the dualism of protocols
More in his article. Dmitri does not draw any conclusions. But I found it interesting to catch a glimpse at what goes into designing a programming language like Swift. It is a bit of an abstract write-up Dmitri created, but if programming language design is your thing, you will love his article.
Time to dive into a much more practical topic now. Thibault Wittemberg writes about
Debouncing with Swift concurrency
When dealing with things like user input combined with network access, you do not want to send a request every time the user types a character into for example a search field. It could potentially overwhelm your backend if all your end users are searching at the same time in your app. The search result would probably not even be read by the end user because they are still typing.
Such is a typical usecase for a debouncer.
The Debounce operator delays the emission of elements from a sequence of events until a certain amount of time has passed without the sequence producing another event. For example, if a search field is debounced for 2 seconds, a request will only be sent to the server if the user has not entered any additional input for at least 2 seconds. This helps to prevent intermediate events from triggering unnecessary requests.
In his article, Thibault explains the concepts you need to know in this area with clear pictures and code. Go read it if you have never heard of debouncing before. And read it anyways if you already know about debouncing because Thibault's article is a clear example of how a good picture or two can really help communicate a concept well.
Next I needed to pick one article from Leonardo's blog. He writes so much great stuff nowadays.
5 Techniques to Effortlessly Send Data from UIKit to SwiftUI
In this article, Leo will check five ways to transfer data from UIKit to SwiftUI. In four of them, the data can update itself and you don’t need to recreate the view, only one that is not possible and you will have to recreate the view yourself.
The five ways to pass data to SwiftUI from UIKit that I will show today are:
View Initializer
Observable Objects
User Defaults
Environment Object
Notification Center
Now go read it yourself, bookmark it for later reference, send me a thank you when you need it. And don't forget about Leonardo's blog too.
Using JavaScript in a Swift app
If you’re writing an iOS app using Swift and trying to solve a problem you’re sure has been solved before, you may look for existing code that solves that problem. It’s likely you’ll first think of looking for open source code written in Swift that you can integrate into your project using Swift Package Manager. For example, by searching the the Swift Package Index. However, we don’t need to limit ourselves to Swift.
In an iOS app, it’s technically fairly easy to also use code written in C, C++, Objective-C, Objective-C++ or JavaScript. In this article, we’ll look at how to call JavaScript code from Swift using JavaScriptCore. As an example, Douglas will go through the steps of adding a JavaScript dependency to his iOS reading app to remove tracking parameters from URLs.
He's not talking about hybrid technologies like React Native that let you write your app’s UI in JavaScript. This is about specific components in the logic — even single functions.
Creating App Prototypes from Low to High-Fidelity
Inventing digital products involves a range of roles and procedures. For instance, when you use a website or an application, you can see the visual elements created by UI designers, and you can interact with the user interface thanks to developers that turned it into a tangible reality. What is “invisible” to the eyes of the end-user is the complex work and process made by user experience designers.
The main focus of UX designers is the user, the sensations involved in the use of a specific product or service, how it is easy for them to perform the expected task, and all the interactions the product offers. The purpose is to create an effortless, efficient, and all-around satisfying experience for the user, focusing heavily on empathy.
In his article, he’ll share his methodology to design an app user experience by going through the different prototyping stages. First of all, you will see how to define the core features of an app, trying to avoid overwhelming the experience with too many functions; then, we’ll see how to create an intuitive navigation flow by analyzing different options; finally, how to assemble the interface with definite assets component.
Great stuff to get some insight into what it takes to design something well, and the fun thing is, it kind of is like software development to me. You start small and start building. Iterating closer and closer to your desired solution.
The Tyranny of the Churn Equation
When David Smith writes, I read. And when he starts an article with drawing a paralel with the Rocket Equation, I get excited.
What David shares are a lot of numerical insight into what it takes to run a subscription based business and how to run it well. There are also some insights in there you might want to catch. The biggest thing is the concept of customer aquisition cost, CAC for short. I hate that word, in my current role we constantly talk about metric. Because gaining more customers is great, but only if you spend less to gain them what they actually add to your bottom line. If you spend too much towards gaining customers, there is a very real chance you are infact killing your business because you are not gaining customers at a cost that is sustainable.
A definite read if you are into the subscription-based app business.
Text modifiers in SwiftUI
A part from regular view modifiers in SwiftUI, there are also text modifiers. They apply specific styles to a
Text
view and return anotherText
rather thansome View
. We can see the list of available text modifiers in the Text view documentation under the "Styling the view’s text" and other sections. These are the ones that haveText
as their return type
Applying Built-In Image Filters In Swift
In Gabriel's post you are going to learn how to make use of built-in filters, how to supply parameters in order to achieve the most desirable results, as well as how to chain filters for a combined result. On top of outlining the various stages of the process, Gabriel is also presenting a simple SwiftUI app that demonstrates how everything fits in the context of a project.
So break out your favorite images and start playing, the results I got myself looked surprisingly well.
Making a serverless Swift function with Fastly and Upstash
Fastly's Compute@Edge is a service which allows you to build and deploy serverless applications at the edge. These so called edge functions are applications which are deployed to a number of regions across the world so that they are as close to users as possible. On top of the benefits which serverless computing provides, such as not having to maintain the server infrastructure, edge functions are extremely quick and have very low latency.
How to Run Stream’s Docs on a Multipass VM
This is an article I wrote on Stream's blog.
By using Multipass and a few convenient scripts, I am able to create a runtime environment for Stream docs without having to worry about the side effects of anything that might have ended up on my system. If it turns out to be broken after a while, a full reset of my Docusaurus environment takes just a few minutes. I am also using Multipass VMs more and more when looking at other people’s code. I like the idea of being able to work on something in total isolation from anything else I am working on.
If you add something like VSCode remote development to connect and edit on your Multipass VMs, the experience is even better.
I think you should check this article because I wrote it, obviously, but also because Multipass or another way to isolate your workstation from random experimentation with multiple projects.
Xcode Cloud scripts: Fastlane and Cocoapods
Xcode Cloud is a CI/CD service made by Apple which is deeply integrated into Xcode. Since its introduction, there has been a lot of discussion amongst iOS developers on whether it is a good alternative to existing CI/CD providers and what migration to Xcode Cloud would look like.
Setting up this new service is rather straigh-forward for small or new apps but it can be daunting for big codebases which have been around for a long time. These big codebases tend to still rely to some extent on third-party dependency managers such as CocoaPods and on third-party CI/CD tools such as Fastlane.
The use of such third-party frameworks tends to put people off switching over to Xcode Cloud but, in this article, Pol will go through how the use of custom CI scripts can help you and your team progressively migrate to Xcode Cloud without having to abandon the tools you have used for a long time. More specifically, this article explains how to build an app using CocoaPods and upload the resulting app archive to AppCenter using Fastlane from an Xcode Cloud workflow.
Swift async/await in AWS lambdas
The swift-server team have been hard at work getting the first stable release of the swift-aws-lambda-runtime project ready.
The changes for this unreleased 1.0 version include, among others, the adoption of
async/await
. In this article we'll rewrite an existing lambda to use the latestmain
revision of the swift-aws-lambda-runtime package and take an early look at what the new APIs look like and how they enable us to useasync/await
in AWS lambdas.
Some really cool stuff you can do on Amazon's cloud with scalable architecture without deploying any servers.
Using CallKit - How to Integrate Voice and Video Calling Into iOS Apps
Amos does an amazing write-up on how to deal with this framework in your app. The lessons are applicable to any app wanting to integrate with CallKit.
HTTP/3 support for URLSession
Marco Eidinger provides us with an overview of what HTTP/3 provides us and in what way everything is already taken care of by URLSession. Biggest takeaway I had from his write-up is that w should be fine.
Testing Apps with an iPhone and the CarPlay Simulator
Ever since WWDC 2022, there is a new way to test CarPlay-enabled apps with your iPhone and Apple's CarPlay Simulator.
The CarPlay Simulator can run a CarPlay-enabled app in a window that simulates the in-car display experience, almost as if you are running it inside a car's CarPlay system or an aftermarket module.
The CarPlay Simulator comes as a part of the **Additional Tools for Xcode** package and can be downloaded from the Apple Developer Website.
Trap exit code (SIGINT, SIGTERM etc) in a Swift Package Executable CLI
When building an executable CLI product using swift package, especially ones with long running tasks, users can exit the script at anytime by sending exit code to the process, for example, by tapping
CTL+C
or executekillall
command.Sometimes the CLI needs to trap such signals to do cleanup works. For Example, if the CLI is writing data continuously into a file, it might need to close the file properly on exit so that the file will not be corrupted.
The day my app got thousands of downloads and in-app unlocks
This year, Filip's document scanner app Scan it was part of the fantastic Indie App Santa project. Going in, he had yet to learn what to expect beyond some significant amount of downloads.
Scan it was featured on December 5, so Filip felt the urge to wake up soon and check that there is not a massive fire to put out. Thankfully he woke up to just a few support emails mentioning the price is not Free (probably a timezone issue) and problems with Family Sharing…
Looking at it now, Filip has gotten less than 20 support emails and a few messages on Twitter. For some reason, during the “D-Day,” it seemed like many more.
Thankfully people were supportive and understanding.
Filip writes a good recap on his experience when receiving a big influx of new users. It does not matter for what reason this happens, the lessons are universal. You are never ready, you can only do your best. And most likely, if you did a decent job developing your product, and you are open about the challenges you are facing, things will work out.
When does a SwiftUI Environment get retained?
The answer depends on how we use SwiftUI. For an app entirely written using it, one might argue that it gets released whenever the app finishes. But what about an UIKit app that uses some SwiftUI views?
To answer this question, let’s explore some scenarios involving environment objects. They have reference semantics, and we can track their instances using the memory graph.
Animated Launch Screen in SwiftUI
In this article you will learn how to create a Launch screen in SwiftUI using modern approaches like environment variables, create a state machine to control the animations, and also async/await to mock an API call.
The API call part is very important because after that is completed it will trigger the dismissal of the Launch Screen, and this behavior is really close to or if not identical to what we have in a lot of apps. Keep in mind the responsibility of everything here. The act of call to dismiss doesn’t come from the view itself as an external agent, but the dismissal itself is the responsibility of the Launch Screen State Manager.
A Guided Tour for SwiftUI ForEach Structure
We will start this article by answering the first thing you need to know, and the exact definition that structures ForEach in SwiftUI. Then we will provide examples of how and when you can use it to improve your code.
ForEach in SwiftUI is one of the most basic structures out there and it is really important to have a good grasp of it.
What is ForEach in SwiftUI?
What is the difference between List and ForEach in SwiftUI
ForEach is a view that creates an array of views from an underlying collection of data. The resulting views can be used within other container views, e.g., VStack, HStack, and List.
List is a container view that turns a collection of views into a list structure.*
How Does Swift Concurrency Prevents Thread Explosions?
A few weeks back, I read an article by Wojciech Kulik, where he talks about some of the pitfalls in the Swift Concurrency framework. In one of the sections, Wojciech briefly mentioned thread explosion, and how Swift Concurrency can prevent it from happening by limiting us from overcommitting the system with more threads than the CPU cores.
This makes me wonder… Is that really the case? How does this work behind the scenes? Can we somehow cheat the system to create more threads than the CPU cores?
We are going to answer all these questions in this article. So without further ado, let’s jump right in.
Building custom layout in SwiftUI. Basics
SwiftUI provides the Layout protocol allowing us to build super-custom layouts by digging into the layout system without using GeometryReader. Layout protocol brings us the incredible power of building and reusing any layout you can imagine. This week we will learn how to use the new Layout protocol to build a flow layout in SwiftUI.
Using SwiftUI Effects Library: How to Add Particle Effects to iOS Apps
Creating particle animations similar to the iMessage screen and bubble effects in iOS can be difficult. The main reason is that the Core Animation Emitter Layer that allows you to animate, emit and render particle effects is complex to set up and configure due to its large number of parameters.
In this article, you will discover how to integrate and render particles such as snow, confetti, rain, smoke, and fireworks to iOS applications effortlessly and without knowing the Physics behind these animations.
Introducing - Swift cheatsheet - The.Swift.Dev.
A complete Swift programming language reference for beginners with more than a 100 snippets. Now available on Gumroad.
You should check this one, It's a very convenient resource.