# EffemKit Swift client for the Effem AT Protocol AppView. Provides social podcasting features — subscriptions, comments, recommendations, bookmarks, curated lists, and profiles — built on the AT Protocol. ## Requirements - Swift 6.2+ - iOS 26+ / macOS 26+ / watchOS 26+ / tvOS 26+ ## Dependencies - [CoreATProtocol](https://tangled.org/@sparrowtek.com/CoreATProtocol) — AT Protocol primitives, OAuth, networking ## Installation Add EffemKit as a dependency in your `Package.swift`: ```swift dependencies: [ .package(url: "https://tangled.org/@sparrowtek.com/EffemKit", branch: "main"), ] ``` Or add it as a local package in Xcode. ## Quick Start ### 1. Configure the AppView ```swift import EffemKit import CoreATProtocol // At app launch Task { @APActor in setup(appViewHost: "https://appview.effem.xyz") } ``` ### 2. Read Data ```swift @APActor func loadTrending() async throws -> [PodcastResult] { let service = EffemService() let response = try await service.getTrending(max: 20) return response.feeds } ``` ### 3. Write Data (requires authentication) ```swift @APActor func subscribe(feedId: Int, userDID: String) async throws { let repoService = EffemRepoService() let podcast = PodcastRef(feedId: feedId) _ = try await repoService.subscribe(to: podcast, repo: userDID) } ``` ## Architecture EffemKit uses a two-router architecture: | Path | Service | Target | Auth Required | |------|---------|--------|--------------| | Read | `EffemService` | Effem AppView | No | | Write | `EffemRepoService` | User's PDS | Yes | **Reads** go to the Effem AppView, which indexes social records from the AT Protocol firehose and proxies Podcast Index metadata enriched with social overlay data. **Writes** go to the authenticated user's PDS using standard `com.atproto.repo.createRecord` / `deleteRecord` calls. The AppView picks up new records asynchronously via the firehose. All public API is isolated to `@APActor` for thread safety. ## API Overview ### EffemService (Read) | Category | Methods | |----------|---------| | Subscriptions | `getSubscriptions`, `getSubscribers` | | Comments | `getComments`, `getCommentThread` | | Recommendations | `getRecommendations`, `getPopular` | | Lists | `getList`, `getLists` | | Bookmarks | `getBookmarks` | | Inbox | `getInbox` | | Profiles | `getProfile` | | Podcast Search | `searchPodcasts`, `searchEpisodes` | | Podcast Metadata | `getPodcast`, `getEpisodes`, `getEpisode`, `getTrending`, `getCategories` | ### EffemRepoService (Write) | Category | Methods | |----------|---------| | Subscriptions | `subscribe`, `unsubscribe` | | Comments | `postComment`, `deleteComment` | | Recommendations | `recommend`, `unrecommend` | | Bookmarks | `bookmark`, `removeBookmark` | | Lists | `createList`, `deleteList` | | Profile | `updateProfile` | ## Lexicon Namespace All Effem records use the `xyz.effem.*` namespace: - `xyz.effem.feed.subscription` - `xyz.effem.feed.comment` - `xyz.effem.feed.recommendation` - `xyz.effem.feed.bookmark` - `xyz.effem.feed.list` - `xyz.effem.actor.profile` ## Documentation Build the DocC documentation: ```bash swift package generate-documentation ``` Or in Xcode: Product > Build Documentation. ## Testing ```bash swift test ``` 15 tests across 8 suites covering model decoding, round-tripping, serialization, and AT URI generation.