ReadKeep/readeck/UI/AddBookmark/AddBookmarkViewModel.swift
Ilyas Hallak 8882a402ef refactor: Simplify Share Extension to open main app directly
- Refactor ShareViewController to extract URL and open main app instead of direct API calls
- Add robust URL extraction from multiple content types (URL, text, property lists)
- Implement comprehensive debugging for Share Extension content processing
- Add URL scheme handling in main app (readeck://add-bookmark)
- Add notification-based communication between Share Extension and main app
- Extend BookmarksViewModel with share notification handling
- Support automatic AddBookmarkView opening with prefilled URL and title from shares

Technical changes:
- Remove Core Data dependency from Share Extension
- Add extensionContext.open() for launching main app with custom URL scheme
- Process all registered type identifiers for robust content extraction
- Add NSDataDetector for URL extraction from plain text
- Handle Safari property list sharing format
- Add share state management in BookmarksViewModel (@Observable pattern)
- Implement NotificationCenter publisher pattern with Combine

URL scheme format: readeck://add-bookmark?url=...&title=...
Notification: 'AddBookmarkFromShare' with url and title in userInfo
2025-06-13 15:02:46 +02:00

86 lines
2.4 KiB
Swift

import Foundation
import UIKit
@Observable
class AddBookmarkViewModel {
private let createBookmarkUseCase = DefaultUseCaseFactory.shared.makeCreateBookmarkUseCase()
var url: String = ""
var title: String = ""
var labelsText: String = ""
var isLoading: Bool = false
var errorMessage: String?
var showErrorAlert: Bool = false
var showSuccessAlert: Bool = false
var clipboardURL: String?
var isValid: Bool {
!url.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty &&
URL(string: url.trimmingCharacters(in: .whitespacesAndNewlines)) != nil
}
var parsedLabels: [String] {
labelsText
.components(separatedBy: ",")
.map { $0.trimmingCharacters(in: .whitespacesAndNewlines) }
.filter { !$0.isEmpty }
}
@MainActor
func createBookmark() async {
guard isValid else { return }
isLoading = true
errorMessage = nil
do {
let cleanURL = url.trimmingCharacters(in: .whitespacesAndNewlines)
let cleanTitle = title.trimmingCharacters(in: .whitespacesAndNewlines)
let labels = parsedLabels
let request = CreateBookmarkRequest(
url: cleanURL,
title: cleanTitle.isEmpty ? nil : cleanTitle,
labels: labels.isEmpty ? nil : labels
)
let message = try await createBookmarkUseCase.execute(createRequest: request)
// Optional: Zeige die Server-Nachricht an
print("Server response: \(message)")
clearForm()
} catch let error as CreateBookmarkError {
errorMessage = error.localizedDescription
showErrorAlert = true
} catch {
errorMessage = "Fehler beim Erstellen des Bookmarks"
showErrorAlert = true
}
isLoading = false
}
func checkClipboard() {
guard let clipboardString = UIPasteboard.general.string,
URL(string: clipboardString) != nil else {
clipboardURL = nil
return
}
clipboardURL = clipboardString
}
func pasteFromClipboard() {
guard let clipboardURL = clipboardURL else { return }
url = clipboardURL
}
func clearForm() {
url = ""
title = ""
labelsText = ""
}
}