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

SwiftUI文档型应用:视图显示前初始化文档数据问询

解决方案:SwiftUI文档URL预加载与视图初始化处理

核心方案

通过启动加载页完成文档URL的所有预处理(包括图片URL组合、视频内容解析等),待处理完成后再渲染主视图。同时使用ObservableObject管理数据状态,确保视图仅在数据就绪后加载。


1. 重构数据管理类

创建ObservableObject子类,负责文档加载、URL预处理逻辑,替代直接在Doc结构体中处理的方式:

import SwiftUI

// 扩展Doc,新增视频URL字段(按需调整)
struct Doc: Codable {
    var images: [URL]
    var videos: [URL] = []
    
    init(images: [URL], videos: [URL] = []) {
        self.images = images
        self.videos = videos
    }
}

// 数据管理类:处理文档加载、URL预处理
class DocDataManager: ObservableObject {
    @Published var processedDoc: Doc?
    @Published var isLoading = true
    
    // 加载并预处理文档
    func loadAndProcessDocument(_ document: TestInitialiseFromDocDocument) {
        DispatchQueue.global(qos: .userInitiated).async {
            // 模拟生产环境的多项预处理操作
            let processedImages = self.processImageURLs(document.document.images)
            let processedVideos = self.processVideoURLs(document.document.videos)
            
            DispatchQueue.main.async {
                self.processedDoc = Doc(images: processedImages, videos: processedVideos)
                self.isLoading = false
            }
        }
    }
    
    // 图片URL处理逻辑(示例:补全域名、格式转换等)
    private func processImageURLs(_ urls: [URL]) -> [URL] {
        return urls.map { url in
            // 这里替换为实际处理逻辑,比如拼接基础域名
            let baseURL = URL(string: "https://your-domain.com/")!
            return baseURL.appending(path: url.path)
        }
    }
    
    // 视频URL处理逻辑(示例:解析流媒体地址、验证有效性等)
    private func processVideoURLs(_ urls: [URL]) -> [URL] {
        return urls.filter { url in
            // 这里替换为实际视频URL验证逻辑
            url.pathExtension == "mp4" || url.pathExtension == "mov"
        }
    }
}

2. 实现启动加载视图与主视图切换

创建加载视图,在数据预处理完成后自动切换到主视图:

struct ContentView: View {
    @StateObject private var dataManager = DocDataManager()
    @State private var document: TestInitialiseFromDocDocument = .init()
    
    var body: some View {
        Group {
            if dataManager.isLoading {
                // 启动加载页:展示加载动画或提示
                VStack {
                    ProgressView("正在处理资源...")
                        .scaleEffect(1.2)
                    Text("请稍候")
                        .padding(.top, 10)
                }
                .onAppear {
                    // 应用启动时立即开始处理文档
                    dataManager.loadAndProcessDocument(document)
                }
            } else {
                // 主视图:使用预处理后的文档数据
                MainView(doc: dataManager.processedDoc!)
            }
        }
    }
}

// 主视图示例:展示处理后的图片和视频
struct MainView: View {
    let doc: Doc
    
    var body: some View {
        ScrollView {
            VStack(spacing: 20) {
                Text("处理后的图片URL")
                    .font(.title)
                ForEach(doc.images, id: \.self) { url in
                    Text(url.absoluteString)
                        .padding()
                        .background(Color.gray.opacity(0.1))
                        .cornerRadius(8)
                }
                
                Text("处理后的视频URL")
                    .font(.title)
                ForEach(doc.videos, id: \.self) { url in
                    Text(url.absoluteString)
                        .padding()
                        .background(Color.blue.opacity(0.1))
                        .cornerRadius(8)
                }
            }
            .padding()
        }
    }
}

3. 调整文档读取逻辑

修改TestInitialiseFromDocDocument的初始化方法,确保读取文档后能传递给数据管理类处理:

struct TestInitialiseFromDocDocument: FileDocument, Codable {
    var document: Doc

    init() {
        // 测试数据:可替换为实际文档内容
        let imageA = URL(string: "assets/imageA.jpg")!
        let imageB = URL(string: "assets/imageB.png")!
        let videoA = URL(string: "assets/videoA.mp4")!
        let videoB = URL(string: "assets/videoB.txt")! // 无效视频格式,会被过滤
        
        let newDoc = Doc(images: [imageA, imageB], videos: [videoA, videoB])
        self.document = newDoc
    }

    static var readableContentTypes: [UTType] { [.exampleText] }

    init(configuration: ReadConfiguration) throws {
        guard let data = configuration.file.regularFileContents else {
            throw CocoaError(.fileReadCorruptFile)
        }
        let fileContents = try JSONDecoder().decode(Self.self, from: data)
        self = fileContents
    }
    
    func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper {
        let data = try JSONEncoder().encode(self)
        return .init(regularFileWithContents: data)
    }
}

额外说明

  • 用户添加新URL后,只需调用dataManager.loadAndProcessDocument(newDocument)即可重新触发预处理逻辑,视图会自动更新。
  • 预处理逻辑(processImageURLs、processVideoURLs)可根据生产需求扩展,比如添加缓存、错误处理、异步下载预览图等。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 10:20:33