feat: 최근 들은 콘텐츠 로컬 DB 추가
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// PersistenceController.swift
|
||||
// SodaLive
|
||||
//
|
||||
// Created by klaus on 7/28/25.
|
||||
//
|
||||
|
||||
import CoreData
|
||||
|
||||
struct PersistenceController {
|
||||
static let shared = PersistenceController()
|
||||
|
||||
let container: NSPersistentContainer
|
||||
|
||||
init() {
|
||||
container = NSPersistentContainer(name: "DataModel")
|
||||
container.loadPersistentStores { description, error in
|
||||
if let error = error {
|
||||
fatalError("Error loading Core Data stores: \(error)")
|
||||
}
|
||||
}
|
||||
container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
//
|
||||
// RecentContent+CoreDataClass.swift
|
||||
// SodaLive
|
||||
//
|
||||
// Created by klaus on 7/28/25.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import CoreData
|
||||
|
||||
@objc(RecentContent)
|
||||
public class RecentContent: NSManagedObject {
|
||||
}
|
||||
|
||||
extension RecentContent {
|
||||
@nonobjc public class func fetchRequest() -> NSFetchRequest<RecentContent> {
|
||||
return NSFetchRequest<RecentContent>(entityName: "RecentContent")
|
||||
}
|
||||
|
||||
@NSManaged public var contentId: Int64
|
||||
@NSManaged public var coverImageUrl: String
|
||||
@NSManaged public var title: String
|
||||
@NSManaged public var creatorNickname: String
|
||||
@NSManaged public var listenedAt: Date
|
||||
}
|
||||
123
SodaLive/Sources/MyPage/Recent/DB/RecentContentService.swift
Normal file
123
SodaLive/Sources/MyPage/Recent/DB/RecentContentService.swift
Normal file
@@ -0,0 +1,123 @@
|
||||
//
|
||||
// RecentContentService.swift
|
||||
// SodaLive
|
||||
//
|
||||
// Created by klaus on 7/28/25.
|
||||
//
|
||||
|
||||
import CoreData
|
||||
import Combine
|
||||
|
||||
class RecentContentService {
|
||||
private let viewContext: NSManagedObjectContext
|
||||
|
||||
init(context: NSManagedObjectContext = PersistenceController.shared.container.viewContext) {
|
||||
self.viewContext = context
|
||||
}
|
||||
|
||||
func getRecentContents(limit: Int = 10) -> [RecentContent] {
|
||||
let request = RecentContent.fetchRequest()
|
||||
request.sortDescriptors = [NSSortDescriptor(key: "listenedAt", ascending: false)]
|
||||
request.fetchLimit = limit
|
||||
|
||||
do {
|
||||
return try viewContext.fetch(request)
|
||||
} catch {
|
||||
print("Error fetching recent contents: \(error)")
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
func insertRecentContent(contentId: Int64, coverImageUrl: String, title: String, creatorNickname: String) {
|
||||
// Check if content already exists
|
||||
if let existingContent = findContent(byId: contentId) {
|
||||
// Update timestamp
|
||||
existingContent.listenedAt = Date()
|
||||
saveContext()
|
||||
} else {
|
||||
// Create new content
|
||||
let newContent = RecentContent(context: viewContext)
|
||||
newContent.contentId = contentId
|
||||
newContent.coverImageUrl = coverImageUrl
|
||||
newContent.title = title
|
||||
newContent.creatorNickname = creatorNickname
|
||||
newContent.listenedAt = Date()
|
||||
saveContext()
|
||||
}
|
||||
|
||||
// Keep only most recent 10 items
|
||||
keepMostRecent(limit: 10)
|
||||
}
|
||||
|
||||
func deleteByContentId(contentId: Int64) {
|
||||
if let content = findContent(byId: contentId) {
|
||||
viewContext.delete(content)
|
||||
saveContext()
|
||||
}
|
||||
}
|
||||
|
||||
func getCount() -> Int {
|
||||
let request = RecentContent.fetchRequest()
|
||||
|
||||
do {
|
||||
return try viewContext.count(for: request)
|
||||
} catch {
|
||||
print("Error counting recent contents: \(error)")
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func truncate() {
|
||||
let fetchRequest: NSFetchRequest<NSFetchRequestResult> = RecentContent.fetchRequest()
|
||||
let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
|
||||
|
||||
do {
|
||||
try viewContext.execute(deleteRequest)
|
||||
saveContext()
|
||||
} catch {
|
||||
print("Error truncating recent contents: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
private func keepMostRecent(limit: Int) {
|
||||
let count = getCount()
|
||||
if count <= limit { return }
|
||||
|
||||
let request = RecentContent.fetchRequest()
|
||||
request.sortDescriptors = [NSSortDescriptor(key: "listenedAt", ascending: false)]
|
||||
|
||||
do {
|
||||
let allContents = try viewContext.fetch(request)
|
||||
for i in limit..<allContents.count {
|
||||
viewContext.delete(allContents[i])
|
||||
}
|
||||
saveContext()
|
||||
} catch {
|
||||
print("Error keeping most recent contents: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
private func findContent(byId contentId: Int64) -> RecentContent? {
|
||||
let request = RecentContent.fetchRequest()
|
||||
request.predicate = NSPredicate(format: "contentId == %lld", contentId)
|
||||
request.fetchLimit = 1
|
||||
|
||||
do {
|
||||
let results = try viewContext.fetch(request)
|
||||
return results.first
|
||||
} catch {
|
||||
print("Error finding content by ID: \(error)")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
private func saveContext() {
|
||||
if viewContext.hasChanges {
|
||||
do {
|
||||
try viewContext.save()
|
||||
} catch {
|
||||
print("Error saving context: \(error)")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user