Làm cách nào để có phiên bản Ứng dụng và số bản dựng bằng Swift?


387

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?



6
Đó là Objective-C, không phải Swift.
yvind Vik

10
Hãy chắc chắn không nhầm lẫn CFBundleVersion& CFBundleShortVersionString`. Đầu tiên là phiên bản xây dựng của bạn . Cái khác là số phiên bản . Xem tại đây để biết thêm
Honey

1
@ YvindVik Hầu hết mọi người đều cho rằng bạn có thể dịch giải pháp Objective-C sang Swift mà không cần cầm tay.
gnasher729

Câu trả lời:


424

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


Khi tôi sử dụng điều này, tôi gặp lỗi trình biên dịch "[NSObject: AnyObject]? Không có thành viên có tên 'subscript'"
andreas

Bạn có thể thử thay thế AnyObject? bởi AnyObject! mà không biết chính xác mã bạn đang sử dụng thì rất khó đoán được lỗi là gì, hãy nhớ rằng Swift có thể thay đổi từ bản phát hành Xcode này sang bản phát hành Xcode khác, do đó, cũng sẽ có liên quan để biết phiên bản Xcode của bạn.
David

18
@andreas infoDictionarynê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
azdev

1
Tôi đã phải thêm một "!" sau "như". let appVersion = NSBundle.mainBundle().infoDictionary!["CFBundleVersion"] as! String
yosei

3
Bạn nên tránh sử dụng một unrap cưỡng bức "!" vì chúng sẽ khiến ứng dụng của bạn bị sập bất cứ khi nào một trong những giá trị đó là không
Julius

279

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.


6
self.labelVersion.textlà loại Tùy chọn, vì vậy bạn có thể chỉ định trực tiếpNSBundle.mainBundle().infoDictionary?["CFBundleShortVersionString"] as? String
Jonauz

8
Có một lý do giá trị sẽ không được thiết lập? Đồng ý rằng nó chắc chắn thận trọng hơn let, chỉ tự hỏi tại sao nó có thể cần thiết. Cảm ơn!
Crashalot

@Crashalot mặc dù tên của bạn;) bạn không muốn ứng dụng của mình bị sập nếu, giả sử, bạn mắc lỗi đánh máy, thay vào đó là số phiên bản là "đã xảy ra lỗi".
Daniel Springer

OP: bạn có thể thay thế? với ! và xóa "dưới dạng Chuỗi". Nếu không, dù sao đi nữa, nó sẽ không sụp đổ
Daniel Springer

245

Đã 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

CFBundleVersionKey không còn hoạt động trong Swift 3, Xcode 8. Bạn có biết khóa mới để sử dụng không?
Crashalot

71

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:

(*) Đã cập nhật cho tiện ích mở rộng

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

@Deprecated: Câu trả lời cũ

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

1
hoặc: class func getVersion () -> String {return NSBundle.mainBundle (). infoDixi? ["CFBundleShortVersionString"] là? Chuỗi ?? "không có thông tin phiên bản"}
tapmonkey

Tôi nghĩ rằng sao chép các câu trả lời khác không có ý nghĩa. Nếu câu trả lời của bạn không còn giá trị nữa thì bạn luôn có khả năng xóa nó và nhường chỗ cho các câu trả lời khác :)
carmen_munich

1
@carmen_munich Vì bạn nói xấu ở đây nên tôi phải trả lời bạn. Trước hết, câu trả lời này được đăng vào tháng 3 năm 2015 và câu trả lời của bạn được đăng vào tháng 2 năm 2017. Do đó, cảm hứng của bạn phải đến từ những câu trả lời trước đó. Thứ hai, tôi chưa thấy câu trả lời của bạn, tôi đã cập nhật câu trả lời của mình vì ngày nay tôi sử dụng nó theo cách này. Tôi đoán sử dụng tiện ích mở rộng không phải là duy nhất đối với một người nào đó trong cộng đồng iOS. Thực sự, hãy cố gắng trưởng thành và tôn trọng các nhà phát triển khác. Tôi không đạt được bất cứ điều gì đăng ở đây. Tôi muốn giúp mọi người. Hãy cố gắng đừng làm nản lòng mọi người đang cố gắng giúp đỡ về SO.
Gunhan

Tôi đã nghe rất nhiều phản hồi từ người mới rằng họ đăng câu trả lời và muốn thấy ai đó nhấp vào "lên", điều này thực sự tốt để xem và thúc đẩy mọi người. Nhưng nếu ai đó sao chép câu trả lời trong câu trả lời lỗi thời của mình, người đã nỗ lực đăng nó sẽ không có được động lực mà ai đó đã bình chọn. Vì vậy, những người mới thực sự cảm thấy thất vọng và có cảm giác rằng họ không mang lại giá trị cho cộng đồng và ngừng đăng. Và đừng hiểu lầm, ý tôi là nói chung. Hy vọng bạn không cảm thấy bị xúc phạm và hiểu rõ hơn tại sao tôi đưa ra đề nghị này.
carmen_munich

@carmen_munich Nếu bạn sắp xếp theo thứ tự thời gian các câu trả lời cho câu hỏi này, bạn sẽ nhận thấy rằng người khác đã đưa ra câu trả lời giống như bạn đã làm trước bạn! Vì vậy, bạn đang đổ lỗi cho tôi một cái gì đó mà bạn đã tự làm. Vì tôi có lịch sử cho câu hỏi này, tôi đã chia sẻ tùy chọn sử dụng mới của mình trong một bản cập nhật. Đó là tất cả.
Gunhan

32

Dành cho Swift 4.0

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

29

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

Thật ra nó hơi khác. Tôi sử dụng vũ lực unrapping chẳng hạn. Bạn có thể nghĩ rằng lực lượng unrapping nói chung là xấu, đây là một trong những trường hợp hiếm hoi mà nó ổn. Để giải thích thêm một chút, các giá trị này phải có trong từ điển nếu không có gì đó thực sự sai với tệp dự án. Đó là lý do tại sao phương pháp này đang sử dụng vũ lực
hủy kết nối

Đổi tên và buộc hủy bỏ không phải là một thay đổi để đăng như một câu trả lời mới. Ngoài ra, mọi người có thể học cách hủy bỏ lực lượng có thể được sử dụng ở bất cứ đâu khi họ thấy câu trả lời của bạn. Đối với độc giả, đừng cho rằng chìa khóa ở đó, tốt hơn hết là xử lý việc hủy ghép tùy chọn theo cách thủ công thay vì ép buộc.
Gunhan

Để công bằng, có một số trường hợp hiếm hoi mà lực lượng unrapping là ổn. Bài đăng này chỉ cho thấy một trường hợp có thể ổn. Nếu bạn muốn biết thêm về các trường hợp hủy bỏ lực lượng, có một số giải thích và hướng dẫn tốt từ Paul Hudson. Tôi thực sự có thể giới thiệu cho tất cả người mới www.hackingwithswift.com
carmen_munich

Đó là một đề nghị tốt cho người mới. Có lẽ bạn cũng có thể đọc thêm và tìm hiểu thêm. Ngoài ra, bạn nên cải thiện sự hiểu biết của bạn về ý kiến ​​và những gì họ ngụ ý. Ví dụ, không ai nói với bạn rằng bạn không bao giờ / không bao giờ sử dụng vũ lực. Nhưng đối với thông tin ra lệnh, các khóa đó có thể bị xóa và lực không mở có thể dẫn đến sự cố. Nó là an toàn hơn để xử lý unrapping ở đây.
Gunhan

Có lẽ bạn có thể giải thích trong trường hợp nào họ có thể được gỡ bỏ và không? Những gì tôi học được từ tài nguyên được đề cập không phải trong trường hợp partiuclare này. Họ phải luôn ở đó trừ khi tệp dự án bị hỏng, trong trường hợp đó, dự án có thể sẽ không được biên dịch
carmen_munich

16

Đố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.


16

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

14

Xcode 8, Swift 3:

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

13

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

Để sử dụng điều này, bạn cần nói Bundle.main.fullVersion chẳng hạn
Joseph Astrahan

12

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

11

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

9

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

8

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

6

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


1
Đó là cách Swift đúng đắn, không ép buộc, ở bất cứ đâu
Juan Boero

5

Đối với Swift 1.2, đó là:

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

1
bạn đã có thể sử dụng ? cũng như
Dan Rosenstark 16/07/2015

4

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 }

Làm thế nào về số lượng xây dựng? Cảm ơn! CFBundleVersionKey không hoạt động.
Crashalot

@Crashalot Tôi cũng cập nhật nó với số bản dựng. Đây cũng là danh sách của tất cả các Khóa nền tảng cốt lõi: developer.apple.com/l
Library / content / document / General / Lỗi

3

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

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
    }

}

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


2

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

2

Bây giờ bạn có thể sử dụng một hằng số cho việc này, thay vì phải sử dụng mã được gõ theo chuỗi như trước đây, điều này làm cho mọi thứ trở nên thuận tiện hơn.

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

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

1

Đố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à SwifterSwiftcó 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

1

Cập nhật cho Swift 5

đâ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.


1

Dành cho Swift 5.0 :

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

1

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
    }

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

1

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:

  • một ví dụ SwiftUI
  • Hiển thị biểu tượng cảm xúc tam giác cảnh báo (thay vì làm hỏng ứng dụng) nếu thiếu khóa từ Info.plist

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

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

    }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.