ฉันมีแอพ IOS ที่มี Azure back-end และต้องการบันทึกกิจกรรมบางอย่างเช่นการเข้าสู่ระบบและเวอร์ชันของผู้ใช้แอปที่กำลังทำงานอยู่
ฉันจะคืนเวอร์ชันและหมายเลขบิลด์ด้วย Swift ได้อย่างไร
ฉันมีแอพ IOS ที่มี Azure back-end และต้องการบันทึกกิจกรรมบางอย่างเช่นการเข้าสู่ระบบและเวอร์ชันของผู้ใช้แอปที่กำลังทำงานอยู่
ฉันจะคืนเวอร์ชันและหมายเลขบิลด์ด้วย Swift ได้อย่างไร
คำตอบ:
แก้ไข
อัปเดตสำหรับ Swift 4.2
let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String
แก้ไข
ดังที่ @azdev ชี้ให้เห็นในเวอร์ชันใหม่ของ Xcode คุณจะได้รับข้อผิดพลาดในการรวบรวมสำหรับลองใช้วิธีแก้ไขปัญหาก่อนหน้าของฉันเพื่อแก้ไขสิ่งนี้เพียงแก้ไขมันตามที่แนะนำให้แกะพจนานุกรมมัดโดยใช้!
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
ฉันรู้ว่าคำตอบนี้ได้รับการตอบแล้ว แต่โดยส่วนตัวฉันคิดว่ามันสะอาดกว่านี้เล็กน้อย:
สวิฟท์ 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 เป็นศูนย์การคลายการเลือกจะทำให้รหัสถูกข้าม
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
คำตอบที่อัปเดตเก่า
ฉันทำงานกับ Frameworks มากตั้งแต่คำตอบดั้งเดิมของฉันดังนั้นฉันจึงต้องการอัปเดตโซลูชันเป็นสิ่งที่ง่ายและมีประโยชน์มากขึ้นในสภาพแวดล้อมแบบหลายกลุ่ม:
extension NSBundle { var releaseVersionNumber: String? { return self.infoDictionary?["CFBundleShortVersionString"] as? String } var buildVersionNumber: String? { return self.infoDictionary?["CFBundleVersion"] as? String } }
ตอนนี้ส่วนขยายนี้จะมีประโยชน์ในแอปเพื่อระบุทั้งบันเดิลหลักและบันเดิลอื่น ๆ ที่รวมไว้ (เช่นเฟรมเวิร์กที่แชร์สำหรับการเขียนโปรแกรมส่วนขยายหรือเฟรมเวิร์กที่สามเช่น AFNetworking) ดังนี้:
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"]
เช่น? สตริง {return version} ส่งคืน "หมายเลขเวอร์ชันไม่พร้อมใช้งาน"}
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
สวิฟท์ 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()
สำหรับSwift 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 ในงานทั่วไปซึ่ง> เอกลักษณ์
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
}
}
Xcode 8, Swift 3:
let gAppVersion = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") ?? "0"
let gAppBuild = Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion") ?? "0"
Swift 4 ส่วนขยายที่มีประโยชน์สำหรับ Bundle
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) ได้รับ 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"]
ไวยากรณ์เก่าที่รวดเร็ว
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)"
}
}
ตอนนี้คุณสามารถใช้ค่าคงที่สำหรับสิ่งนี้แทนที่จะต้องใช้รหัสที่พิมพ์อย่างเข้มงวดเหมือน แต่ก่อนซึ่งทำให้สิ่งต่าง ๆ สะดวกยิ่งขึ้น
var appVersion: String {
return Bundle.main.infoDictionary![kCFBundleVersionKey as String] as! String
}
public var appVersionNumberString: String {
get {
return Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as! String
}
}
SWIFT 4
// ขั้นแรกรับ nsObject โดยกำหนดเป็น AnyObject ที่เป็นตัวเลือก
let nsObject: AnyObject? = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as AnyObject
// จากนั้นเพียงแค่โยนวัตถุเป็น String แต่ระวังคุณอาจต้องการตรวจสอบศูนย์
let version = nsObject 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 ซึ่งต่ำกว่าหมายเลขบิลด์ปัจจุบัน หากไม่ต้องการแสดงหน้าจอดังกล่าวให้กับผู้ใช้ใหม่เพียงเพิ่มหมายเลขบิลด์หลังจากล็อกอินครั้งแรกหรือเมื่อการขึ้นเครื่องเสร็จสมบูรณ์
สำหรับSwift 5.0 :
let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as! String
ฟังก์ชั่นยูทิลิตี้ง่าย ๆ เพื่อกลับรุ่นแอปเป็น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
}
if let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String {
lblVersion.text = "Version \(version)"
}
Swift 5 เป็นส่วนขยาย UIApplication
extension UIApplication {
static var release: String {
return Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as! String? ?? "x.x"
}
static var build: String {
return Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion") as! String? ?? "x"
}
static var version: String {
return "\(release).\(build)"
}
}
ตัวอย่างการใช้:
print("release: \(UIApplication.release)")
print("build: \(UIApplication.build)")
print("version: \(UIApplication.version)")