SwiftUI预览崩溃,如果返回具有UUID的结构,则等待异步iOS15

ghhaqwfi  于 2023-03-09  发布在  iOS
关注(0)|答案(4)|浏览(172)

我将代码简化为非常简单的代码。如果结构体有Int,预览就会崩溃(如果我在模拟器或真实的设备上运行,预览就会崩溃)

通过iOS 15 Xcode 13.1和beta版13.2测试

import SwiftUI
import Combine

struct MyStruct: Codable, Hashable, Identifiable {
    var id: UUID = UUID() //with Int is ok
    var str: String
}

struct ContentView2: View {
    
    @State private var myStruct: MyStruct = MyStruct(str: "struct1-init")
    
    var body: some View {
        VStack {
            Text(myStruct.str)
                .onAppear(perform: doSometingStruct)
        }
    }
    
    private func doSometingStruct() {
        Task {
            let get = await getAsyncStruct()
            myStruct = get
        }
    }
    
    private func getAsyncStruct() async -> MyStruct {
        let str = MyStruct(str: "struct1-done")
        return str
    }
}

struct ContentView2_Previews: PreviewProvider {
    static var previews: some View {
        ContentView2()
    }
}
i5desfxk

i5desfxk1#

这似乎是一个错误的xcode预览视图与异步代码...尝试测试与注解任务:

private func doSometingStruct() {
        //Task {
        //    let get = await getAsyncStruct()
        //    myStruct = get
        //}
    }
rjzwgtxy

rjzwgtxy2#

感觉不“正确”,但是能够通过不让异步函数返回任何东西并将结构存储在可以从调用函数获得的全局变量中来绕过这个问题。感觉各种各样的错误,但是它确实可以修复崩溃。如果有人有更好的解决方案,我很想知道!

g6ll5ycj

g6ll5ycj3#

我通过强制async函数休眠一小段时间,然后仅在预览时返回结果,从而解决了这个问题(对于其他仍遇到这个问题的人)。
下面是一个例子:

private func getAsyncStruct() async -> MyStruct {
    let str = MyStruct(str: "struct1-done")
    do {
        try await Task.sleep(nanoseconds: 1)
    } catch {
        print("Error: \(error)")
    }
    return str
}

请注意,为了确保您不在生产代码中执行此操作,并且仅用于预览,我将getAsyncStruct模拟到一个依赖项中,在该依赖项中,上述内容被传入用于预览,而另一个不同的实现被传入用于实时。
例如,

private func getAsyncStruct() async -> MyStruct {
    viewModel.getAsyncStrut()
}

然后可以将具有上述实现的不同viewModel传递到预览中。
希望这能帮到什么人。

wmomyfyw

wmomyfyw4#

这似乎在Xcode 14.0中得到了修复

相关问题