ReadKeep/readeck/Data/Repository/BookmarkSyncRepository.swift
Ilyas Hallak 2d3be2430f wip
2025-06-25 21:44:55 +02:00

104 lines
3.5 KiB
Swift

import Foundation
import CoreData
class BookmarkSyncRepository {
private let userDefaults = UserDefaults.standard
private let lastSyncTimestampKey = "lastBookmarkSyncTimestamp"
private var api: PAPI
private let coreDataManager = CoreDataManager.shared
init(api: PAPI) {
self.api = api
}
func resetBookmarks() async throws {
let context = coreDataManager.context
try await context.perform {
// Fetch Request für alle BookmarkEntity Objekte
let fetchRequest: NSFetchRequest<NSFetchRequestResult> = BookmarkEntity.fetchRequest()
let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
do {
// Batch Delete ausführen
try context.execute(deleteRequest)
// Context speichern
try context.save()
// UserDefaults zurücksetzen
self.userDefaults.removeObject(forKey: self.lastSyncTimestampKey)
print("Alle Bookmarks wurden erfolgreich gelöscht")
} catch {
print("Fehler beim Löschen der Bookmarks: \(error)")
throw error
}
}
}
func syncBookmarks() async throws {
try? await resetBookmarks()
// Letzten Sync-Timestamp aus UserDefaults abrufen
let lastSyncTimestamp = userDefaults.double(forKey: lastSyncTimestampKey)
let updatedSince = lastSyncTimestamp > 0 ? Date(timeIntervalSince1970: lastSyncTimestamp) : nil
// Bookmarks vom Server abrufen
let bookmarks = try await fetchBookmarks(updatedSince: updatedSince)
// Batch-Insert durchführen
try await batchInsertBookmarks(bookmarks)
// Aktuellen Timestamp speichern
userDefaults.set(Date().timeIntervalSince1970, forKey: lastSyncTimestampKey)
}
private func fetchBookmarks(updatedSince: Date?) async throws -> [Bookmark] {
let bookmarks = try await api.getBookmarks(state: .unread, updatedSince: updatedSince, limit: nil, offset: nil)
return bookmarks.map {
$0.toDomain()
}
}
private func batchInsertBookmarks(_ bookmarks: [Bookmark]) async throws {
let context = CoreDataManager.shared.context
// Existierende URLs aus Core Data abrufen
let existingURLs = try await getExistingBookmarkURLs()
// Nur neue Bookmarks filtern
let newBookmarks = bookmarks.filter { !existingURLs.contains($0.url) }
// Batch-Insert
await context.perform {
for bookmark in newBookmarks {
newBookmarks.forEach {
_ = $0.toEntity(context: context)
}
}
do {
try context.save()
} catch {
print("Fehler beim Speichern der Bookmarks: \(error)")
}
}
}
private func getExistingBookmarkURLs() async throws -> Set<String> {
let context = CoreDataManager.shared.context
let request: NSFetchRequest<BookmarkEntity> = BookmarkEntity.fetchRequest()
request.propertiesToFetch = ["url"]
request.resultType = .dictionaryResultType
return try await context.perform {
let results = try context.fetch(request) as! [[String: Any]]
return Set(results.compactMap { $0["url"] as? String })
}
}
}