Complete ground-up rewrite in SwiftUI targeting iOS 26. Drops the Flutter/Dart codebase entirely in favour of a lean native app with no third-party dependencies. Features shipped: - Bookmark list with pagination, pull-to-refresh, swipe delete/archive - Add bookmark form + iOS share extension (zero-tap save from any app) - Tags tab — all tags sorted by count, tap to browse filtered bookmarks - Native search tab (Tab role: .search) with instant client-side filtering - AI enrichment via OpenRouter (google/gemini-2.0-flash-lite-001): auto-summary and tag generation, semantic search, smart collections - Settings: linkding server config, OpenRouter API key - App Groups for credential sharing between main app and share extension - Swift 6 strict concurrency throughout (@Observable, @MainActor) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
70 lines
2.6 KiB
Markdown
70 lines
2.6 KiB
Markdown
# Marks
|
|
|
|
A native iOS client for [linkding](https://github.com/sissbruecker/linkding), the self-hosted bookmark manager.
|
|
|
|
Built from scratch in SwiftUI targeting iOS 26. Replaces the previous Flutter-based app.
|
|
|
|
## Features
|
|
|
|
- Browse and search your bookmarks
|
|
- Swipe to delete or archive
|
|
- Add bookmarks manually
|
|
- Share to Marks from any app (share extension)
|
|
- Tag browser — see all tags sorted by count, tap to filter
|
|
- Native search tab with instant client-side filtering
|
|
- AI enrichment via OpenRouter — auto-generates summaries and tags for each bookmark
|
|
- Semantic search — rank bookmarks by relevance using AI
|
|
- Smart Collections — AI groups your bookmarks into themed collections
|
|
- Pagination — loads more as you scroll
|
|
|
|
## Requirements
|
|
|
|
- iOS 26+
|
|
- A running [linkding](https://github.com/sissbruecker/linkding) instance with API access
|
|
- (Optional) An [OpenRouter](https://openrouter.ai) API key for AI features
|
|
|
|
## AI Features
|
|
|
|
All AI features are optional and powered by [OpenRouter](https://openrouter.ai) using `google/gemini-2.0-flash-lite-001` — one of the cheapest available models (~$0.075/M input tokens).
|
|
|
|
| Feature | What it does |
|
|
|---|---|
|
|
| Auto-enrichment | Generates a one-sentence summary and 3-5 tags for each bookmark |
|
|
| Semantic search | Ranks your bookmarks by relevance to a natural language query |
|
|
| Smart Collections | Groups up to 150 bookmarks into 3-6 themed collections |
|
|
|
|
Add your OpenRouter API key in Settings to enable these features.
|
|
|
|
## Building
|
|
|
|
Requires [xcodegen](https://github.com/yonaskolb/XcodeGen).
|
|
|
|
```bash
|
|
brew install xcodegen
|
|
xcodegen generate
|
|
open Marks.xcodeproj
|
|
```
|
|
|
|
Then build and run in Xcode. The project uses automatic signing — set your development team in `project.yml` under `DEVELOPMENT_TEAM`.
|
|
|
|
## Architecture
|
|
|
|
- **SwiftUI** with `@Observable` and `@MainActor` throughout (Swift 6 strict concurrency)
|
|
- **LinkdingAPI** — thin wrapper around the linkding REST API
|
|
- **ClaudeService** — OpenRouter client for AI enrichment, semantic search, and collections
|
|
- **BookmarksViewModel** — central state: bookmarks list, pagination, search, enrichment progress
|
|
- **App Groups** — share extension and main app share credentials via `group.com.magicive.marks`
|
|
- **UserDefaults** — AI summaries and tags cached locally by bookmark ID
|
|
|
|
## Project structure
|
|
|
|
```
|
|
Marks/
|
|
Models/ Bookmark, ServerConfig, SmartCollection
|
|
Services/ LinkdingAPI, ClaudeService
|
|
Views/ BookmarksView, TagsView, SearchView, SettingsView, …
|
|
Assets.xcassets App icon and assets
|
|
ShareExtension/ iOS share extension (zero-tap bookmark saving)
|
|
project.yml xcodegen project spec
|
|
```
|