openjutsu
영상에서 원클릭으로 인물 교체, ComfyUI·MiniMax H3 기반 오픈소스 로컬 힉스필드 겐주츠 대안, FLUX.3 Klein 재조명 지원
PodHaven을 만나보세요: 기기 내 추천, 스마트 리스트, 조절 가능한 무음 건너뛰기, CarPlay 지원으로 듣기를 내 방식대로
Meet PodHaven: on-device recommendations, Smart Lists, configurable silence skipping, and CarPlay. Make every listen your own.
미디어Swift · PythonGitHub @jubishop온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
A modern podcast app for iOS, built with Swift and SwiftUI — discover, subscribe, and listen with ML-powered recommendations, offline downloads, queue, tags, widgets, and OPML import/export.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다.
README 전문 보기 ↗PodHaven is a modern podcast application for iOS, built with Swift and SwiftUI. It provides a clean and intuitive interface for discovering, subscribing to, and listening to your favorite podcasts.
Website: artisanalsoftware.com/podhaven
git clone https://github.com/jubishop/podhaven.git
cd podhaven
bin/setup
bin/check --full
open PodHaven.xcodeproj
Cmd+R in Xcode to build and run the app in the simulator.For more advanced users, here are the commands to build and test from the command line.
Use bin/check --documents-only for Markdown edits and bin/check for fast
static checks. Use focused Swift and tooling checks during development.
Before pushing, merging, or releasing functionally material changes, run
bin/test-all --ensure --revision <sha> for the final clean revision. It
requires the full app, macro, tooling, and skill suites to pass without skipped
tests or Swift warnings. Documentation, comments, and formatting-only changes
use relevant focused checks. GitHub does not run test CI. Follow the
validation policy
and test workflow.
env -u SDKROOT xcodebuild build-for-testing -hideShellScriptEnvironment -project PodHaven.xcodeproj -scheme PodHaven -destination 'platform=macOS,name=My Mac' LM_FORCE_LINK_GENERATION=YES
Run the complete local validation from the repository root:
bin/test-all
Logs, the Xcode result bundle, and the tested checkout are recorded under
.cache/test-all/.
Swift Testing filters must stay at suite level; method-level filters can report success while running zero tests.
bin/with-my-mac-lock env -u SDKROOT xcodebuild test -hideShellScriptEnvironment -project PodHaven.xcodeproj -scheme PodHaven -destination 'platform=macOS,name=My Mac' -skipMacroValidation -only-testing:PodHavenTests/SomeSuite -resultBundlePath .cache/FocusedTests.xcresult LM_FORCE_LINK_GENERATION=YES > .cache/focused-tests.log 2>&1
bin/check-swift-results .cache/FocusedTests.xcresult --build-log .cache/focused-tests.log
Use a new result-bundle path for each run. bin/with-my-mac-lock waits for any
other My Mac test run on this Mac to finish first.
Print the current app version:
bin/version
Set the next app version across all targets and build configurations:
bin/version 1.0.1
This changes the app version (MARKETING_VERSION). The command rejects invalid
or older versions. Use bin/version --help for usage.
Commit your changes, then test, archive, upload, and distribute a build to the external Everyone group:
bin/shipit
Before any version change or build, the command writes TestFlight "What to Test"
notes with llm: one or two plain sentences about the app changes since the
newest build testers already have. In a terminal it shows the notes and lets
you use them, edit them in your editor, or stop. If that newest build is the one this run would distribute,
the command stops with nothing to do. Supply your own notes instead with:
bin/shipit --notes "Improved playback reliability."
The command checks the existing external Everyone group before building. After upload, it checks processing every 30 seconds for up to two hours, adds the notes, submits for beta review when needed, and verifies the group assignment. Testers are notified when Apple makes the build available. Apple beta review can remain pending after the command finishes. Notes must be nonblank and at most 4000 bytes.
If processing times out or distribution fails after upload, rerun the same command from the same clean commit. It reuses the uploaded build. A single local upload receipt in Git's metadata directory supports retries; each new upload replaces it.
bin/shipit increments the build number automatically. If Apple closes a version
for external beta review, use bin/version to set a higher app version, commit it,
and upload a new build. Successful runs also publish the Git tag and GitHub
release. The generated GitHub release summary remains separate from the
TestFlight notes.
Other options:
| Option | Behavior |
|---|---|
-h, --help | Show usage without building or uploading. |
-f, --force | Allow a branch other than main. A clean working tree is still required. |
--api-key PATH --api-key-id ID --api-issuer-id ID | Authenticate with an App Store Connect API key. Supply all three options together. |
The API key options can also be set with ASC_KEY_PATH, ASC_KEY_ID, and
ASC_ISSUER_ID. Keep private keys outside the repository. Without a key, uploads
use Xcode's Apple ID login. Distribution uses Fastlane's own Apple ID login and
may request two-factor authentication; FASTLANE_USER selects the Apple ID.
An App Manager or Admin role is needed for external distribution. Fastlane is
required; install it with brew install fastlane.
bin/shipit and bin/deploy.sh are aliases and accept the same options.
Release the next minor version with generated "What's New" notes:
bin/appstore
The command requires clean main. It increments the minor version (2.1.2
becomes 2.2), commits and pushes the version change, tests, archives, uploads,
waits for that exact build to finish processing, and submits for App Review.
Apple releases it automatically after approval.
Override the release number or public "What's New" notes when needed:
bin/appstore --notes "Improved playback reliability."
bin/appstore --release 3 --notes "A new major release."
--release must be strictly greater than the current version and have zero or
one dot. Without --notes, the command writes a few plain-language bullets with
llm about the app changes since the live App Store build, before changing
anything. In a terminal you can use, edit, or decline them. Public notes must
contain 1 to 4000 characters and are used for every existing listing language.
First, the command checks for app commits that the newest build in testing for
Everyone lacks. It shows when that build went out, when the newer commits
landed, and what they change, then asks whether to release anyway. Without a
terminal, it stops instead; run bin/shipit first to give testers those
changes.
Show the live version, pending versions and reviews, and uploaded builds for the current local app version without releasing:
bin/appstore --status
To submit an exact existing build, use --release VERSION --build NUMBER.
This skips the version change and upload. The build must match that version.
The description, screenshots, and other listing metadata carry over. Only the build, release setting, and "What's New" text are updated. The command verifies Apple's saved build, notes, release setting, and submission state before reporting success. It does not wait for Apple to complete App Review.
The build must be App Store eligible with export compliance already complete. Apple can still require changes to listing or review information before accepting a submission; the command reports those errors.
If a run stops, use bin/appstore --status to inspect the state, then retry the
same command. It retains the chosen version, notes, and exact build across
retries, including after a failed version push. See
Versioning and releases for the complete workflow and retry rules.
Fastlane is required (brew install fastlane). Authentication uses the same
--api-key, --api-key-id, and --api-issuer-id options and ASC_* environment
variables described above. Without a key, it uses Fastlane's Apple ID login.
Use bin/appstore --help for all options.
PodHaven is built using modern Swift practices and a clean, modular architecture.
@Observable) with Factory for dependency injection.async/await).ReadableError conformance and state management.ReadableError protocol and ErrorKit, with Sentry integration for production error reporting.OSLog with structured file logging and Sentry forwarding.| Target | Description |
|---|---|
| PodHaven | Main iOS app |
| PodhavenShare | Share extension for adding podcasts from other apps |
| PodHavenWidget | Home screen widget extension |
| PodHavenMacros | Swift macro compilation target |
| PodHavenTests | Parallelized test suite |
| Package | Purpose |
|---|---|
| GRDB.swift | SQLite database management |
| XMLCoder | RSS feed parsing |
| Nuke | Image loading and caching |
| Factory | Dependency injection |
| Tagged | Type-safe identifiers |
| Sentry | Error reporting and crash analytics |
| IdentifiedCollections | Collection utilities |
| OrderedCollections | Foundation collection extensions |
| Semaphore | Concurrency utilities |
| swift-sharing | Shared state management |
| swift-log | Structured logging |
| swift-navigation | Navigation utilities |
| swift-algorithms | Algorithm utilities |
Tests use the Swift Testing framework with the @Suite / #expect DSL. The test plan runs all suites in parallel. An in-memory GRDB database (AppDB.inMemory()) powers repository tests, and Factory overrides with .context(.test) provide test fakes.
Contributions are welcome! If you have a feature request, bug report, or want to contribute to the code, please feel free to open an issue or submit a pull request.
This project is licensed under a Source Available License. You are free to view, study, and contribute to the code, but commercial use, redistribution, and derivative works (outside of contributions) are not permitted. See the LICENSE file for full details.
Copyright (c) 2026 Justin Bishop. All rights reserved.