Saya memiliki aplikasi iOS dengan back-end Azure, dan ingin mencatat peristiwa tertentu, seperti login dan versi aplikasi yang dijalankan pengguna.
Bagaimana saya bisa mengembalikan versi dan membangun nomor menggunakan Swift?
Saya memiliki aplikasi iOS dengan back-end Azure, dan ingin mencatat peristiwa tertentu, seperti login dan versi aplikasi yang dijalankan pengguna.
Bagaimana saya bisa mengembalikan versi dan membangun nomor menggunakan Swift?
Jawaban:
EDIT
Diperbarui untuk Swift 4.2
let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String
EDIT
Seperti yang ditunjukkan oleh @azdev pada versi baru Xcode Anda akan mendapatkan kesalahan kompilasi untuk mencoba solusi saya sebelumnya, untuk menyelesaikan ini cukup edit seperti yang disarankan untuk membuka bungkusan kamus bundel menggunakan!
let nsObject: AnyObject? = Bundle.main.infoDictionary!["CFBundleShortVersionString"]
Akhiri Edit
Cukup gunakan logika yang sama daripada di Objective-C tetapi dengan beberapa perubahan kecil
//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
Saya harap ini membantu Anda.
David
infoDictionary
harus dibuka menggunakan !
. Inilah yang saya gunakan, ditempatkan dalam file Globals.swift:let appVersion = NSBundle.mainBundle().infoDictionary!["CFBundleVersion"] as String
let appVersion = NSBundle.mainBundle().infoDictionary!["CFBundleVersion"] as! String
Saya tahu ini sudah dijawab tetapi secara pribadi saya pikir ini sedikit lebih bersih:
Swift 3.0:
if let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String {
self.labelVersion.text = version
}
Cepat <2.3
if let version = NSBundle.mainBundle().infoDictionary?["CFBundleShortVersionString"] as? String {
self.labelVersion.text = version
}
Dengan cara ini, versi if let menangani pemrosesan bersyarat (mengatur teks label dalam kasus saya) dan jika infoDictionary atau CFBundleShortVersionString adalah nihil, pembatalan opsional akan menyebabkan kode dilewati.
self.labelVersion.text
adalah tipe opsional, sehingga Anda dapat langsung menetapkanNSBundle.mainBundle().infoDictionary?["CFBundleShortVersionString"] as? String
let
, hanya bertanya-tanya mengapa itu mungkin diperlukan. Terima kasih!
Diperbarui untuk Swift 3.0
Itu NS
-prefixes sekarang hilang di Swift 3.0 dan beberapa properti / metode telah berubah nama menjadi lebih Swifty. Seperti inilah bentuknya sekarang:
extension Bundle {
var releaseVersionNumber: String? {
return infoDictionary?["CFBundleShortVersionString"] as? String
}
var buildVersionNumber: String? {
return infoDictionary?["CFBundleVersion"] as? String
}
}
Bundle.main.releaseVersionNumber
Bundle.main.buildVersionNumber
Jawaban Yang Diperbarui Lama
Saya sudah sering bekerja dengan Kerangka sejak jawaban asli saya, jadi saya ingin memperbarui solusi saya untuk sesuatu yang lebih sederhana dan jauh lebih berguna dalam lingkungan multi-bundel:
extension NSBundle { var releaseVersionNumber: String? { return self.infoDictionary?["CFBundleShortVersionString"] as? String } var buildVersionNumber: String? { return self.infoDictionary?["CFBundleVersion"] as? String } }
Sekarang ekstensi ini akan berguna dalam aplikasi untuk mengidentifikasi bundel utama dan bundel lain yang disertakan (seperti kerangka kerja bersama untuk pemrograman ekstensi atau kerangka kerja ketiga seperti AFNetworking), seperti:
NSBundle.mainBundle().releaseVersionNumber NSBundle.mainBundle().buildVersionNumber // or... NSBundle(URL: someURL)?.releaseVersionNumber NSBundle(URL: someURL)?.buildVersionNumber
Jawaban Asli
Saya ingin memperbaiki beberapa jawaban yang sudah diposting. Saya menulis ekstensi kelas yang dapat ditambahkan ke rantai alat Anda untuk menangani ini dengan cara yang lebih logis.
extension NSBundle { class var applicationVersionNumber: String { if let version = NSBundle.mainBundle().infoDictionary?["CFBundleShortVersionString"]
sebagai? String {return version} return "Nomor Versi Tidak Tersedia"}
class var applicationBuildNumber: String { if let build = NSBundle.mainBundle().infoDictionary?["CFBundleVersion"] as? String { return build } return "Build Number Not Available" } }
Jadi sekarang Anda dapat mengakses ini dengan mudah dengan:
let versionNumber = NSBundle.applicationVersionNumber
Saya juga tahu ini sudah dijawab tetapi saya membungkus jawaban sebelumnya:
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")"
}
}
Pemakaian:
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
}
Untuk versi yang lebih lama :
class func getVersion() -> String {
if let version = NSBundle.mainBundle().infoDictionary?["CFBundleShortVersionString"] as? String {
return version
}
return "no version info"
}
Jadi jika Anda ingin mengatur teks label atau ingin menggunakan tempat lain;
self.labelVersion.text = getVersion()
Untuk Swift 4.0
let version = Bundle.main.infoDictionary!["CFBundleShortVersionString"]!
let build = Bundle.main.infoDictionary!["CFBundleVersion"]!
Saya membuat Ekstensi di Bundel
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
}
}
dan kemudian menggunakannya
versionLabel.text = "\(Bundle.main.appName) v \(Bundle.main.versionNumber) (Build \(Bundle.main.buildNumber))"
Untuk Swift 3.0 NSBundle tidak berfungsi, Kode berikut berfungsi dengan baik.
let versionNumberString =
Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString")
as! String
dan hanya untuk nomor build, itu adalah:
let buildNumberString =
Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion")
as! String
Yang membingungkan 'CFBundleVersion' adalah nomor build seperti yang dimasukkan dalam Xcode pada General-> Identity.
Xcode 9.4.1 Swift 4.1
Perhatikan penggunaan localizedInfoDictionary untuk mengambil versi bahasa yang tepat dari nama tampilan bundel.
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, Ekstensi berguna untuk Bundel
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))"
}
}
Bundel + 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
}
}
Pemakaian:
someLabel.text = Bundle.main.versionNumber
OP meminta nomor versi dan nomor pembuatan. Sayangnya sebagian besar jawaban tidak menyediakan kedua opsi tersebut. Selain itu, yang lain menambahkan metode ekstensi yang tidak perlu. Inilah satu yang cukup sederhana dan menyelesaikan masalah 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 ""
}
}
Jawaban saya (per Agustus 2015), mengingat Swift terus berevolusi:
let version = NSBundle.mainBundle().infoDictionary!["CFBundleVersion"] as! String
Saya membuat ekstensi untuk aplikasi UIA.
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"
}
}
Setelah melihat dokumentasi, saya percaya bahwa yang berikut ini lebih bersih:
let version =
NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleShortVersionString")
as? String
Sumber : "Penggunaan metode ini lebih disukai daripada metode akses lainnya karena metode ini mengembalikan nilai kunci yang dilokalkan ketika ada."
Untuk Swift 1.2 itu:
let version = NSBundle.mainBundle().infoDictionary!["CFBundleShortVersionString"] as! String
let build = NSBundle.mainBundle().infoDictionary!["CFBundleVersion"] as! String
Swift 3:
Nomor Versi
if let versionNumberString = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String { // do something }
Bangun nomor
if let buildNumberString = Bundle.main.infoDictionary?["CFBundleVersion"] as? String { // do something }
Cepat 4
func getAppVersion() -> String {
return "\(Bundle.main.infoDictionary!["CFBundleShortVersionString"] ?? "")"
}
Bundle.main.infoDictionary! ["CFBundleShortVersionString"]
Sintaks lama yang cepat
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
}
}
Perhatian: Anda harus menggunakan jika biarkan di sini jika versi aplikasi atau build tidak disetel yang akan menyebabkan crash jika Anda mencoba menggunakannya! untuk membuka
Ini versi terbaru untuk 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
}
}
SWIFT 4
// Pertama dapatkan nsObject dengan mendefinisikan sebagai opsional AnyObject
let nsObject: AnyObject? = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as AnyObject
// Kalau begitu, masukkan saja objek sebagai String, tapi hati-hati, kamu mungkin ingin mengecek nil
let version = nsObject as! String
bagi siapa pun yang tertarik, ada perpustakaan yang bagus dan rapi yang disebut SwifterSwift
tersedia di github dan juga sepenuhnya didokumentasikan untuk setiap versi swift (lihat swifterswift.com ).
menggunakan perpustakaan ini, membaca versi aplikasi dan nomor build akan semudah ini:
import SwifterSwift
let buildNumber = SwifterSwift.appBuild
let version = SwifterSwift.appVersion
inilah fungsi yang saya gunakan untuk memutuskan apakah akan menampilkan halaman "aplikasi yang diperbarui" atau tidak. Ini mengembalikan nomor build, yang saya konversi menjadi 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")
}
Jika tidak pernah digunakan sebelumnya akan mengembalikan 0 yang lebih rendah dari nomor build saat ini. Untuk tidak menampilkan layar seperti itu kepada pengguna baru, cukup tambahkan nomor build setelah login pertama atau ketika on-boarding selesai.
Fungsi utilitas sederhana untuk mengembalikan versi Aplikasi sebagai 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
}
Bundel + Extension.swift (SwiftUI, Swift 5, Xcode 11)
Saya menggabungkan ide dari beberapa jawaban, dan sedikit memperluas:
Yayasan impor
bundel ekstensi {
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 "⚠️"
}
}
}
Contoh penggunaan 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)"
}