Swift. Get Application Basic Info
  
  
Very often you need to get basic application information, for example to show user an application version or maybe some issue has occurred and you want to collect some details about user device. Some information are relatively easy to get some are not so.
So, lets get some basic information. Personally, I prefer keep that information isolated and in one place. Lets create AppInfo struct and add couple of imports.
import SwiftUI
struct AppInfo { }
Application Information
All basic application information can be retrieved from the Bundle object directly or from it’s informational property list.

Display Name
static var displayName: String {
    Bundle.main.infoDictionary?["CFBundleName"] as? String ?? "Unknown"
}
Bundle Identifier
static var bundleIdentifier: String {
    return Bundle.main.bundleIdentifier ?? ""
}
Application Version
static var appVersion: String {
    Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "1.0"
}
static var appBuild: String {
    Bundle.main.infoDictionary?["CFBundleVersion"] as? String ?? "0"
}
static var appFullVersion: String {
    appVersion + "." + appBuild
}
Device Information
To get basic information about device we can use UIDevice object.
OS Version
static var systemVersion: String {
    UIDevice.current.systemVersion
}
Device Model
Unfortunately, there is no easy way to get exact device model. The UIDevice object has model property that should return device model, but it returns only device type (like iPhone). To get exact device model (like iPhone 13), we need to write a bit tricky code.
static var deviceModel: String {
#if targetEnvironment(simulator)
    let identifier = ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"]!
#else
    var systemInfo = utsname()
    uname(&systemInfo)
    let machineMirror = Mirror(reflecting: systemInfo.machine)
    let identifier = machineMirror.children.reduce("") { identifier, element in
        guard let value = element.value as? Int8, value != 0 else { return identifier }
        return identifier + String(UnicodeScalar(UInt8(value)))
    }
#endif
    return identifier
}
Usage
Now, when we have everything we need we can try to use it.
Text("Version: \(AppInfo.appVersion)")
Summary
So, lets combine everything all together.
import SwiftUI
struct AppInfo {
    
    static var bundleIdentifier: String {
        return (Bundle.main.bundleIdentifier ?? "")
    }
    
    static var displayName: String {
        Bundle.main.infoDictionary?["CFBundleName"] as? String ?? "Unknown"
    }
    
    static var appBuild: String {
        Bundle.main.infoDictionary?["CFBundleVersion"] as? String ?? "0"
    }
    
    static var appVersion: String {
        Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "1.0"
    }
    
    static var appFullVersion: String {
        appVersion + "." + appBuild
    }
    static var systemVersion: String {
        UIDevice.current.systemVersion
    }
    
    static var deviceModel: String {
        #if targetEnvironment(simulator)
        let identifier = ProcessInfo().environment["SIMULATOR_MODEL_IDENTIFIER"]!
        #else
        var systemInfo = utsname()
        uname(&systemInfo)
        let machineMirror = Mirror(reflecting: systemInfo.machine)
        let identifier = machineMirror.children.reduce("") { identifier, element in
            guard let value = element.value as? Int8, value != 0 else { return identifier }
            return identifier + String(UnicodeScalar(UInt8(value)))
        }
        #endif
        return identifier
    }
}
Source Code
The sample application for this article you can find here .