How to show the app icon and version in a SwiftUI view
Helm Pro yearly subscribers now get a 30% discount on RocketSim thanks to contingent pricing on the App Store.
Displaying the app icon and version in your app is a great way to provide users, both internal (e.g. testers or stakeholders) and external, with a quick and easy way to identify both which version and variant of the app they are using.
In this article, I will show you how you can create an accessible SwiftUI view that does exactly that and look great for all text sizes and appearances:
Getting the app icon
The first step to building the view is to get the app icon from the main bundle. This can be done, as this answer in Stack Overflow shows, by retrieving the values for a set of keys in the app’s Info.plist
file:
import Foundation
enum AppIconProvider {
static func appIcon(in bundle: Bundle = .main) -> String {
# 1
guard let icons = bundle.object(forInfoDictionaryKey: "CFBundleIcons") as? [String: Any],
# 2
let primaryIcon = icons["CFBundlePrimaryIcon"] as? [String: Any],
# 3
let iconFiles = primaryIcon["CFBundleIconFiles"] as? [String],
# 4
let iconFileName = iconFiles.last else {
fatalError("Could not find icons in bundle")
}
return iconFileName
}
}
Let’s go through the code above step by step:
- We then retrieve the value for the
CFBundleIcons
key in theInfo.plist
file. This value is a dictionary containing nested dictionaries with information about the app’s icons. - We then retrieve the value for the
CFBundlePrimaryIcon
key in theCFBundleIcons
dictionary. This value is a dictionary containing information about the app’s primary icon. - We then retrieve the value for the
CFBundleIconFiles
key in theCFBundlePrimaryIcon
dictionary. This value is an array containing the names of the app’s icon files. These names can be used to create a namedUIImage
using theUIImage(named:)
initialiser. - Finally, we retrieve the last value in the
CFBundleIconFiles
array.
Getting the app version
Now that we have the app icon, let’s retrieve the app version string. Similarly to what we did earlier, we need to read the value for the CFBundleShortVersionString
key in the app’s Info.plist
:
import Foundation
enum AppVersionProvider {
static func appVersion(in bundle: Bundle = .main) -> String {
guard let version = bundle.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String else {
fatalError("CFBundleShortVersionString should not be missing from info dictionary")
}
return version
}
}
If you want to include the build number alongside the version number in the view we will create in the next section, you can retrieve the value for the
CFBundleVersion
key instead.
Creating a SwiftUI view
Let’s now put everything together and create a SwiftUI view that shows the app icon and version side by side:
import SwiftUI
struct AppVersionInformationView: View {
# 1
let versionString: String
let appIcon: String
var body: some View {
# 2
HStack(alignment: .center, spacing: 12) {
# 3
// App icons can only be retrieved as named `UIImage`s
// https://stackoverflow.com/a/62064533/17421764
if let image = UIImage(named: appIcon) {
Image(uiImage: image)
.resizable()
.aspectRatio(contentMode: .fit)
.clipShape(RoundedRectangle(cornerRadius: 8))
}
# 4
VStack(alignment: .leading) {
Text("Version")
.bold()
Text("v\(versionString)")
}
.font(.caption)
.foregroundColor(.primary)
}
# 5
.fixedSize()
# 6
.accessibilityElement(children: .ignore)
.accessibilityLabel("App version \(versionString)")
}
}
Let’s go through the code above step by step:
- The view takes two parameters: the app version and the app icon. These values are passed through to the view using the two providers we created earlier.
- We display the app icon and version in a horizontal stack with a spacing of 12 points.
- We display the app icon in an
Image
view. However, app icons can only be retrieved as namedUIImage
s, so we’ll have to create aUIImage
first and then convert it into aSwiftUI
Image
. - We then display the app version in a vertical stack composed of a label with the text version and the app version string itself.
- We use the
fixedSize()
modifier to ensure that both the app icon andVStack
views are the same height. - Finally, we group all child views into a single accessibility element and give it a label to provide a better experience for VoiceOver users.
The result of what we have done so far is a view that looks great for all text sizes:
Finally, we can put all elements we created in this article together and display the new version information view in our app like this:
import SwiftUI
struct ContentView: View {
var body: some View {
AppVersionInformationView(
versionString: AppVersionProvider.appVersion(),
appIcon: AppIconProvider.appIcon()
)
}
}