[英]Swift Package Manager - Setting Custom Classes in storyboard in package fails
I am trying to implement a support for Swift Package Manager for an iOS framework that we used to link in our main project with Carthage.我正在尝试为 iOS 框架实现对 Swift Package 管理器的支持,该框架用于在我们的主项目中与 Carthage 链接。 The framework's name is "OptionsSheetKit"该框架的名称是“OptionsSheetKit”
The framework contained a UIViewController
that is a replica of UIAlertController
with the .sheet
appearance, and a storyboard that has the view controller's design.该框架包含一个UIViewController
,它是具有.sheet
外观的UIAlertController
的副本,以及一个具有视图控制器设计的 storyboard。
When i make an instance of the view controller from within the framework like this:当我从这样的框架内创建视图 controller 的实例时:
let content = UIStoryboard(name: "OptionsSheet", bundle: .module).instantiateViewController(withIdentifier: PickerViewController.identifier) as? PickerViewController
The app compiles and runs however all custom set classes are no longer set and i get this warning in the debug area of XCode:该应用程序编译并运行,但是不再设置所有自定义集类,我在 XCode 的调试区域收到此警告:
2021-02-23 17:19:15.606835+0200 OptionsSheetKitExample[23732:6479875] [Storyboard] Unknown class _TtC31OptionsSheetKit_OptionsSheetKit19SheetViewController in Interface Builder file.
2021-02-23 17:19:15.607631+0200 OptionsSheetKitExample[23732:6479875] [Storyboard] Unknown class _TtC31OptionsSheetKit_OptionsSheetKit19SheetViewController in Interface Builder file.
2021-02-23 17:19:15.608020+0200 OptionsSheetKitExample[23732:6479875] [Storyboard] Unknown class _TtC31OptionsSheetKit_OptionsSheetKit19SheetViewController in Interface Builder file.
2021-02-23 17:19:15.608378+0200 OptionsSheetKitExample[23732:6479875] [Storyboard] Unknown class _TtC31OptionsSheetKit_OptionsSheetKit19SheetViewController in Interface Builder file.
2021-02-23 17:19:15.608776+0200 OptionsSheetKitExample[23732:6479875] [Storyboard] Unknown class _TtC31OptionsSheetKit_OptionsSheetKit19SheetViewController in Interface Builder file.
My Package.swift
looks like this:我的Package.swift
看起来像这样:
// swift-tools-version:5.3
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "OptionsSheetKit",
platforms: [
.iOS(.v12)
],
products: [
// Products define the executables and libraries a package produces, and make them visible to other packages.
.library(
name: "OptionsSheetKit",
targets: ["OptionsSheetKit"]),
],
dependencies: [
// Dependencies declare other packages that this package depends on.
// .package(url: /* package url */, from: "1.0.0"),
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages this package depends on.
.target(
name: "OptionsSheetKit",
dependencies: []),
]
)
This is how the class is set in the storyboard, but it fails to find it. storyboard中的class是这样设置的,但是找不到。
Maybe it fails to get the module right.也许它无法使模块正确。
I know that for SwiftPM .storyboard
is a known file, and it automatically makes a resource bundle for the package, and i can see that resource bundle in the app's main bundle with file name OptionsSheetKit_OptionsSheetKit.bundle
, i know its bundle identifier has to be OptionsSheetKit-OptionsSheetKit-resources
, so its all in there.我知道对于 SwiftPM .storyboard
是一个已知文件,它会自动为 package 创建一个资源包,我可以在应用程序的主包中看到该资源包,文件名为OptionsSheetKit_OptionsSheetKit.bundle
,我知道它的包标识符为OptionsSheetKit-OptionsSheetKit-resources
,所以它都在那里。
The only way i managed to make it work is by instantiating the ViewController with the iOS 13+ method UIStoryboard.instantiateViewController(identifier: String, creator: NSCoder)
but its a workaround which as i had to do that not only for the view controller, but for each and every custom class i have set inside the controller's views, which makes the storyboard pointless.我设法使其工作的唯一方法是使用 iOS 13+ 方法UIStoryboard.instantiateViewController(identifier: String, creator: NSCoder)
实例化 ViewController,但它是一种解决方法,因为我不仅要为视图 controller 这样做,但是对于我在控制器视图中设置的每个自定义 class,这使得 storyboard 毫无意义。
Whats' more is that the app's min deployment target is iOS 12.2, so this will not cut it for me.更重要的是该应用程序的最小部署目标是 iOS 12.2,所以这对我来说不会削减。
Do you guys have an idea why this fails?你们知道为什么会失败吗? I tried setting the type
parameter in the library's product to .dynamic
as i know dynamic frameworks can have resources in their bundles, as i did that before, tried the .static
type too, but couldn't make it work either way.我尝试将库产品中的type
参数设置为.dynamic
,因为我知道动态框架可以在它们的包中包含资源,就像我之前所做的那样,也尝试了.static
类型,但无法使其工作。
Is this a known bug, or simply SwiftPM still does not support this?这是一个已知的错误,还是 SwiftPM 仍然不支持这个?
Thanks in advance!提前致谢!
I managed to fix it by adding @objc
name in my view controller's class definition and use that name instead in the storyboard.我设法通过在我的视图控制器的 class 定义中添加@objc
名称来修复它,并在 storyboard 中使用该名称。
@objc(OBJCPickerViewController)
public final class PickerViewController { ... }
Thats how i used the OBJCPickerViewController
name inside the storyboard这就是我在 storyboard 中使用OBJCPickerViewController
名称的方式
And all worked nice.一切都很好。 I think the reason this works is because in Objective C there are no modules( thats why @objc
classes have prefixes in their names ) and with @objc
you are basically bypassing the class/module name mangling, making it really easy for storyboards to find your class.我认为这行得通的原因是因为在Objective C 中没有模块(这就是为什么@objc
类的名称中有前缀)并且使用@objc
你基本上绕过了类/模块名称修改,使得故事板很容易找到你的 class。
I found out the solution here , so shout out to Marius Ilie for writing this down!我在这里找到了解决方案,因此请向 Marius Ilie 大声疾呼写下这篇文章!
If any of you could propose a more elegant solution, please let me know so we could stop relying on objc to save us in our swift code.如果你们中的任何人可以提出更优雅的解决方案,请告诉我,这样我们就可以停止依赖 objc 来将我们保存在我们的 swift 代码中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.