获取Bundle信息
获取Bundle中的信息,一个做法是读取info.plist文件,将读到的数据转成json来获取
swift
var config: [String: Any]?
if let infoPlistPath = Bundle.main.url(forResource: "Info", withExtension: "plist") {
do {
let infoPlistData = try Data(contentsOf: infoPlistPath)
if let dict = try PropertyListSerialization.propertyList(from: infoPlistData, options: [], format: nil) as? [String: Any] {
config = dict
}
} catch {
print(error)
}
}
使用PropertyListSerialization.propertyList
将infoPlistData转成dict,整个获取的过程比较原始,其实Apple有提供一些API直接获取
swift
print(Bundle.main.object(forInfoDictionaryKey: "CFBundleName")!)
print(Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion")!)
print(Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString")!)
object
是Bundle实例上的方法,forInfoDictionaryKey
指定的key对应的value,整个使用体验比上一份读取info文件要好太多了。可以给Bundle添加extension,更方便调用
swift
extension Bundle {
var appName: String? {
return object(forInfoDictionaryKey: "CFBundleName") as? String
}
var appVersion: String? {
return object(forInfoDictionaryKey: "CFBundleVersion") as? String
}
var buildNumber: String? {
return object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String
}
}
美滋滋啊......
而且object的API还比直接读取plist文件多一个功能,就是在有国际化的时候,object能直接获取到本地文件资源,可以自己试一下。
获取RootViewController
在iOS13之前,可以这样直接获取keyWindow和 root viewController UIApplication.shared.keyWindow?.rootViewController
但是iOS13支持了多视窗(multiple scenes),iOS15中UIApplication.shared.keyWindow?就要不支持了,所以iOS13之后,获取keyWindow的写法有些调整
swift
extension UIApplication {
var firstKeyWindow: UIWindow? {
let windowScenes = UIApplication.shared.connectedScenes.compactMap{$0 as? UIWindowScene}
let activeScene = windowScenes.filter { $0.activationState == .foregroundActive }
let firstActiveScene = activeScene.first
let keyWindow = firstActiveScene?.keyWindow
return keyWindow
}
}
UIApplication.shared.connectedScenes
获取到所有视窗,并通过compactMap转成UIWindowScene对象- Multiple Windows意味着会获取到不止一个active scene,默认获取到所有activeScene的第一个
- 从active scene对象上获取keyWindow对象返回
之后可以用这个extension的firstKeyWindow获取rootViewController(有点像iOS13之前的用法了) let vc = UIApplication.shared.firstKeyWindow?.rootViewController
UIWindowScene.keyWindow
到iOS15才支持,iOS13中需要我们自己手动过滤下keyWindow的筛选,代码改动如下(更紧凑些):
swift
var firstKeyWindow: UIWindow? {
return UIApplication.shared.connectedScenes
.compactMap { $0 as? UIWindowScene }
.filter { $0.activationState == .foregroundActive }
.first?.windows
.first(where: \.isKeyWindow)
}
使用了 window.first(where: \.isKeyWindow)
来获取keywindow,它是UIWindow的一个属性