3c7a783b6cf5a5330042b8417dcc94bc3c2aac1c
Two changes. Tapping a card did nothing. LibraryCard carried its own press-scale effect via onLongPressGesture(minimumDuration: 0), and a zero-duration long press fires immediately and swallows the tap the host attaches. It was invisible in the prototype because nothing was listening for taps there. LibraryCard is now purely presentational and the grid wraps it in a Button with the existing RowPressStyle, which gets the same scale without competing for the gesture. The list now speaks the same design as the cards: paper ground, the color chip where the favicon was, serif quoted title, monospaced domain/date, serif-italic AI summary, monospaced tag chips. Everything the old row carried is still there — unread state, excerpt, tags, podcast affordance, reading progress — along with all swipe actions, since it is still a List. BookmarkListRow takes a style rather than being rewritten, because the Tags and Search screens use the same row and should not be silently restyled by a change aimed at the bookmarks screen. The tag filter strip moved up to BookmarksView. Both layouts speak the same language now, so the strip belongs to the screen rather than to one mode — which also retires the rule that leaving cards mode had to clear the tag filter to stop it becoming invisible. The tag chip strip fades at its trailing edge; without it a tag clipped mid-word reads as broken text rather than as something scrollable. Verified in both layouts and both color schemes against the live server. Full suite passes (16 tests). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JgLHztZGaEHvS3KNeGQmRM
Marks
A native iOS client for 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 instance with API access
- (Optional) An OpenRouter API key for AI features
AI Features
All AI features are optional and powered by OpenRouter 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.
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
@Observableand@MainActorthroughout (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
Description
Native iOS client for linkding — SwiftUI, iOS 26, AI enrichment via OpenRouter
2.8 MiB
Languages
Swift
97.7%
Shell
1.4%
HTML
0.9%