我正在尝试在您的一个具有故事板的项目中添加对SPM的支持。
目前我们抓住它的UIStoryboard(name: String, bundle: String?)
,但这似乎不适用于扫描探针显微镜,因为没有真正的捆绑。即使打印所有包,也不能显示包的包。
我们有没有办法支持故事板,或者SPM仅仅是文件?
尝试:
UIStoryboard(name: "GiftCards", bundle: Bundle(for: self))
UIStoryboard(name: "GiftCards", bundle: Bundle(for: type(of: self)))
UIStoryboard(name: "GiftCards", bundle: Bundle(identifier: "com.x.x"))
发布于 2020-09-22 08:39:42
从Xcode12.0开始,这种方式可以正常工作,但是需要一些额外的步骤才能完成。
场景:
Swift
BadgeKit.storyboard
的包中嵌入的序列图像板
BadgeKit
Package.swift
header // swift-tools-version:5.3
或更高版本的目标:
中工作
步骤:
将序列图像板引用添加到应用程序序列图像板,并按如下方式进行配置:
具有序列图板值BadgeKit
和束标识符BadgeKit-BadgeKit-resources
的序列图板引用属性面板。
Xcode使用以下格式自动生成一个包(及其标识符),用于保存在SPM包中找到的资源:[package name]-[package target name]-resources
。在我们的例子中,包名和目标名是相同的(BadgeKit
)。
虽然SPM资源包总是在构建过程中创建并包含在应用程序中,但它们不会在运行时在包之外自动可用。如果你没有在代码中的任何地方导入和使用包的目标,Xcode会试图通过不加载包的资源包来进行优化(这可能是Apple的一个疏忽,仅仅是故事板引用不足以触发这一点)。因此,如果您只在故事板中使用SPM包的资源,则需要一个变通方法来诱使Xcode使SPM包的包可用。
将此代码添加到应用程序的AppDelegate.swift
文件中作为解决方法:
@UIApplicationMain final class AppDelegate: UIResponder {
[…]
override init() {
super.init()
// WORKAROUND: Storyboards do not trigger the loading of resource bundles in Swift Packages.
let bundleNames = ["BadgeKit_BadgeKit"]
bundleNames.forEach { (bundleName) in
guard
let bundleURL = Bundle.main.url(forResource: bundleName, withExtension: "bundle"),
let bundle = Bundle(url: bundleURL) else {
preconditionFailure()
}
bundle.load()
}
[…]
}
[…]
}
在我们的示例中,数组bundleNames
包含一个字符串,该字符串对应于我们的包将在构建过程中为其资源创建的包的预期文件名。Xcode自动命名这些包文件,如下所示:[package name]_[package target name].bundle
。请注意,包的文件名与其标识符不同。
如果您对哪些包(及其对应的标识符)在运行时加载并可用感到好奇,您可以使用以下代码进行故障排除:
let bundles = Bundle.allBundles
bundles.forEach { (bundle) in
print("Bundle identifier loaded: \(bundle.bundleIdentifier)") }
}
在SPM BadgeKit包中配置序列图像板:
使用SPM包目标名称("BadgeKit")
填充“模块”。
发布于 2021-01-20 08:33:45
关键是在实例化情节提要时使用Bundle.module
1-将此视图控制器扩展添加到swift包中:
public extension UIViewController{
public static func getStoryboardVC() -> UIViewController {
let storyboard = UIStoryboard(name: String(describing: self), bundle: Bundle.module) // Use Bundle.module
return storyboard.instantiateInitialViewController()!
}
}
Bundle.module表示包含的包。
2-在应用程序中,在我的例子中,swift包被称为MySwiftPackage。我从swift包中调用扩展方法来实例化我想要呈现的视图控制器:
@IBAction func openCard(){
let vc = MySwiftPackage.MyViewController.getStoryboardVC() as! MySwiftPackage.MyViewController
vc.personNo = "11111"
vc.personId = "8888888"
present(vc, animated: true, completion: nil)
}
https://stackoverflow.com/questions/58000140
复制