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

如何扩展iOS的ARSessionDelegate并将代理结果回传至注册类?

如何将ARSession代理方法的结果传递给注册类

下面是几种实用的实现方式,根据你的场景选择即可:

方法一:使用闭包(最简洁的轻量方案)

在自定义代理类中定义闭包属性,当代理方法触发时调用闭包传递结果:

// 自定义ARSession代理类
class ARKitSessionDelegate: NSObject, ARSessionDelegate {
    // 定义接收ARFrame的闭包
    var onFrameUpdated: ((ARFrame) -> Void)?
    
    func session(_ session: ARSession, didUpdate frame: ARFrame) {
        // 调用闭包,把frame传递出去
        onFrameUpdated?(frame)
    }
}

// 在注册代理的类中使用
private var arKitSessionDelegate = ARKitSessionDelegate()
arKitView.session.delegate = arKitSessionDelegate

// 设置闭包接收结果
arKitSessionDelegate.onFrameUpdated = { frame in
    // 在这里处理frame数据,比如更新UI、计算空间位置等
    print("收到更新的ARFrame: \(frame.camera.transform)")
}

方法二:自定义代理协议(适合多类型结果传递)

如果需要传递多种事件(比如错误、追踪状态变化),自定义协议会让逻辑更清晰:

// 自定义输出代理协议
protocol ARKitSessionOutputDelegate: AnyObject {
    func arSessionDidUpdateFrame(_ frame: ARFrame)
    func arSessionDidFail(with error: Error)
}

// 自定义ARSession代理类
class ARKitSessionDelegate: NSObject, ARSessionDelegate {
    // 弱引用避免循环引用
    weak var outputDelegate: ARKitSessionOutputDelegate?
    
    func session(_ session: ARSession, didUpdate frame: ARFrame) {
        outputDelegate?.arSessionDidUpdateFrame(frame)
    }
    
    func session(_ session: ARSession, didFailWithError error: Error) {
        outputDelegate?.arSessionDidFail(with: error)
    }
}

// 注册代理的类遵守自定义协议
class ARContainerViewController: UIViewController, ARKitSessionOutputDelegate {
    private var arKitSessionDelegate = ARKitSessionDelegate()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        arKitView.session.delegate = arKitSessionDelegate
        // 设置自定义输出代理
        arKitSessionDelegate.outputDelegate = self
    }
    
    // 实现协议方法接收结果
    func arSessionDidUpdateFrame(_ frame: ARFrame) {
        // 处理ARFrame数据
    }
    
    func arSessionDidFail(with error: Error) {
        // 处理错误逻辑
    }
}

方法三:使用通知中心(适合多类接收场景)

如果需要多个类同时接收ARSession的结果,可以用通知中心广播数据,但注意避免滥用导致代码耦合:

// 自定义ARSession代理类
class ARKitSessionDelegate: NSObject, ARSessionDelegate {
    func session(_ session: ARSession, didUpdate frame: ARFrame) {
        // 发送通知,携带frame数据
        NotificationCenter.default.post(
            name: NSNotification.Name(rawValue: "ARFrameUpdatedNotification"),
            object: frame
        )
    }
}

// 在注册代理的类中监听通知
class ARContainerViewController: UIViewController {
    private var arKitSessionDelegate = ARKitSessionDelegate()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        arKitView.session.delegate = arKitSessionDelegate
        // 添加通知监听
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(handleFrameUpdate(_:)),
            name: NSNotification.Name(rawValue: "ARFrameUpdatedNotification"),
            object: nil
        )
    }
    
    @objc private func handleFrameUpdate(_ notification: Notification) {
        guard let frame = notification.object as? ARFrame else { return }
        // 处理frame数据
    }
    
    deinit {
        // 移除通知监听,避免内存泄漏
        NotificationCenter.default.removeObserver(self)
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 11:36:14