Update of my mobile apps to Swift 6
With the recent updates of Xcode and iOS, I took the opportunity to update my mobile apps to the latest version of Xcode 16 and Swift 6.
Main reasons to update
- I felt that to support older versions of iOS, I was losing track to the latest updates in SwiftUI.
- I was also not supporting the cross-platform architecture from Apple, so MacOS and the new Vision Pro.
- I also wanted to check my code for the new concurrency checks in Swift 6. So one of the goals was also to fully update my code to the latest version of Swift.
Update process
- Instead of trying to bring all updates into my existing source codes, I have created new projects with the latest version of Xcode and migrated my existing code into this new blank projects.
- During the process, I have reintroduced the linter, as discussed in Swift: How to Install and Configure SwiftLint.
- I have also enabled Swift 6 (under Project | Build Settings | Swift Compiler - Language | Swift Language Version | Swift 6).
- With the occasion, I have also enabled Code Analysis (under Project | Static Analysis - Analysis Policy | Analyze During 'Build' | Yes).
Update to Swift 6
In the SwiftUIDownloader app, I needed to fix my warnings as follows:
- All the callback methods in my delegates were not running in the main thread, so I needed to mark my methods as 'nonisolated'.
- This meant that to access member of my view model, I needed to enter the main thread via Task { @MainActor in ... }
Other updates for SwiftUIDownloader
- The navigation with NavigationView is deprecated, so I have replaced it with NavigationStack. This allowed it to work in MacOS too.
- For iOS and Vision Pro apps, I needed to re-add the following capabilities (under Project | Target | Signing & Capabilities | Background Modes):
- Background fetch
- Background processing
- To make the app to work even for MacOS, as it is sandboxed, I needed to add another capability (under Project | Target | Signing & Capabilities | App Sandbox):
- Outgoing Connections (Client)
Other updates for SwiftUIMusicPlayer
- I had the same issues with NavigationStack and delegate issues, solved them quickly after the previous project
- The artwork load methods are deprecated, so I needed to replace them with the async versions of similar methods. All of this was pretty linear to be honest.
- AVRouterPickerView and UIScreenReader are not available in VisionOS, so I needed to remove them from this specific build.
- On Apple Vision Pro, the default layout of the application is horizontal. I could have forced it to be vertical, in portrait mode, but I thought it would have been interesting to add landscape layout to iOS too. So I have done it and so the application has two different layouts: one vertical, with the image on top of the other controls, and one horizontal, where the image is on the left and on the right there are all other controls.
- With this, I have corrected some old bugs in the drag of the sliders for both music positioning and volume.
- At this point it was working for iOS and VisionOS, but I had many errors on Mac! The issue here is that it is not possible to control volume in a MacOS sandboxed application. I have chosen the most pragmetic approach, i.e. to disable the controls for volume management in MacOS.
- About this topic: on VisionOS, the MPVolumeView control for volume management is available, but on the simulator doesn't have any effect. I could have disabled it on VisionOS too, but I have chosen not to do it, unless I will verify on a real Apple Vision Pro that it really doesn't work.
- Btw: I needed to re-add the following capability in the project settings:
- Background Mode | Audio, AirPlay and Picture in Picture
Conclusions
What to say? Updating these two sample apps became a bigger project, once I have chosen to add support for Apple Vision Pro and MacOS.
But I am very happy with the outcomes, because it shows a more modern way of developing mobile (and at this point, not only mobile) applications.
I just would like to remind you, these two application are open-source and they are available at SwiftUIDownloader and SwiftUIMusicPlayer.