Fix import link error

This commit is contained in:
2025-08-16 20:24:00 +10:00
parent 6e4d80f2d6
commit 0442c2bb68
+64 -35
View File
@@ -81,6 +81,49 @@ struct SettingsView: View {
var skippedCount = 0
var failedEntries: [String] = []
// Helper to generate slug similar to backend slugify
func generateSlug(_ raw: String) -> String {
let base = raw
.lowercased()
.trimmingCharacters(in: .whitespacesAndNewlines)
.replacingOccurrences(of: " ", with: "-")
.replacingOccurrences(of: "[^a-z0-9-]", with: "", options: .regularExpression)
return base
}
// Fetch or create tag ensuring unique slug
func fetchOrCreateTag(named name: String) throws -> Tag {
let trimmed = name.trimmingCharacters(in: .whitespacesAndNewlines)
if trimmed.isEmpty { throw NSError(domain: "Import", code: 10, userInfo: [NSLocalizedDescriptionKey: "Empty tag name"]) }
// Case-insensitive fetch
let request: NSFetchRequest<Tag> = Tag.fetchRequest()
request.predicate = NSPredicate(format: "name ==[c] %@", trimmed)
request.fetchLimit = 1
if let existing = try context.fetch(request).first { return existing }
// Create new tag with unique slug
let tag = Tag(context: context)
tag.name = trimmed
var slug = generateSlug(trimmed)
if slug.isEmpty { slug = UUID().uuidString.prefix(8).lowercased() }
// Ensure slug uniqueness
var uniqueSlug = slug
var index = 1
while true {
let slugRequest: NSFetchRequest<Tag> = Tag.fetchRequest()
slugRequest.predicate = NSPredicate(format: "slug == %@", uniqueSlug)
slugRequest.fetchLimit = 1
if try context.count(for: slugRequest) == 0 { break }
uniqueSlug = "\(slug)-\(index)"
index += 1
}
tag.slug = uniqueSlug
tag.createdAt = Date()
return tag
}
// First try to parse the entire JSON as LinkData array
do {
let linkDataArray = try JSONDecoder().decode([LinkData].self, from: data)
@@ -106,24 +149,12 @@ struct SettingsView: View {
// Handle tags if present
if let tagNames = linkData.tags {
for tagName in tagNames {
let tagFetchRequest: NSFetchRequest<Tag> = Tag.fetchRequest()
tagFetchRequest.predicate = NSPredicate(format: "name == %@", tagName)
var tag: Tag
if let existingTag = try context.fetch(tagFetchRequest).first {
tag = existingTag
} else {
tag = Tag(context: context)
tag.name = tagName
// Generate slug (required non-optional Core Data attribute)
tag.slug = tagName
.lowercased()
.trimmingCharacters(in: .whitespacesAndNewlines)
.replacingOccurrences(of: " ", with: "-")
.replacingOccurrences(of: "[^a-z0-9-]", with: "", options: .regularExpression)
tag.createdAt = Date()
do {
let tag = try fetchOrCreateTag(named: tagName)
link.addToTags(tag)
} catch {
print("⚠️ Skipped tag '\(tagName)': \(error.localizedDescription)")
}
link.addToTags(tag)
}
}
@@ -170,24 +201,12 @@ struct SettingsView: View {
// Handle tags if present
if let tagNames = linkData.tags {
for tagName in tagNames {
let tagFetchRequest: NSFetchRequest<Tag> = Tag.fetchRequest()
tagFetchRequest.predicate = NSPredicate(format: "name == %@", tagName)
var tag: Tag
if let existingTag = try context.fetch(tagFetchRequest).first {
tag = existingTag
} else {
tag = Tag(context: context)
tag.name = tagName
// Generate slug (required non-optional Core Data attribute)
tag.slug = tagName
.lowercased()
.trimmingCharacters(in: .whitespacesAndNewlines)
.replacingOccurrences(of: " ", with: "-")
.replacingOccurrences(of: "[^a-z0-9-]", with: "", options: .regularExpression)
tag.createdAt = Date()
do {
let tag = try fetchOrCreateTag(named: tagName)
link.addToTags(tag)
} catch {
print("⚠️ Skipped tag '\(tagName)': \(error.localizedDescription)")
}
link.addToTags(tag)
}
}
@@ -204,7 +223,17 @@ struct SettingsView: View {
}
}
try context.save()
do {
try context.save()
} catch {
let nsError = error as NSError
if let detailed = nsError.userInfo[NSDetailedErrorsKey] as? [NSError] {
for d in detailed { print("❌ Save detail: \(d), userInfo: \(d.userInfo)") }
} else {
print("❌ Save error: \(nsError), userInfo: \(nsError.userInfo)")
}
throw nsError
}
// Refresh the link view model
linkViewModel.fetchLinks()