iOS 框架的路径
Path to bundle of iOS framework
我正在为 iOS 开发一个框架,它带有一些数据文件。要将它们加载到 Dictionary
中,我会这样做:
public func loadPListFromBundle(filename: String, type: String) -> [String : AnyObject]? {
guard
let bundle = Bundle(for: "com.myframework")
let path = bundle.main.path(forResource: filename, ofType: type),
let plistDict = NSDictionary(contentsOfFile: path) as? [String : AnyObject]
else {
print("plist not found")
return nil
}
return plistDict
}
如果我在带有框架的游乐场中使用它,它会按预期工作。
但是如果我使用嵌入在应用程序中的框架,它就不再起作用了,"path" 现在指向应用程序的包,而不是框架的包。
如何确保访问框架的包?
编辑:上面的代码驻留在框架中,而不是在应用程序中。
EDIT2: 上面的代码是实用函数,不是结构或 class.
的一部分
尝试以下代码获取自定义包:
let bundlePath = Bundle.main.path(forResource: "CustomBunlde", ofType: "bundle")
let resourceBundle = Bundle.init(path: bundlePath!)
更新
如果在你的框架中,试试这个:
[[NSBundle bundleForClass:[YourClass class]] URLForResource:@"YourResourceName" withExtension:@".suffixName"];
使用Bundle(for:Type)
:
let bundle = Bundle(for: type(of: self))
let path = bundle.path(forResource: filename, ofType: type)
或通过 identifier
(框架包 ID)搜索包:
let bundle = Bundle(identifier: "com.myframework")
只需指定资源的 class 名称,下面的函数将为您提供与 class 关联的 Bundle 对象,因此如果 class 与框架关联它将提供框架包。
let bundle = Bundle(for: <YourClassName>.self)
Swift 5
let bundle = Bundle(for: Self.self)
let path = bundle.path(forResource: "filename", ofType: ".plist")
import class Foundation.Bundle
private class BundleFinder {}
extension Foundation.Bundle {
/// Returns the resource bundle associated with the current Swift module.
static var module: Bundle = {
let bundleName = "ID3TagEditor_ID3TagEditorTests"
let candidates = [
// Bundle should be present here when the package is linked into an App.
Bundle.main.resourceURL,
// Bundle should be present here when the package is linked into a framework.
Bundle(for: BundleFinder.self).resourceURL,
// For command-line tools.
Bundle.main.bundleURL,
]
for candidate in candidates {
let bundlePath = candidate?.appendingPathComponent(bundleName + ".bundle")
if let bundle = bundlePath.flatMap(Bundle.init(url:)) {
return bundle
}
}
fatalError("unable to find bundle named ID3TagEditor_ID3TagEditorTests")
}()
}
发件人:Source
---更新---
它提供了 3 种关于如何获得正确的包的大多数注释用法,这非常有用,特别是当您开发自己的框架或使用 Cocoapods 时。
我正在为 iOS 开发一个框架,它带有一些数据文件。要将它们加载到 Dictionary
中,我会这样做:
public func loadPListFromBundle(filename: String, type: String) -> [String : AnyObject]? {
guard
let bundle = Bundle(for: "com.myframework")
let path = bundle.main.path(forResource: filename, ofType: type),
let plistDict = NSDictionary(contentsOfFile: path) as? [String : AnyObject]
else {
print("plist not found")
return nil
}
return plistDict
}
如果我在带有框架的游乐场中使用它,它会按预期工作。
但是如果我使用嵌入在应用程序中的框架,它就不再起作用了,"path" 现在指向应用程序的包,而不是框架的包。
如何确保访问框架的包?
编辑:上面的代码驻留在框架中,而不是在应用程序中。
EDIT2: 上面的代码是实用函数,不是结构或 class.
的一部分尝试以下代码获取自定义包:
let bundlePath = Bundle.main.path(forResource: "CustomBunlde", ofType: "bundle")
let resourceBundle = Bundle.init(path: bundlePath!)
更新
如果在你的框架中,试试这个:
[[NSBundle bundleForClass:[YourClass class]] URLForResource:@"YourResourceName" withExtension:@".suffixName"];
使用Bundle(for:Type)
:
let bundle = Bundle(for: type(of: self))
let path = bundle.path(forResource: filename, ofType: type)
或通过 identifier
(框架包 ID)搜索包:
let bundle = Bundle(identifier: "com.myframework")
只需指定资源的 class 名称,下面的函数将为您提供与 class 关联的 Bundle 对象,因此如果 class 与框架关联它将提供框架包。
let bundle = Bundle(for: <YourClassName>.self)
Swift 5
let bundle = Bundle(for: Self.self)
let path = bundle.path(forResource: "filename", ofType: ".plist")
import class Foundation.Bundle
private class BundleFinder {}
extension Foundation.Bundle {
/// Returns the resource bundle associated with the current Swift module.
static var module: Bundle = {
let bundleName = "ID3TagEditor_ID3TagEditorTests"
let candidates = [
// Bundle should be present here when the package is linked into an App.
Bundle.main.resourceURL,
// Bundle should be present here when the package is linked into a framework.
Bundle(for: BundleFinder.self).resourceURL,
// For command-line tools.
Bundle.main.bundleURL,
]
for candidate in candidates {
let bundlePath = candidate?.appendingPathComponent(bundleName + ".bundle")
if let bundle = bundlePath.flatMap(Bundle.init(url:)) {
return bundle
}
}
fatalError("unable to find bundle named ID3TagEditor_ID3TagEditorTests")
}()
}
发件人:Source
---更新---
它提供了 3 种关于如何获得正确的包的大多数注释用法,这非常有用,特别是当您开发自己的框架或使用 Cocoapods 时。