如何在视图中“解包”Publisher 对象 [swift]

Posted

技术标签:

【中文标题】如何在视图中“解包”Publisher 对象 [swift]【英文标题】:How to 'unwrap' Publisher object in view [swift] 【发布时间】:2021-02-18 05:48:04 【问题描述】:

我将如何将数组内容分配给一个变量以在视图中使用。

struct SwiftCameraApp: App 
     @StateObject var service = CameraService()
     var body: some Scene 
        WindowGroup 
            Home()
                .environmentObject(service)     
     


public class CameraService: NSObject, ObservableObject 
    
    @Published var videoClips = [URL]()

    public func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) 
        print("finished recording the video to: \(outputFileURL)")
        print(output.recordedDuration)

        videoClips.append(outputFileURL)
            
        //returns 1 at this point
        print("\(videoClips.count) video clip is now in the camera service")


struct ViewA: View 
    @StateObject var model = CameraService()
     Button("Adds item to videoClips") 
            model.fileOutput()
            


struct ViewB: View 
    @EnvironmentObject var service : CameraService
    var body: some View 
        Button("Prints Array count") 
            print(service.$videoClips.count())
        
    

输出: 计数(上游:Combine.Published>.Publisher(主题:Combine.PublishedSubject>)) 也许有助于了解。 a) 当 CameraService 启动时 videoClips 为空。在视图 A 中按下按钮后会添加一个值。 b)我认为在初始化视图时会创建一个新的 CameraService,使其成为一个空数组 c) 想法是拍摄视频。将其附加到 videoClips 数组中,然后对视图 B 中的内容进行处理。

【问题讨论】:

【参考方案1】:

也许您只是想要(即数组中的元素数量):

    Button("Prints Array count") 
        print(service.videoClips.count)
    

更新:它在ViewA中使用了不同的CameraService对象,所以更新ViewAViewB中没有任何变化,因为模型的实例不一样。

相反,您需要使用对相同CameraService 的引用,即。在环境对象中提供的那个

struct ViewA: View 
    @EnvironmentObject var model: CameraService   // << here !!
     Button("Adds item to videoClips") 
            model.fileOutput()
            

【讨论】:

打印 0 甚至知道我知道数组中有值 您能提供最小的可重现示例吗?【参考方案2】:

@StateObject var model = CameraService() 中的每一个都是服务的一个单独实例。 SwiftCameraApp 中的那个看不到 ViewA 在做什么,反之亦然。

如果您希望他们使用SwiftCameraApp 中的EnvironmentObject 与过去通信>Home>ViewA 或者您可以将您的服务更改为单例。

public class CameraService: NSObject, ObservableObject 
    static let shared = CameraService()
    @Published var videoClips = [URL]()

    private init()

    public func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) 
        print("finished recording the video to: \(outputFileURL)")
        print(output.recordedDuration)

        videoClips.append(outputFileURL)
        
        //returns 1 at this point
        print("\(videoClips.count) video clip is now in the camera service")

并将您的 StateObjects 更改为 @StateObject var model = CameraService.shared

【讨论】:

以上是关于如何在视图中“解包”Publisher 对象 [swift]的主要内容,如果未能解决你的问题,请参考以下文章

VIEW 视图

多处理进程对象中的字典解包

如何从 C(服务器)中收到的 python(客户端)“解包”数据包?

Swift & Core Data 解包 fetchedresults

如何设置Django管理员搜索字段?

taglib-sharp 中是不是有与 Label/Publisher 等效的字段?