RepoPilotOpen in app →

longitachi/ZLPhotoBrowser

Wechat-like image picker. Support select photos, videos, gif and livePhoto. Support edit image and crop video. 微信样式的图片选择器,支持预览/相册内拍照及录视频、拖拽/滑动选择,编辑图片/视频,支持多语言国际化等功能;

Healthy

Healthy across the board

Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained — safe to depend on.

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 3w ago
  • 7 active contributors
  • Apache-2.0 licensed
Show 3 more →
  • CI configured
  • Tests present
  • Concentrated ownership — top contributor handles 68% of recent commits

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Healthy" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/longitachi/zlphotobrowser)](https://repopilot.app/r/longitachi/zlphotobrowser)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/longitachi/zlphotobrowser on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: longitachi/ZLPhotoBrowser

Generated by RepoPilot · 2026-05-10 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/longitachi/ZLPhotoBrowser shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

GO — Healthy across the board

  • Last commit 3w ago
  • 7 active contributors
  • Apache-2.0 licensed
  • CI configured
  • Tests present
  • ⚠ Concentrated ownership — top contributor handles 68% of recent commits

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live longitachi/ZLPhotoBrowser repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/longitachi/ZLPhotoBrowser.

What it runs against: a local clone of longitachi/ZLPhotoBrowser — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in longitachi/ZLPhotoBrowser | Confirms the artifact applies here, not a fork | | 2 | License is still Apache-2.0 | Catches relicense before you depend on it | | 3 | Default branch master exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 54 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>longitachi/ZLPhotoBrowser</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of longitachi/ZLPhotoBrowser. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/longitachi/ZLPhotoBrowser.git
#   cd ZLPhotoBrowser
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of longitachi/ZLPhotoBrowser and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "longitachi/ZLPhotoBrowser(\\.git)?\\b" \\
  && ok "origin remote is longitachi/ZLPhotoBrowser" \\
  || miss "origin remote is not longitachi/ZLPhotoBrowser (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(Apache-2\\.0)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"Apache-2\\.0\"" package.json 2>/dev/null) \\
  && ok "license is Apache-2.0" \\
  || miss "license drift — was Apache-2.0 at generation time"

# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 4. Critical files exist
test -f "Sources/ZLPhotoBrowser" \\
  && ok "Sources/ZLPhotoBrowser" \\
  || miss "missing critical file: Sources/ZLPhotoBrowser"
test -f "Sources/ZLPhotoBrowser/ZLPhotoBrowser.swift" \\
  && ok "Sources/ZLPhotoBrowser/ZLPhotoBrowser.swift" \\
  || miss "missing critical file: Sources/ZLPhotoBrowser/ZLPhotoBrowser.swift"
test -f "Sources/ZLPhotoBrowser/ZLPhotoConfiguration.swift" \\
  && ok "Sources/ZLPhotoBrowser/ZLPhotoConfiguration.swift" \\
  || miss "missing critical file: Sources/ZLPhotoBrowser/ZLPhotoConfiguration.swift"
test -f "Sources/ZLPhotoBrowser/PhotoManager" \\
  && ok "Sources/ZLPhotoBrowser/PhotoManager" \\
  || miss "missing critical file: Sources/ZLPhotoBrowser/PhotoManager"
test -f "Example/Example/AppDelegate.swift" \\
  && ok "Example/Example/AppDelegate.swift" \\
  || miss "missing critical file: Example/Example/AppDelegate.swift"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 54 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~24d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/longitachi/ZLPhotoBrowser"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

ZLPhotoBrowser is a WeChat-style image and media picker written in Swift that allows users to select photos, videos, GIFs, and Live Photos from the device library or camera. It provides built-in editors for cropping videos and editing images (with tools for drawing, text stickers, filters, mosaics, and adjustments), plus a custom camera interface—solving the need for a production-grade, highly customizable iOS media selection flow without rolling your own. Modular Swift package with CocoaPods/Carthage/SPM support. Core library likely lives in the root ZLPhotoBrowser/ directory (not shown in detail), while Example/Example/ contains a runnable demo app with sample stickers and assets. CHANGELOG.md, README, and .github/ suggest community-facing workflows.

👥Who it's for

iOS developers (Swift primary, Objective-C secondary) building consumer apps that need WeChat-like media pickers with advanced editing capabilities, particularly those targeting Chinese markets or wanting a polished, feature-rich alternative to the native photo picker.

🌱Maturity & risk

Actively maintained and production-ready. The repo shows ~1.9M lines of Swift code, supports multiple distribution methods (CocoaPods, Carthage, SPM), includes a full Example app, and has SwiftUI support. However, the file list does not expose recent commit dates or test suite coverage, so assess CI/test presence before shipping to critical paths.

Single-maintainer risk (longitachi) is the primary concern for long-term maintenance. The codebase is large (~1.9M Swift LoC) with potential for high complexity in media handling (camera, photo library, video processing) and iOS version-specific edge cases. No visible test coverage metrics or CI pipeline details in the provided file list.

Active areas of work

Cannot determine from the file list alone—no recent commit data, open PR list, or issue tracker snapshots provided. Check the GitHub releases page and CHANGELOG.md for the latest version details.

🚀Get running

Clone the repo, then open Example/Example.xcodeproj in Xcode and run on a simulator or device. For integration: add via CocoaPods (pod 'ZLPhotoBrowser'), Carthage, or SPM; see README and Wiki for language-specific setup.

Daily commands: Open Example/Example.xcodeproj in Xcode → Select a simulator or physical device → Cmd+R. The Example app has pre-loaded sample images (image1.png, image2.png, image3.png in Assets.xcassets) and sticker packs (imageSticker1 through imageSticker15) for demo.

🗺️Map of the codebase

  • Sources/ZLPhotoBrowser — Main library entry point directory containing all core photo browser functionality and UI components
  • Sources/ZLPhotoBrowser/ZLPhotoBrowser.swift — Root view controller and primary API for launching the photo picker—every integration starts here
  • Sources/ZLPhotoBrowser/ZLPhotoConfiguration.swift — Central configuration object controlling all picker behavior, styling, and feature flags—required reading to understand customization
  • Sources/ZLPhotoBrowser/PhotoManager — Photo and video asset management layer—handles all PHAsset queries, permissions, and media retrieval
  • Example/Example/AppDelegate.swift — Example app entry point demonstrating real-world integration patterns and permission setup
  • .swiftpm/xcode/package.xcworkspace — Swift Package Manager configuration—defines module structure and iOS deployment target
  • Sources/ZLPhotoBrowser/ImageEditor — Image editing pipeline supporting crop, filter, and annotation—complex UI state management

🛠️How to make changes

Add a new language localization

  1. Create a new .lproj folder in Sources/ZLPhotoBrowser/Resources/ (e.g., fr.lproj for French) (Sources/ZLPhotoBrowser/Resources/fr.lproj/Localizable.strings)
  2. Copy all English strings from Sources/ZLPhotoBrowser/Resources/en.lproj/Localizable.strings and translate each value (Sources/ZLPhotoBrowser/Resources/en.lproj/Localizable.strings)
  3. Update ZLPhotoConfiguration.languageType enum in ZLPhotoConfiguration.swift to include the new language case (Sources/ZLPhotoBrowser/ZLPhotoConfiguration.swift)
  4. Register the language in ZLPhotoLanguageManager (maps configuration to bundle lookup) (Sources/ZLPhotoBrowser/General/ZLPhotoLanguageManager.swift)

Add a custom image filter to the editor

  1. Create a new Swift file in Sources/ZLPhotoBrowser/ImageEditor/ (e.g., CustomFilter.swift) (Sources/ZLPhotoBrowser/ImageEditor/CustomFilter.swift)
  2. Implement filter logic using CIImage and CIFilter, following the pattern in existing filters (brightness, saturation, etc.) (Sources/ZLPhotoBrowser/ImageEditor/ZLPhotoEditorImageVC.swift)
  3. Register the filter in the filter cell array of ZLPhotoEditorImageVC.setupFilterView() method (Sources/ZLPhotoBrowser/ImageEditor/ZLPhotoEditorImageVC.swift)
  4. Add UI button/slider in the editor toolbar and wire it to apply the filter via processImage(_:) (Sources/ZLPhotoBrowser/ImageEditor/ZLPhotoEditorImageVC.swift)

Customize the theme colors and fonts

  1. Create a ZLPhotoConfiguration instance and set themeColorDark, themeColor, textColor, and other UI properties (Example/Example/ViewController.swift)
  2. Call ZLPhotoConfiguration.default().configureDefaultUI() to apply theme defaults, then override specific colors (Sources/ZLPhotoBrowser/ZLPhotoConfiguration.swift)
  3. Pass the configured object to ZLPhotoBrowserViewController(config: myConfig) (Sources/ZLPhotoBrowser/ZLPhotoBrowser.swift)
  4. Verify theme is applied by checking ZLPhotoUIConfiguration singleton which reads from ZLPhotoConfiguration.default() (Sources/ZLPhotoBrowser/General/ZLPhotoUIConfiguration.swift)

Add support for a new media format (e.g., AVIF)

  1. Update ZLPhotoConfiguration.mediaType enum to include the new format type if not already using a generic type (Sources/ZLPhotoBrowser/ZLPhotoConfiguration.swift)
  2. Modify PhotoManager's asset fetching predicates to include the new UTType in the PHAssetMediaType filter (Sources/ZLPhotoBrowser/PhotoManager/ZLAssetManager.swift)
  3. Extend ZLImageSaveUtil.save() to handle encoding to the new format using ImageIO and appropriate codec settings (Sources/ZLPhotoBrowser/General/ZLImageSaveUtil.swift)
  4. Test export by capturing and editing an image, then verifying the output file format (Example/Example/ViewController.swift)

🔧Why these technologies

  • Swift (UIKit + AVFoundation + Photos framework) — Native iOS APIs provide direct access to Photos library, camera hardware, and efficient real-time media processing; minimal dependency overhead
  • PHAsset & PHAssetCollection (Photos Framework) — Apple's official API for enumerating and loading photos/videos from library with built-in caching and efficient thumbnail generation
  • AVFoundation (AVAssetExportSession, AVCaptureSession) — Hardware-accelerated video recording, trimming, and export; camera preview and frame capture without third-party dependencies
  • Core Image (CIFilter, CIImage) — GPU-accelerated image filtering and processing; low-latency real-time preview during editing
  • ImageIO (CGImageSourceCreateWithURL, CGImageDestination) — Format-agnostic image encoding/decoding supporting JPEG, PNG, GIF, HEIC, AVIF; respects original image orientation
  • SwiftPM + CocoaPods + Carthage — Multi-distribution support; codebase designed to be package-agnostic for broad ecosystem adoption

⚖️Trade-offs already made

  • Use UICollectionView for photo grid instead of LazyVGrid (SwiftUI)
    • Why: Fine-grained control over cell lifecycle, drag-to-select gesture handling, and memory-efficient recycling of thousands of thumbnails
    • Consequence: Requires UIViewController-based integration; higher boilerplate than SwiftUI but superior scroll performance on older devices

🪤Traps & gotchas

  1. Media library access requires Privacy-PhotoLibrary and Privacy-Camera Info.plist keys; missing these will cause runtime crashes. 2) Video editing and cropping depend on AVFoundation/AVPlayer; ensure you handle video codec compatibility (not all formats may transcode smoothly). 3) Live Photo support requires iOS 9.1+ and may fail silently on older devices. 4) The editor's filter effects and mosaic tools are computationally expensive—large images may cause UI lag if not properly throttled. 5) Custom camera requires Privacy-Camera and may conflict with other camera libraries if not properly managed.

🏗️Architecture

💡Concepts to learn

  • yohoho/DouYin — A TikTok-like short video editor using similar Swift/AVFoundation patterns for video selection and cropping.
  • longitachi/ZLImageEditor — Extracted image editing module from ZLPhotoBrowser; a standalone library if you only need the image editor without the picker UI.
  • AnyImageKit/AnyImageKit — A competing Chinese-developed media picker library with similar WeChat-style UX and image editing, useful for feature comparison.
  • alexiscn/WeChatSwift — A WeChat-inspired Swift app that demonstrates similar media browsing and editing patterns in a full-app context.
  • apple/swift-package-manager — ZLPhotoBrowser is SPM-compatible; understanding SPM helps with version pinning and dependency resolution in Xcode projects.

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add comprehensive unit tests for ZLPhotoBrowser core classes

The repo has an Example project but no visible test target or unit tests for core functionality like photo selection, video editing, and image cropping. This is critical for a widely-used library to ensure reliability across iOS versions and prevent regressions.

  • [ ] Create a new test target in the Example.xcodeproj
  • [ ] Write unit tests for photo/video selection logic (likely in Sources/ directory)
  • [ ] Add tests for image editing and crop video functionality
  • [ ] Add tests for the multi-language localization system mentioned in the description
  • [ ] Set up GitHub Actions workflow to run tests on each PR (since .travis.yml exists but GitHub Actions is preferred)

Implement GitHub Actions CI/CD workflow with Xcode build and test

The repo has .travis.yml indicating past CI setup, but .github/ISSUE_TEMPLATE.MD is present without a workflows/ directory. Modern Swift/iOS projects use GitHub Actions. This ensures contributors get fast feedback on build status and SwiftPM compatibility across platforms.

  • [ ] Create .github/workflows/build-and-test.yml for running Xcode builds
  • [ ] Include matrix testing for iOS 14+ minimum deployment targets
  • [ ] Add SwiftPM build verification (since .swiftpm/xcode/package.xcworkspace exists)
  • [ ] Add CocoaPods pod spec validation step
  • [ ] Include Carthage compatibility check (badge shows it's supported)

Create detailed API documentation for image editing and video cropping modules

The README mentions 'edit image/crop video' as key features, but there's no visible inline documentation or separate guide. The wiki link references 'How-to-use' but specific examples for the editing/cropping APIs are likely missing, making it hard for contributors to extend these features.

  • [ ] Add Swift doc comments (///) to all public image editing classes/methods
  • [ ] Add Swift doc comments to video cropping APIs with parameter descriptions
  • [ ] Create EDITING_GUIDE.md in the repo root with code examples for image filters and crop operations
  • [ ] Document the gesture handling system for drag/slide selection mentioned in description
  • [ ] Add inline code examples showing how to customize editing UI colors and styles

🌿Good first issues

  • Add unit tests for the image editor's filter pipeline (Brightness, Contrast, Saturation adjustments)—currently no test files visible in the list; start by testing the filter effect application logic in a hypothetical Tests/ directory.
  • Expand the localization system beyond the documented languages by adding new .lproj folders and Localizable.strings files; the README mentions 'multi-language' but no .strings files are visible—this is low-risk, high-visibility work.
  • Add comprehensive inline documentation/docstrings to the public configuration classes (e.g., those controlling max selection count, video duration constraints, column layout). The README lists these features but no doc comments are evident in the file list.

Top contributors

Click to expand

📝Recent commits

Click to expand
  • e0ecc00 — Merge pull request #1046 from tac-han/xx/scale (longitachi)
  • fc20ec1 — fix #1045 (p_xiaohhhan)
  • 18b1243 — Fix #1042 (longitachi)
  • aa54702 — Add thumbVCAllowPanToDismiss property to control whether the thumbnail interface allows swiping back from the edge. (longitachi)
  • 58e03d9 — Update README (longitachi)
  • 21360c8 — Bumped version to 4.7.4 (longitachi)
  • 5ee2428 — Merge pull request #1036 from hstdt/theme (longitachi)
  • b472d2a — Fix done button theme color (hstdt)
  • 37bb48b — Some minor update (longitachi)
  • 2c2a9ff — Create LICENSE (longitachi)

🔒Security observations

The ZLPhotoBrowser iOS image picker library shows reasonable security posture based on available information. No obvious hardcoded secrets, SQL injection risks, or XSS vulnerabilities are apparent from the file structure. The primary security concern is the inability to audit dependencies due to missing or empty dependency file content. The codebase appears to follow standard iOS project structure with proper asset management. Recommendations focus on implementing dependency vulnerability scanning, ensuring CI/CD security, and verifying that no sensitive configuration data is embedded in project files.

  • Medium · Missing dependency information for security audit — Package dependencies configuration (not provided). The Package.swift or Podfile dependency file content is empty, making it impossible to verify if the project uses outdated or vulnerable dependencies. Without visible dependency declarations, potential security vulnerabilities in third-party libraries cannot be assessed. Fix: Ensure all dependencies are explicitly declared and regularly updated. Use tools like CocoaPods, SPM, or Carthage vulnerability scanners to check for known vulnerabilities. Implement automated dependency checking in CI/CD pipeline.
  • Low · Build configuration files exposed — Example/Example.xcodeproj/project.pbxproj, Example/Example.xcodeproj/project.xcworkspace/. Project configuration files (.pbxproj, .xcworkspace) are tracked in version control. While not inherently dangerous, these files may contain sensitive build settings or paths that could be exploited. Fix: Review .pbxproj and workspace files to ensure no hardcoded secrets, API keys, or sensitive paths are included. Use build configuration files and environment variables for sensitive settings instead.
  • Low · Travis CI configuration present but incomplete — .travis.yml. The .travis.yml file indicates CI/CD setup, but without seeing its contents, security best practices for CI/CD cannot be verified (e.g., secure credential handling, signed commits). Fix: Ensure Travis CI configuration uses encrypted environment variables for secrets, implements branch protection rules, verifies commit signatures, and doesn't expose sensitive information in logs.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.