我尝试使用Swift UI从核心数据中保存和获取数据。我调试代码,可以看到数据保存到核心数据中,并且有5条记录,但问题是当我尝试重新加载并重新运行它时,它只显示一条记录。
下面是代码视图模型。
import Foundation
import CoreData
@MainActor
class RedditViewModel: ObservableObject {
@Published private(set) var stories = [Story]()
private var redditService: RedditService
init(redditService: RedditService = RedditService()) {
self.redditService = redditService
}
// Swift 5.5
func fetchData(viewContext: NSManagedObjectContext) async {
let url = NetworkURLs.urlBase
do {
let response = try await redditService.getModel(from: url)
let stories = response.data.children.map { $0.data }
self.stories = stories
saveRecord(viewContext: viewContext)
} catch (let error) {
print(error)
}
}
public func saveRecord(viewContext: NSManagedObjectContext) {
do {
let redit = ReditEntity(context: viewContext)
stories.forEach { story in
redit.title = story.title
redit.numComments = Int64(story.numComments)
redit.score = Int64(story.score)
redit.urlImage = story.thumbnail
}
try viewContext.save()
} catch {
print(error.localizedDescription)
}
}
}
下面是主应用程序的代码。
import SwiftUI
@main
struct CoreDataDemoApp: App {
@StateObject private var viewModel = RedditViewModel()
let persistentContainer = CoreDataManager.shared.persistentContainer
var body: some Scene {
WindowGroup {
ContentView().environment(\.managedObjectContext, persistentContainer.viewContext).environmentObject(viewModel)
}
}
}
下面是进入内容视图的代码。
import SwiftUI
import CoreData
struct ContentView: View {
@EnvironmentObject private var viewModel: RedditViewModel
@Environment(\.managedObjectContext) private var viewContext
@FetchRequest(entity: ReditEntity.entity(), sortDescriptors: [])
private var dbStories: FetchedResults<ReditEntity>
var dbFatchReditRecord: NSFetchRequest<ReditEntity> = ReditEntity.fetchRequest()
var body: some View {
VStack {
Text("Reddit Service")
.font(.largeTitle)
List {
ForEach(dbStories) { story in
// custom cell
RowView(title: story.title ?? "", comments: "\(story.numComments)", score: "\(story.score)", urlImage: story.urlImage)
}
}
}
.onAppear {
if dbStories.isEmpty {
Task {
await viewModel.fetchData(viewContext: viewContext)
}
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
let persistedContainer = CoreDataManager.shared.persistentContainer
ContentView().environment(\.managedObjectContext, persistedContainer.viewContext) }
}
下面是RowView.swift的代码
import SwiftUI
struct RowView: View {
@EnvironmentObject var viewModel: RedditViewModel
let title: String
let comments: String
let score: String
let urlImage: String?
var body: some View {
VStack(alignment: .leading) {
HStack {
if let urlImage = urlImage, urlImage.contains("https"), let url = URL(string: urlImage) {
AsyncImage(url: url)
}
VStack(alignment: .leading) {
HeadTitleView(title: title)
Text("Comments: \(comments)")
Text("Score: \(score)")
Spacer()
}
}
}
}
}
下面是标题的代码.swift ..
import SwiftUI
struct HeadTitleView: View {
@EnvironmentObject var viewModel: RedditViewModel
let title: String
var body: some View {
Text(title)
}
}
下面是截图。
1条答案
按热度按时间yzuktlbb1#
在这里,您创建了一个实体对象,但随后在循环中重用了同一个对象,因此最终要做的是用每个故事更新这个对象,而不是为每个故事创建一个新对象。
只需交换线路即可解决问题