【问题标题】:How to incorporate Framework SwiftUI如何合并框架 SwiftUI
【发布时间】:2019-10-22 10:26:54
【问题描述】:

我们只能从 iOS 13.0+ 使用 Framework SwiftUI。那么如何从部署 Target 10.0 或至少 12.0 中合并这个框架。

【问题讨论】:

  • 你第一句话不是基本回答了第二句话吗?
  • @maddy,不,应该有办法。 #available 13.0 之类的东西
  • 如果您的应用在 iOS 12 设备上运行,您打算如何使用由 SwiftUI 制作的 UI?既然不能,您是否打算为您的应用程序编写两个完全独立的 UI?一个在 UIKit 中,一个在 SwiftUI 中?这是一个痛苦的计划。

标签: ios swift xcode swiftui


【解决方案1】:

虽然@DenFav 是绝对正确的 - 使用 SwiftUI 支持 iOS 13 以下的部署目标很痛苦,但这是可能的。

步骤:

  1. 弱链接框架(我用过这个answer):

    将 -weak_framework SwiftUI 添加到其他链接器标志解决了我的问题

  2. 使用 canImport 包装所有 SwiftUI 调用(请参阅 answer):

    #if canImport(SwiftUI) && canImport(Combine)

这将允许您使用部署目标

可选:

现在的问题是:如何处理视图模型。我用自己的实现解决了这个问题。您可以在Ruuvi Station的public repo查看解决方案。注意:代码很复杂(VIPER),这就是为什么我将简要描述主要思想。

viewModel 实现在Classes/Presentation/Binding

我正在使用这些 viewModel,wrapping 它们和 ObservableObject 用于 SwiftUI。

您仍然可以在observe 中对SwiftUI code 进行更改。

结果是:iOS 13 使用SwiftUI code 作为表示层,而 iOS 12 及更低版本使用传统的UIKit code

如果可以使用 SwiftUI 代码,viewController 负责determining

【讨论】:

  • 尝试这个后,它将编译并能够在模拟器上执行。但是存档失败:(
  • 我还尝试了上述方法加上@available(iOS 13.0, iOSApplicationExtension 13.0, *),并在尝试存档时收到以下错误消息:Use of undeclared type 'View'Use of undeclared type 'AnyView' 等。几乎所有来自 SwiftUI 的东西。有什么想法吗?
  • 经过数小时的研究和设置调整,我终于让它工作了。事实证明,我的 iOS 部署目标设置为 10.0,但上述建议适用于 11.0 及更高版本。因此,对于那些尽管有建议仍无法使其工作的人,请检查您的 iOS 部署目标
【解决方案2】:

构建阶段 → 将二进制文件与库链接 → 添加 SwiftUI.framework(状态:可选)

import SwiftUI

@available(iOS 13.0, *)
struct SwiftUIView : View {
    var body: some View {
        Text("Hello World!")
    }
}

@available(iOS 13.0, *)
struct SwiftUIView_Previews : PreviewProvider {
    static var previews: some View {
        SwiftUIView()
    }
}

等等。

此目标的 SwiftUI 预览不起作用,但您可以添加一个特殊目标“SwiftUI 预览”。

【讨论】:

  • 这似乎不起作用。我有一个针对 iOS 11 的 iOS 项目,但我想围绕 SwiftUI 构建并重新构建我的 UIKit 视图之一,仅使其可供 iOS 13 用户使用。我尝试使用这种方法,但遇到了一些错误。你曾经能够让它工作吗?
  • @MikeG,这适用于我当前针对 iOS 12 的 iOS 项目。你遇到了什么错误?
  • 4 个不同的错误 1) Inheritance from non-protocol type 'View' 2) Function declares an opaque return type, but has no return statements in its body from which to infer an underlying type 3) Cannot convert return expression of type 'Text' to return type 'some View 4) Type 'SwiftUIView_Previews' does not conform to protocol 'PreviewProvider
  • @MikeG,我再次检查了一个针对 iOS 11 的新项目。它工作正常,我没有这样的错误。您是否为项目中的所有视图和预览提供程序添加了@available(iOS 13.0, *)?
  • 感谢您的检查。我所做的只是添加一个新文件,复制粘贴上面的代码,然后将SwiftUI.framework (Status: Optional) 添加到构建阶段“将二进制文件与库链接”部分。我的应用程序中有很多其他视图,但这些都是 UIViewUIKit 构建的,不需要任何更改。我的应用中没有其他预览提供程序。
【解决方案3】:

没有合理的方法可以做到这一点。 #available 或 @available 允许您区分某些代码或整个类,但不能区分应用程序本身。

您可以使用 @available 来消除 SwiftUI 结构或具有 12.0 部署目标的类的警告,但在这种情况下,您需要使用 Swift UI 从故事板(.xib 等)完全复制 UI。此外,完全不同的“绑定”方法还需要您在该应用程序中重新实现现有逻辑(与您以前使用过哪种架构无关)。任何 VIPER、VIP、MVC 都旨在向 ViewController(View) 发送一些数据更改通知?在 Swift UI 中,您需要使用 Bindable 对象。它还会导致您创建 ViewModel 的副本(如果有的话),因为它们会有所不同。

结果?你有 UI 的第二个实现,视图模型的第二个实现,另外 80% 的 Presenter 实现(或者你用什么)。只有数据库和休息管理器将被重用。如果你有非常好的架构,这是有效的。不要忘记你需要支持 UI 和逻辑的两个分支。

有两种方法:重新开发几乎完整的应用程序以支持 SwiftUI 和 UIKit,或者,如果您不想只支持一个 iOS 13,请等到 iOS 14 发布,然后用 SwiftUI 支持它们。

【讨论】:

  • 等待一年有什么用?
  • @maddy,我的意思是,在 iOS 14 发布之后,您将能够支持 iOS 13-14。目前你只能使用 SwiftUI 支持 iOS 13
  • 所以这仍然意味着 iOS 13 的部署目标。这意味着只有一种方式,而不是两种方式。
猜你喜欢
  • 2020-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-22
  • 2014-06-11
  • 2014-08-02
  • 2021-11-08
  • 1970-01-01
相关资源
最近更新 更多