| import Foundation |
| import UIKit |
|
|
| import Darwin |
|
|
| |
| enum DeviceInfoHelper { |
| |
| @MainActor |
| static func platformString() -> String { |
| let v = ProcessInfo.processInfo.operatingSystemVersion |
| let name = switch UIDevice.current.userInterfaceIdiom { |
| case .pad: |
| "iPadOS" |
| case .phone: |
| "iOS" |
| default: |
| "iOS" |
| } |
| return "\(name) \(v.majorVersion).\(v.minorVersion).\(v.patchVersion)" |
| } |
|
|
| |
| static func platformStringForDisplay() -> String { |
| let v = ProcessInfo.processInfo.operatingSystemVersion |
| return "iOS \(v.majorVersion).\(v.minorVersion).\(v.patchVersion)" |
| } |
|
|
| |
| @MainActor |
| static func deviceFamily() -> String { |
| switch UIDevice.current.userInterfaceIdiom { |
| case .pad: |
| "iPad" |
| case .phone: |
| "iPhone" |
| default: |
| "iOS" |
| } |
| } |
|
|
| |
| static func modelIdentifier() -> String { |
| var systemInfo = utsname() |
| uname(&systemInfo) |
| let machine = withUnsafeBytes(of: &systemInfo.machine) { ptr in |
| String(bytes: ptr.prefix { $0 != 0 }, encoding: .utf8) |
| } |
| let trimmed = machine?.trimmingCharacters(in: .whitespacesAndNewlines) ?? "" |
| return trimmed.isEmpty ? "unknown" : trimmed |
| } |
|
|
| |
| static func appVersion() -> String { |
| Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "dev" |
| } |
|
|
| |
| static func appBuild() -> String { |
| let raw = Bundle.main.infoDictionary?["CFBundleVersion"] as? String ?? "" |
| return raw.trimmingCharacters(in: .whitespacesAndNewlines) |
| } |
|
|
| |
| static func openClawVersionString() -> String { |
| let version = appVersion() |
| let build = appBuild() |
| if build.isEmpty || build == version { |
| return version |
| } |
| return "\(version) (\(build))" |
| } |
| } |
|
|