You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Mac Catalyst的UIKit应用中使用macOS专属SwiftUI视图?

解决方案:Mac Catalyst应用中集成macOS专属LocalAuthenticationView

一、解决SwiftUI视图类型不兼容问题

你碰到的Type 'any View' cannot conform to 'View'错误,核心原因是SwiftUI的View属于关联类型协议,any View作为存在类型无法直接被UIHostingController接收(该控制器要求传入具体的View实现类型)。正确的思路是在插件包中避免直接返回SwiftUI视图,转而返回包装好的视图控制器:

  1. 在macOS插件包中定义协议,返回NSViewController:
// 插件包内的协议定义
public protocol LocalAuthProvider {
    func makeLocalAuthViewController() -> NSViewController
}

// 插件中的具体实现
public class MacLocalAuthProvider: LocalAuthProvider {
    public func makeLocalAuthViewController() -> NSViewController {
        let authView = LocalAuthenticationView() // 实例化macOS专属SwiftUI视图
        return NSHostingController(rootView: authView)
    }
}
  1. 主应用加载插件后,将NSViewController转换为Catalyst兼容的UIViewController:
    Catalyst支持将AppKit视图控制器的视图直接转为UIKit可用视图,也可以通过容器控制器管理生命周期:
// 主应用中加载插件并处理视图
if let provider = loadMacPlugin() as? LocalAuthProvider {
    let macVC = provider.makeLocalAuthViewController()
    // 将NSViewController的视图转为UIKit的UIView
    let authUIView = UIView(nsView: macVC.view)
    authUIView.frame = view.bounds
    view.addSubview(authUIView)
    
    // 若需要完整生命周期管理,添加为子控制器
    addChild(macVC)
    macVC.didMove(toParent: self)
}

二、直接使用AppKit的LAAuthenticationView

如果选择使用AppKit原生的LAAuthenticationView,完全可以在Mac Catalyst应用中加载并显示:

  1. 插件包中返回LAAuthenticationView实例:
public protocol LocalAuthNSViewProvider {
    func makeLocalAuthNSView() -> LAAuthenticationView
}

public class MacLocalAuthNSViewProvider: LocalAuthNSViewProvider {
    public func makeLocalAuthNSView() -> LAAuthenticationView {
        let authView = LAAuthenticationView()
        // 配置视图属性,比如代理、样式等
        authView.delegate = self
        return authView
    }
}
  1. 主应用中转换为UIKit视图并嵌入:
if let provider = loadMacPlugin() as? LocalAuthNSViewProvider {
    let nsAuthView = provider.makeLocalAuthNSView()
    // 将NSView转为UIKit兼容的UIView
    let uiAuthView = UIView(nsView: nsAuthView)
    uiAuthView.frame = CGRect(x: 20, y: 20, width: 300, height: 100)
    view.addSubview(uiAuthView)
    
    // 视图代理逻辑可在插件内封装,或通过自定义协议向主应用传递事件
}

三、插件包配置关键注意事项

  • 插件包必须设置为纯macOS目标,不能是Catalyst目标,确保能访问macOS专属API。
  • 主应用需仅在Catalyst环境下加载插件,避免iOS环境报错:
func loadMacPlugin() -> Any? {
    #if targetEnvironment(macCatalyst)
        guard let pluginURL = Bundle.main.url(forResource: "MacAuthPlugin", withExtension: "bundle") else { return nil }
        guard let pluginBundle = Bundle(url: pluginURL) else { return nil }
        pluginBundle.load()
        return pluginBundle.classNamed("MacLocalAuthProvider")?.init()
    #else
        return nil
    #endif
}

内容的提问来源于stack exchange,提问作者Igor Kulman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 15:15:11