Tôi có một ứng dụng IOS có back-end Azure và muốn đăng nhập một số sự kiện nhất định, như đăng nhập và phiên bản nào của người dùng ứng dụng đang chạy.
Làm cách nào tôi có thể trả lại phiên bản và số bản dựng bằng Swift?
Tôi có một ứng dụng IOS có back-end Azure và muốn đăng nhập một số sự kiện nhất định, như đăng nhập và phiên bản nào của người dùng ứng dụng đang chạy.
Làm cách nào tôi có thể trả lại phiên bản và số bản dựng bằng Swift?
Câu trả lời:
BIÊN TẬP
Đã cập nhật cho Swift 4.2
let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String
BIÊN TẬP
Như @azdev đã chỉ ra trên phiên bản Xcode mới, bạn sẽ gặp lỗi biên dịch khi thử giải pháp trước đây của tôi, để giải quyết vấn đề này chỉ cần chỉnh sửa nó như đề xuất để mở khóa từ điển gói bằng cách sử dụng a!
let nsObject: AnyObject? = Bundle.main.infoDictionary!["CFBundleShortVersionString"]
Kết thúc chỉnh sửa
Chỉ sử dụng logic tương tự như trong Objective-C nhưng với một số thay đổi nhỏ
//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
Tôi hy vọng điều này sẽ giúp bạn ra ngoài.
David
infoDictionary
nên được mở khóa bằng cách sử dụng !
. Đây là những gì tôi đang sử dụng, được đặt vào tệp Globals.swift:let appVersion = NSBundle.mainBundle().infoDictionary!["CFBundleVersion"] as String
let appVersion = NSBundle.mainBundle().infoDictionary!["CFBundleVersion"] as! String
Tôi biết điều này đã được trả lời nhưng cá nhân tôi nghĩ rằng điều này sạch sẽ hơn một chút:
Swift 3.0:
if let version = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String {
self.labelVersion.text = version
}
Swift <2.3
if let version = NSBundle.mainBundle().infoDictionary?["CFBundleShortVersionString"] as? String {
self.labelVersion.text = version
}
Bằng cách này, phiên bản if let sẽ xử lý việc xử lý có điều kiện (đặt văn bản nhãn trong trường hợp của tôi) và nếu thông tin Từ điển hoặc CFBundleShortVersionString không được hủy bỏ tùy chọn sẽ khiến mã bị bỏ qua.
self.labelVersion.text
là loại Tùy chọn, vì vậy bạn có thể chỉ định trực tiếpNSBundle.mainBundle().infoDictionary?["CFBundleShortVersionString"] as? String
let
, chỉ tự hỏi tại sao nó có thể cần thiết. Cảm ơn!
Đã cập nhật cho Swift 3.0
Các NS
-prefix hiện đã có trong Swift 3.0 và một số thuộc tính / phương thức đã thay đổi tên thành Swifty hơn. Đây là những gì nó trông giống như bây giờ:
extension Bundle {
var releaseVersionNumber: String? {
return infoDictionary?["CFBundleShortVersionString"] as? String
}
var buildVersionNumber: String? {
return infoDictionary?["CFBundleVersion"] as? String
}
}
Bundle.main.releaseVersionNumber
Bundle.main.buildVersionNumber
Câu trả lời cập nhật cũ
Tôi đã làm việc với Framework rất nhiều kể từ câu trả lời ban đầu của mình, vì vậy tôi muốn cập nhật giải pháp của mình thành một thứ vừa đơn giản vừa hữu ích hơn nhiều trong môi trường nhiều gói:
extension NSBundle { var releaseVersionNumber: String? { return self.infoDictionary?["CFBundleShortVersionString"] as? String } var buildVersionNumber: String? { return self.infoDictionary?["CFBundleVersion"] as? String } }
Bây giờ tiện ích mở rộng này sẽ hữu ích trong các ứng dụng để xác định cả gói chính và bất kỳ gói đi kèm nào khác (chẳng hạn như khung chia sẻ để lập trình tiện ích mở rộng hoặc khung thứ ba như AFNetworking), như vậy:
NSBundle.mainBundle().releaseVersionNumber NSBundle.mainBundle().buildVersionNumber // or... NSBundle(URL: someURL)?.releaseVersionNumber NSBundle(URL: someURL)?.buildVersionNumber
Câu trả lời gốc
Tôi muốn cải thiện một số câu trả lời đã được đăng. Tôi đã viết một phần mở rộng lớp có thể được thêm vào chuỗi công cụ của bạn để xử lý việc này theo cách logic hơn.
extension NSBundle { class var applicationVersionNumber: String { if let version = NSBundle.mainBundle().infoDictionary?["CFBundleShortVersionString"]
như? Chuỗi {return version} return "Số phiên bản không khả dụng"}
class var applicationBuildNumber: String { if let build = NSBundle.mainBundle().infoDictionary?["CFBundleVersion"] as? String { return build } return "Build Number Not Available" } }
Vì vậy, bây giờ bạn có thể truy cập dễ dàng bằng cách:
let versionNumber = NSBundle.applicationVersionNumber
Tôi cũng biết điều này đã được trả lời nhưng tôi đã kết thúc các câu trả lời trước:
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")"
}
}
Sử dụng:
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
}
Đối với phiên bản cũ hơn :
class func getVersion() -> String {
if let version = NSBundle.mainBundle().infoDictionary?["CFBundleShortVersionString"] as? String {
return version
}
return "no version info"
}
Vì vậy, nếu bạn muốn đặt văn bản nhãn hoặc muốn sử dụng ở một nơi khác;
self.labelVersion.text = getVersion()
Dành cho Swift 4.0
let version = Bundle.main.infoDictionary!["CFBundleShortVersionString"]!
let build = Bundle.main.infoDictionary!["CFBundleVersion"]!
Tôi đã thực hiện Gia hạn trên Gói
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
}
}
và sau đó sử dụng nó
versionLabel.text = "\(Bundle.main.appName) v \(Bundle.main.versionNumber) (Build \(Bundle.main.buildNumber))"
Đối với Swift 3.0 NSBundle không hoạt động, Mã sau hoạt động hoàn hảo.
let versionNumberString =
Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString")
as! String
và chỉ cho số bản dựng, đó là:
let buildNumberString =
Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion")
as! String
Một cách khó hiểu 'CFBundleVersion' là số bản dựng được nhập trong Xcode trên Chung-> Danh tính.
Xcode 9.4.1 Swift 4.1
Lưu ý việc sử dụng localizedInfoDipedia để chọn đúng phiên bản ngôn ngữ của tên hiển thị gói.
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, tiện ích mở rộng hữu ích cho gói
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))"
}
}
Gói + Tiện ích mở rộng.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
}
}
Sử dụng:
someLabel.text = Bundle.main.versionNumber
OP yêu cầu cả số phiên bản và số bản dựng. Thật không may, hầu hết các câu trả lời không cung cấp cả hai tùy chọn đó. Ngoài ra, những người khác thêm các phương thức mở rộng không cần thiết. Đây là một điều khá đơn giản và giải quyết vấn đề của 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 ""
}
}
Câu trả lời của tôi (vào tháng 8 năm 2015), đưa ra Swift tiếp tục phát triển:
let version = NSBundle.mainBundle().infoDictionary!["CFBundleVersion"] as! String
Tôi đã tạo một phần mở rộng cho 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"
}
}
Đã xem tài liệu, tôi tin rằng những điều sau đây là sạch hơn:
let version =
NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleShortVersionString")
as? String
Nguồn : "Sử dụng phương thức này được ưa thích hơn các phương thức truy cập khác vì nó trả về giá trị cục bộ của khóa khi có sẵn."
Đối với Swift 1.2, đó là:
let version = NSBundle.mainBundle().infoDictionary!["CFBundleShortVersionString"] as! String
let build = NSBundle.mainBundle().infoDictionary!["CFBundleVersion"] as! String
Swift 3:
Số phiên bản
if let versionNumberString = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String { // do something }
Xây dựng số
if let buildNumberString = Bundle.main.infoDictionary?["CFBundleVersion"] as? String { // do something }
Swift 4
func getAppVersion() -> String {
return "\(Bundle.main.infoDictionary!["CFBundleShortVersionString"] ?? "")"
}
Bundle.main.info Từ điển! ["CFBundleShortVersionString"]
Cú pháp cũ
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
}
}
Chú ý: Bạn nên sử dụng nếu để ở đây trong trường hợp phiên bản ứng dụng hoặc bản dựng không được đặt sẽ dẫn đến sự cố nếu bạn cố gắng sử dụng! để mở khóa
Đây là phiên bản cập nhật cho 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
}
}
Chuyển 4
// Trước tiên hãy lấy nsObject bằng cách định nghĩa là AnyObject tùy chọn
let nsObject: AnyObject? = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as AnyObject
// Sau đó, chỉ cần truyền đối tượng dưới dạng Chuỗi, nhưng hãy cẩn thận, bạn có thể muốn kiểm tra hai lần cho nil
let version = nsObject as! String
Đối với bất kỳ ai quan tâm, có một thư viện đẹp và gọn gàng được gọi là SwifterSwift
có sẵn tại github và cũng được ghi lại đầy đủ cho mọi phiên bản của swift (xem swifterswift.com ).
sử dụng thư viện này, đọc phiên bản ứng dụng và số bản dựng sẽ dễ dàng như sau:
import SwifterSwift
let buildNumber = SwifterSwift.appBuild
let version = SwifterSwift.appVersion
đây là một chức năng tôi đang sử dụng để quyết định có hiển thị trang "ứng dụng được cập nhật" hay không. Nó trả về số bản dựng mà tôi đang chuyển đổi thành 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")
}
Nếu không bao giờ được sử dụng trước nó sẽ trả về 0 thấp hơn số bản dựng hiện tại. Để không hiển thị màn hình như vậy cho người dùng mới, chỉ cần thêm số bản dựng sau lần đăng nhập đầu tiên hoặc khi lên máy bay hoàn tất.
Chức năng tiện ích đơn giản để trả về phiên bản Ứng dụng là 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
}
Gói + Tiện ích mở rộng.swift (SwiftUI, Swift 5, Xcode 11)
Tôi đã kết hợp các ý tưởng từ một vài câu trả lời và mở rộng thêm một chút:
Quỹ nhập khẩu
gói mở rộng {
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 "⚠️"
}
}
}
Sử dụng ví dụ 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)"
}