实践
我们来实践一下使用MVVM模式,并使用async await进行网络请求。
Library.swift
1 2 3 4 5
| import Foundation struct Common: Codable,Hashable { var act: String = "" var prompt: String = "" }
|
LibraryViewModel.swift
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| import Foundation @MainActor class LibraryViewModel: ObservableObject { @Published var commons: [Common] = [] @Published var commonSelected:Common = Common() func getCommons() async { guard let url = URL(string: "https://carteclip.com/api/v1/ama/prompts") else { print("URL无效,请检查输入~") return } do { var request = URLRequest(url: url) request.setValue("zh", forHTTPHeaderField: "prefer-language") let (data, _) = try await URLSession.shared.data( for: request ) if let decodedResponse = try? JSONDecoder().decode([Common].self, from: data) { self.commons = decodedResponse } } catch { print("数据解码失败,请检查~") } } }
|
LibraryView.swift
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| import SwiftUI struct LibraryRow: View { var common: Common var body: some View { VStack(alignment: .leading) { Spacer() Text(common.act) .listRowSeparator(.hidden) .font(.system(size: 18)) .frame(maxWidth: .infinity, alignment: .leading) Spacer() Text(common.prompt) .frame(maxWidth: .infinity, alignment: .leading) .font(.system(size: 15)) .lineLimit(3) Spacer() } } } struct LibraryView: View { @State var presentSheetKey = false @State var cur_common:Common = Common(act: "", prompt: "") @ObservedObject var viewModel: LibraryViewModel var body: some View { NavigationStack { List(viewModel.commons,id: \.self) { common in Section{ Button { viewModel.commonSelected = common presentSheetKey = true } label: { LibraryRow(common:common).listRowSeparator(.hidden) }.buttonStyle(.plain) } }.task { await viewModel.getCommons() }.refreshable { await viewModel.getCommons() } }.sheet(isPresented: $presentSheetKey) { VStack(alignment: .leading,spacing: 20) { Text(viewModel.commonSelected.act).font(.system(size: 17)).foregroundColor(.primary) Text(viewModel.commonSelected.prompt).font(.system(size: 15)).foregroundColor(.secondary).lineSpacing(8) Spacer() HStack(alignment: .bottom,spacing: 20){ Spacer() Button { presentSheetKey = false } label: { Text("取消").foregroundColor(.primary) } Button { } label: { Text("开始对话").foregroundColor(.primary) } } }.padding() .presentationDetents([.fraction(0.5),.medium]) .presentationBackground(.thinMaterial) .presentationCornerRadius(20) .presentationDragIndicator(.visible) } } } struct LibraryView_Previews: PreviewProvider { static var previews: some View { LibraryView( viewModel: LibraryViewModel()) } }
|
LibraryDetailView.swift
1 2 3 4 5 6 7 8 9 10 11
| import Foundation import SwiftUI
struct LibraryDetailView: View { var common:Common @Environment(\.dismiss) var dismiss var body: some View { Text(common.prompt) } }
|