Azureバックエンドを備えたIOSアプリがあり、ログインやユーザーが実行しているアプリのバージョンなど、特定のイベントをログに記録したいと考えています。
Swiftを使用してバージョンとビルド番号を返すにはどうすればよいですか?
Azureバックエンドを備えたIOSアプリがあり、ログインやユーザーが実行しているアプリのバージョンなど、特定のイベントをログに記録したいと考えています。
Swiftを使用してバージョンとビルド番号を返すにはどうすればよいですか?
回答:
編集
Swift 4.2向けに更新
let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String
編集
新しいバージョンのXcodeで@azdevが指摘したように、以前の解決策を試みるとコンパイルエラーが発生します。これを解決するには、!
let nsObject: AnyObject? = Bundle.main.infoDictionary!["CFBundleShortVersionString"]
編集を終了
Objective-Cと同じロジックを使用しますが、いくつかの小さな変更があります
//First get the nsObject by defining as an optional anyObject
let nsObject: AnyObject? = NSBundle.mainBundle().infoDictionary["CFBundleShortVersionString"]
//Then just cast the object as a String, but be careful, you may want to double check for nil
let version = nsObject as! String
これがお役に立てば幸いです。
デビッド
infoDictionary
はを使用してラップ解除する必要があります!
。これはGlobals.swiftファイルに置かれ、私が使用していますものです:let appVersion = NSBundle.mainBundle().infoDictionary!["CFBundleVersion"] as String
let appVersion = NSBundle.mainBundle().infoDictionary!["CFBundleVersion"] as! String
私はこれがすでに回答されていることを知っていますが、個人的にはこれは少しクリーンだと思います:
Swift 3.0:
if let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String {
self.labelVersion.text = version
}
スウィフト<2.3
if let version = NSBundle.mainBundle().infoDictionary?["CFBundleShortVersionString"] as? String {
self.labelVersion.text = version
}
このように、if letバージョンが条件付き処理(私の場合はラベルテキストの設定)を処理し、infoDictionaryまたはCFBundleShortVersionStringがnilの場合、オプションのアンラップによりコードがスキップされます。
self.labelVersion.text
はオプションタイプなので、直接割り当てることができますNSBundle.mainBundle().infoDictionary?["CFBundleShortVersionString"] as? String
let
なぜそれが必要になるのか疑問に思っているだけで、は間違いなくより慎重であることに同意しました。ありがとう!
Swift 3.0用に更新
NS
-prefixesは今スウィフト3.0になくなっているし、いくつかのプロパティ/メソッドは、よりSwiftyように名前を変更しました。これは今のように見えます:
extension Bundle {
var releaseVersionNumber: String? {
return infoDictionary?["CFBundleShortVersionString"] as? String
}
var buildVersionNumber: String? {
return infoDictionary?["CFBundleVersion"] as? String
}
}
Bundle.main.releaseVersionNumber
Bundle.main.buildVersionNumber
古い更新された回答
私は元の回答からずっとフレームワークを使用してきました。そのため、ソリューションをマルチバンドル環境でよりシンプルではるかに役立つものに更新したいと思いました。
extension NSBundle { var releaseVersionNumber: String? { return self.infoDictionary?["CFBundleShortVersionString"] as? String } var buildVersionNumber: String? { return self.infoDictionary?["CFBundleVersion"] as? String } }
次のように、この拡張機能はアプリでメインバンドルと他の含まれているバンドル(拡張プログラミングの共有フレームワークやAFNetworkingなどの3番目のフレームワークなど)の両方を識別するのに役立ちます。
NSBundle.mainBundle().releaseVersionNumber NSBundle.mainBundle().buildVersionNumber // or... NSBundle(URL: someURL)?.releaseVersionNumber NSBundle(URL: someURL)?.buildVersionNumber
元の回答
すでに投稿されている回答のいくつかを改善したいと思いました。これをより論理的な方法で処理するためにツールチェーンに追加できるクラス拡張を作成しました。
extension NSBundle { class var applicationVersionNumber: String { if let version = NSBundle.mainBundle().infoDictionary?["CFBundleShortVersionString"]
なので?String {return version} return "Version Number Not Available"}
class var applicationBuildNumber: String { if let build = NSBundle.mainBundle().infoDictionary?["CFBundleVersion"] as? String { return build } return "Build Number Not Available" } }
したがって、次の方法で簡単にアクセスできます。
let versionNumber = NSBundle.applicationVersionNumber
これはすでに回答済みであることも知っていますが、以前の回答をまとめました。
extension Bundle {
var releaseVersionNumber: String? {
return infoDictionary?["CFBundleShortVersionString"] as? String
}
var buildVersionNumber: String? {
return infoDictionary?["CFBundleVersion"] as? String
}
var releaseVersionNumberPretty: String {
return "v\(releaseVersionNumber ?? "1.0.0")"
}
}
使用法:
someLabel.text = Bundle.main.releaseVersionNumberPretty
Swift 3.1:
class func getVersion() -> String {
guard let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String else {
return "no version info"
}
return version
}
古いバージョンの場合:
class func getVersion() -> String {
if let version = NSBundle.mainBundle().infoDictionary?["CFBundleShortVersionString"] as? String {
return version
}
return "no version info"
}
したがって、ラベルテキストを設定する場合、または別の場所で使用する場合。
self.labelVersion.text = getVersion()
用スウィフト4.0
let version = Bundle.main.infoDictionary!["CFBundleShortVersionString"]!
let build = Bundle.main.infoDictionary!["CFBundleVersion"]!
バンドルの拡張を行いました
extension Bundle {
var appName: String {
return infoDictionary?["CFBundleName"] as! String
}
var bundleId: String {
return bundleIdentifier!
}
var versionNumber: String {
return infoDictionary?["CFBundleShortVersionString"] as! String
}
var buildNumber: String {
return infoDictionary?["CFBundleVersion"] as! String
}
}
そしてそれを使う
versionLabel.text = "\(Bundle.main.appName) v \(Bundle.main.versionNumber) (Build \(Bundle.main.buildNumber))"
Swift 3.0 NSBundleが機能しない場合、以下のコードは完全に機能します。
let versionNumberString =
Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString")
as! String
ビルド番号のみの場合は、次のとおりです。
let buildNumberString =
Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion")
as! String
紛らわしいことに、「CFBundleVersion」は、XcodeでGeneral-> Identityに入力されたビルド番号です。
Xcode 9.4.1 Swift 4.1
バンドル表示名の正しい言語バージョンを取得するために、localizedInfoDictionaryを使用していることに注意してください。
var displayName: String?
var version: String?
var build: String?
override func viewDidLoad() {
super.viewDidLoad()
// Get display name, version and build
if let displayName = Bundle.main.localizedInfoDictionary?["CFBundleDisplayName"] as? String {
self.displayName = displayName
}
if let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String {
self.version = version
}
if let build = Bundle.main.infoDictionary?["CFBundleVersion"] as? String {
self.build = build
}
}
Swift 4、バンドル向けの便利な拡張機能
import Foundation
public extension Bundle {
public var shortVersion: String {
if let result = infoDictionary?["CFBundleShortVersionString"] as? String {
return result
} else {
assert(false)
return ""
}
}
public var buildVersion: String {
if let result = infoDictionary?["CFBundleVersion"] as? String {
return result
} else {
assert(false)
return ""
}
}
public var fullVersion: String {
return "\(shortVersion)(\(buildVersion))"
}
}
Bundle + Extensions.swift
import Foundation
extension Bundle {
var versionNumber: String? {
return infoDictionary?["CFBundleShortVersionString"] as? String
}
var buildNumber: String? {
return infoDictionary?["CFBundleVersion"] as? String
}
var bundleName: String? {
return infoDictionary?["CFBundleName"] as? String
}
}
使用法:
someLabel.text = Bundle.main.versionNumber
OPはバージョン番号とビルド番号の両方を要求しました。残念ながら、ほとんどの回答はこれらのオプションの両方を提供していません。また、不要な拡張メソッドを追加するものもあります。これはかなりシンプルで、OPの問題を解決するものです。
// Example output: "1.0 (234)"
private func versionAndBuildNumber() -> String {
let versionNumber = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String
let buildNumber = Bundle.main.infoDictionary?["CFBundleVersion"] as? String
if let versionNumber = versionNumber, let buildNumber = buildNumber {
return "\(versionNumber) (\(buildNumber))"
} else if let versionNumber = versionNumber {
return versionNumber
} else if let buildNumber = buildNumber {
return buildNumber
} else {
return ""
}
}
私の答え(2015年8月現在)、Swiftが進化し続けることを考えると:
let version = NSBundle.mainBundle().infoDictionary!["CFBundleVersion"] as! String
UIApplicationの拡張機能を作成しました。
extension UIApplication {
static var appVersion: String {
let versionNumber = Bundle.main.infoDictionary?[IdentifierConstants.InfoPlist.versionNumber] as? String
let buildNumber = Bundle.main.infoDictionary?[IdentifierConstants.InfoPlist.buildNumber] as? String
let formattedBuildNumber = buildNumber.map {
return "(\($0))"
}
return [versionNumber,formattedBuildNumber].compactMap { $0 }.joined(separator: " ")
}
}
struct IdentifierConstants {
struct InfoPlist {
static let versionNumber = "CFBundleShortVersionString"
static let buildNumber = "CFBundleVersion"
}
}
ドキュメントを見て、次の方がきれいだと思います。
let version =
NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleShortVersionString")
as? String
出典:「このメソッドの使用は、キーのローカライズされた値が利用可能な場合にローカライズされた値を返すため、他のアクセスメソッドよりも優先されます。」
Swift 1.2の場合:
let version = NSBundle.mainBundle().infoDictionary!["CFBundleShortVersionString"] as! String
let build = NSBundle.mainBundle().infoDictionary!["CFBundleVersion"] as! String
スウィフト3:
バージョンナンバー
if let versionNumberString = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String { // do something }
ビルド番号
if let buildNumberString = Bundle.main.infoDictionary?["CFBundleVersion"] as? String { // do something }
スウィフト4
func getAppVersion() -> String {
return "\(Bundle.main.infoDictionary!["CFBundleShortVersionString"] ?? "")"
}
Bundle.main.infoDictionary!["CFBundleShortVersionString"]
Swiftの古い構文
let appVer: AnyObject? = NSBundle.mainBundle().infoDictionary!["CFBundleShortVersionString"]
extension UIApplication {
static var appVersion: String {
if let appVersion = NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleShortVersionString") {
return "\(appVersion)"
} else {
return ""
}
}
static var build: String {
if let buildVersion = NSBundle.mainBundle().objectForInfoDictionaryKey(kCFBundleVersionKey as String) {
return "\(buildVersion)"
} else {
return ""
}
}
static var versionBuild: String {
let version = UIApplication.appVersion
let build = UIApplication.build
var versionAndBuild = "v\(version)"
if version != build {
versionAndBuild = "v\(version)(\(build))"
}
return versionAndBuild
}
}
注意:アプリのバージョンまたはビルドが設定されていない場合に使用すると、使用しようとするとクラッシュする可能性があります。アンラップする。
Swift 3.2の更新バージョンは次のとおりです。
extension UIApplication
{
static var appVersion:String
{
if let appVersion = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString")
{
return "\(appVersion)"
}
return ""
}
static var buildNumber:String
{
if let buildNum = Bundle.main.object(forInfoDictionaryKey: kCFBundleVersionKey as String)
{
return "\(buildNum)"
}
return ""
}
static var versionString:String
{
return "\(appVersion).\(buildNumber)"
}
}
public var appVersionNumberString: String {
get {
return Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as! String
}
}
興味のある方のためにSwifterSwift
、githubで利用できる素晴らしいライブラリがあり、すべてのバージョンのswiftについて完全に文書化されています(swifterswift.comを参照)。
このライブラリを使用すると、アプリのバージョンとビルド番号を読み取るのが次のように簡単になります。
import SwifterSwift
let buildNumber = SwifterSwift.appBuild
let version = SwifterSwift.appVersion
これは、「更新されたアプリ」ページを表示するかどうかを決定するために使用している関数です。それは私がIntに変換しているビルド番号を返します:
if let version: String = Bundle.main.infoDictionary?["CFBundleVersion"] as? String {
guard let intVersion = Int(version) else { return }
if UserDefaults.standard.integer(forKey: "lastVersion") < intVersion {
print("need to show popup")
} else {
print("Don't need to show popup")
}
UserDefaults.standard.set(intVersion, forKey: "lastVersion")
}
以前に使用したことがない場合は、現在のビルド番号よりも小さい0を返します。このような画面を新しいユーザーに表示しないようにするには、最初のログイン後、またはオンボーディングが完了したときにビルド番号を追加します。
アプリのバージョンをIntとして返すシンプルなユーティリティ関数
func getAppVersion() -> Int {
if let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String {
let appVersionClean = appVersion.replacingOccurrences(of: ".", with: "", options: NSString.CompareOptions.literal, range:nil)
if let appVersionNum = Int(appVersionClean) {
return appVersionNum
}
}
return 0
}
if let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String {
self.lblAppVersionValue.text = version
}
Bundle + Extension.swift(SwiftUI、Swift 5、Xcode 11)
私はいくつかの回答からのアイデアを組み合わせ、少し拡張しました:
輸入財団
拡張バンドル{
public var appVersionShort: String? {
if let result = infoDictionary?["CFBundleShortVersionString"] as? String {
return result
} else {
return "⚠️"
}
}
public var appVersionLong: String? {
if let result = infoDictionary?["CFBundleVersion"] as? String {
return result
} else {
return "⚠️"
}
}
public var appName: String? {
if let result = infoDictionary?["CFBundleName"] as? String {
return result
} else {
return "⚠️"
}
}
}
SwiftUIの使用例
VStack {
Text("Version: \(Bundle.main.appVersionShort!) (\(Bundle.main.appVersionLong!))")
.font(.subheadline)
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
if let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String {
lblVersion.text = "Version \(version)"
}