Bagaimana cara mendapatkan versi Aplikasi dan membangun nomor menggunakan Swift?


387

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?



6
Itu Objective-C, bukan Swift.
Øyvind Vik

10
Pastikan untuk tidak membingungkan CFBundleVersion& CFBundleShortVersionString`. Yang pertama adalah versi build Anda . Yang lainnya adalah nomor versi . Lihat di sini untuk info lebih lanjut
Sayang

1
@ ØyvindVik Kebanyakan orang beranggapan bahwa Anda dapat menerjemahkan solusi Objective-C ke Swift tanpa berpegangan tangan.
gnasher729

Jawaban:


425

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


Ketika saya menggunakan ini, saya mendapatkan kesalahan kompiler "[NSObject: AnyObject]? Tidak memiliki anggota bernama 'subskrip'"
andreas

Anda dapat mencoba mengganti AnyObject? oleh AnyObject! tanpa mengetahui persis kode yang Anda gunakan sangat sulit untuk menebak apa yang salah, juga perlu diingat bahwa Swift dapat berubah dari satu rilis Xcode ke yang lain, sehingga juga relevan untuk mengetahui versi Xcode Anda.
David

18
@andreas infoDictionaryharus dibuka menggunakan !. Inilah yang saya gunakan, ditempatkan dalam file Globals.swift:let appVersion = NSBundle.mainBundle().infoDictionary!["CFBundleVersion"] as String
azdev

1
Saya harus menambahkan satu lagi "!" setelah "as". let appVersion = NSBundle.mainBundle().infoDictionary!["CFBundleVersion"] as! String
yosei

3
Anda harus menghindari menggunakan membuka paksa "!" karena mereka akan menyebabkan aplikasi Anda mogok setiap kali salah satu dari nilai-nilai itu nol
Julius

279

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.


6
self.labelVersion.textadalah tipe opsional, sehingga Anda dapat langsung menetapkanNSBundle.mainBundle().infoDictionary?["CFBundleShortVersionString"] as? String
Jonauz

8
Apakah ada alasan nilainya tidak akan ditetapkan? Setuju itu pasti lebih berhati-hati let, hanya bertanya-tanya mengapa itu mungkin diperlukan. Terima kasih!
Crashalot

@ Crashalot terlepas dari nama Anda;) Anda tidak ingin aplikasi Anda mogok jika, katakanlah, Anda membuat kesalahan ketik, alih-alih minta nomor versi menjadi "ada yang salah".
Daniel Springer

OP: Anda bisa mengganti? dengan! dan hapus "as String". Jika nihil, tidak akan crash
Daniel Springer

245

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

CFBundleVersionKey tidak lagi berfungsi di Swift 3, Xcode 8. Apakah Anda tahu kunci baru untuk digunakan?
Crashalot

71

Saya juga tahu ini sudah dijawab tetapi saya membungkus jawaban sebelumnya:

(*) Diperbarui untuk ekstensi

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

@Drecrecated: Jawaban lama

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()

1
atau: kelas func getVersion () -> String {return NSBundle.mainBundle (). infoDictionary? ["CFBundleShortVersionString"] sebagai? String ?? "no info info"}
tapmonkey

Saya pikir menyalin jawaban lain tidak masuk akal. Jika jawaban Anda tidak valid lagi maka Anda selalu memiliki kemungkinan untuk menghapusnya dan memberikan ruang untuk jawaban lainnya :)
carmen_munich

1
@carmen_munich Karena Anda memfitnah saya harus menjawabnya. Pertama-tama, jawaban ini diposting Maret 2015 dan jawaban Anda diposting Februari 2017. Oleh karena itu, inspirasi Anda harus berasal dari jawaban sebelumnya. Kedua, saya belum melihat jawaban Anda sama sekali, saya memperbarui jawaban saya karena saya menggunakannya sekarang. Saya kira, menggunakan ekstensi tidak unik bagi seseorang di komunitas iOS. Sungguh, coba untuk menjadi dewasa dan menghormati pengembang lain. Saya tidak mendapatkan apa pun yang diposkan di sini. Saya ingin membantu orang. Tolong usahakan untuk tidak mengecilkan hati orang yang mencoba membantu pada SO.
Gunhan

Saya mendengar banyak umpan balik dari para pemula bahwa mereka memposting jawaban dan ingin melihat seseorang mengklik "naik" yang sangat bagus untuk dilihat dan memotivasi orang. Tetapi jika seseorang menyalin jawaban dalam jawaban yang sudah ketinggalan zaman, orang yang berusaha mempostingnya tidak akan mendapatkan motivasi bahwa seseorang memilihnya. Jadi para pemula benar-benar merasa kecewa dan merasa bahwa mereka tidak membawa nilai bagi komunitas dan berhenti memposting. Dan jangan salah, maksud saya ini secara umum. Semoga Anda tidak merasa tersinggung dan mengerti sekarang lebih baik mengapa saya membuat saran ini.
carmen_munich

@carmen_munich Jika Anda secara kronologis memesan jawaban atas pertanyaan ini, Anda akan melihat bahwa orang lain sudah memberikan jawaban yang sama seperti yang Anda lakukan sebelumnya! Jadi Anda menyalahkan saya sesuatu yang Anda lakukan sendiri. Karena saya memiliki riwayat untuk pertanyaan ini, saya membagikan preferensi penggunaan baru saya dalam pembaruan. Itu saja.
Gunhan

32

Untuk Swift 4.0

let version = Bundle.main.infoDictionary!["CFBundleShortVersionString"]!
let build = Bundle.main.infoDictionary!["CFBundleVersion"]!

29

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))"

Sebenarnya agak berbeda. Saya menggunakan kekuatan membuka bungkus misalnya. Anda mungkin berpikir bahwa membuka paksa secara umum adalah buruk, ini salah satu kasus yang jarang terjadi di mana itu boleh saja. Untuk menjelaskannya sedikit lebih, nilai-nilai ini harus ada di kamus jika tidak ada yang salah dengan file proyek. Itu sebabnya pendekatan ini menggunakan kekuatan membuka :-)
carmen_munich

Mengganti nama dan memaksa membuka bukan merupakan perubahan untuk memposting sebagai jawaban baru. Juga, orang-orang mungkin belajar memaksa membuka bungkus dapat digunakan di mana saja ketika mereka melihat jawaban Anda. Bagi para pembaca, jangan menganggap kuncinya ada di sana, selalu lebih baik untuk menangani pembatalan pilihan secara manual daripada memaksakan pembungkusan.
Gunhan

Agar adil ada beberapa kasus langka di mana membuka paksa paksa baik-baik saja. Posting yang satu ini hanya menunjukkan satu kasus di mana itu bisa baik-baik saja. Jika Anda ingin tahu lebih banyak tentang kasus membuka paksa ada beberapa penjelasan yang baik dan tutorial dari Paul Hudson. Saya benar-benar dapat merekomendasikan kepada semua pemula www.hackingwithswift.com
carmen_munich

Ini adalah rekomendasi yang bagus untuk para pemula. Mungkin Anda juga bisa membaca lebih banyak dan belajar lebih banyak. Anda juga harus meningkatkan pemahaman Anda tentang komentar dan apa implikasinya. Misalnya tidak ada yang bilang tidak pernah menggunakan kekuatan membuka bungkus. Tapi untuk info dict kunci-kunci itu bisa dilepas dan force undrap bisa mengakibatkan crash. Lebih aman untuk menangani membuka bungkus di sini.
Gunhan

Mungkin Anda bisa menjelaskan dalam hal apa mereka bisa dihapus dan menjadi nol? Apa yang saya pelajari dari sumber daya menyebutkan itu tidak dalam kasus partiuclare ini. Mereka harus selalu ada di sana kecuali file proyek rusak, dalam hal ini proyek mungkin tidak akan dikompilasi pula
carmen_munich

16

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.


16

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
    }
}

14

Xcode 8, Swift 3:

let gAppVersion = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") ?? "0"
let gAppBuild = Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion") ?? "0"

13

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))"
    }
}

Untuk menggunakan ini, Anda perlu mengatakan Bundle.main.fullVersion misalnya
Joseph Astrahan

12

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

11

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 ""
  }
}

9

Jawaban saya (per Agustus 2015), mengingat Swift terus berevolusi:

let version = NSBundle.mainBundle().infoDictionary!["CFBundleVersion"] as! String

8

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"
    }
}

6

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."


1
itu cara Swift yang tepat, tanpa kekuatan membuka, di mana saja
Juan Boero

5

Untuk Swift 1.2 itu:

let version = NSBundle.mainBundle().infoDictionary!["CFBundleShortVersionString"] as! String
let build = NSBundle.mainBundle().infoDictionary!["CFBundleVersion"] as! String

1
Anda bisa menggunakannya? juga
Dan Rosenstark

4

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 }

Bagaimana dengan nomor build? Terima kasih! CFBundleVersionKey tidak berfungsi.
Crashalot

@ Crashalot Saya memperbaruinya dengan nomor build juga. Berikut ini juga daftar semua Core Foundation Keys: developer.apple.com/library/content/documentation/General/…
jasonnoahchoi

3

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"]

2
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


2

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)"
    }
}

2

Anda sekarang dapat menggunakan konstanta untuk ini, daripada harus menggunakan kode yang diketik seperti sebelumnya, yang membuat segalanya lebih nyaman.

var appVersion: String {
    return Bundle.main.infoDictionary![kCFBundleVersionKey as String] as! String
}

2
public var appVersionNumberString: String {
    get {
        return Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as! String
    }
}

1

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

1

bagi siapa pun yang tertarik, ada perpustakaan yang bagus dan rapi yang disebut SwifterSwifttersedia 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

1

Pembaruan untuk Swift 5

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.


1

Untuk Swift 5.0 :

let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as! String

1

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
    }

1
if let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String {
            self.lblAppVersionValue.text = version
        }

1

Bundel + Extension.swift (SwiftUI, Swift 5, Xcode 11)

Saya menggabungkan ide dari beberapa jawaban, dan sedikit memperluas:

  • contoh SwiftUI
  • Menampilkan emoticon segitiga peringatan (daripada menabrak aplikasi) jika kunci tidak ada dari Info.plist

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)
}

0
if let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String {
        lblVersion.text = "Version \(version)"

    }
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.