SFSafariViewController can be used to let your users open webpages in-app instead of in an external browser. While the view controller works great for UIKit, getting it to work in a SwiftUI app might be challenging. Whenever you’re running into cases where a UIKit solution is available only, you want to know how to write …
Swift Evolution: Reading and learning from proposals
The Swift Programming Language constantly evolves, and most of its changes result from public proposals inside the Swift Evolution repository. The proposals can tell you what changes are coming up next, which is excellent if you want to stay updated with the latest developments. Swift Evolution Proposals can also help you understand newly released features. …
Unit testing async/await Swift code
Unit tests allow you to validate code written using the latest concurrency framework and async/await. While writing tests doesn’t differ much from synchronous tests, there are a few crucial concepts to be aware of when validating asynchronous code. If you’re new to async/await, I encourage you first to read Async await in Swift explained with …
Debugging SwiftUI views: what caused that change?
Debugging SwiftUI views is an essential skill when writing dynamic views with several redrawing triggers. Property wrappers like @State and @ObservedObject will redraw your view based on a changed value. This is often expected behavior, and things look like they should. However, in so-called Massive SwiftUI Views (MSV), there could be many different triggers causing …
Promotional offers: Increase App Revenue using discounts
Promotional offers allow you to increase the revenue for your app by promoting a user’s subscription to a new offer. You can use this technique to win back users who canceled their subscription or to upsell users from a monthly to a yearly plan. Implementing promotional offers differs per project depending on whether you use …
User Defaults reading and writing in Swift
User Defaults are the go-to solution for Swift applications to store preferences that persist across launches of your app. It’s a key-value store backed by a property list (plist) file. Due to this type of backing store, you need to be aware of the supported storage types. There are a few best practices when working …
Thread dispatching and Actors: understanding execution
Actors ensure your code is executed on a specific thread, like the main or a background thread. They help you synchronize access to mutable states and prevent data races. However, developers commonly misunderstand how actors dispatch to threads in non-async contexts. It’s an essential understanding to avoid unexpected crashes. Before we dive deeper into the …
@preconcurrency: Incremental migration to concurrency checking
The @preconcurrency attribute is part of the tools that help you incrementally migrate to strict concurrency checking. When async/await was introduced by Apple, we were writing non-structured asynchronous code, mainly using closures. On our road to Swift 6, we must prepare our projects for strict concurrency checks done by the compiler. The SE-0337 proposal makes …
Picking your minimum iOS version to support
When a new iOS version arrives, it’s oftentimes a moment to reflect on the supported iOS versions and see to which minimum iOS version your project should be set. It’s an important decision in a developer’s job and not something you can do without reasoning. We can be fortunate with the iOS adoption rate in …
Value and Type parameter packs in Swift explained with examples
Type parameter packs and value parameter packs allow you to write a generic function that accepts an arbitrary number of arguments with distinct types. As a result of SE-393, SE-398, and SE-399, you can use this new feature from Swift 5.9. One of the most noticeable places of impact is the 10-view limit in SwiftUI, …