hilen/TSWeChat
A WeChat alternative. Written in Swift 5.
Stale — last commit 7y ago
worst of 4 axeslast commit was 7y ago; no tests detected…
no tests detected; no CI workflows detected…
Documented and popular — useful reference codebase to read through.
last commit was 7y ago; no CI workflows detected
- ✓9 active contributors
- ✓Distributed ownership (top contributor 42% of recent commits)
- ✓MIT licensed
Show 3 more →Show less
- ⚠Stale — last commit 7y ago
- ⚠No CI workflows detected
- ⚠No test directory detected
What would change the summary?
- →Use as dependency Mixed → Healthy if: 1 commit in the last 365 days; add a test suite
- →Fork & modify Mixed → Healthy if: add a test suite
- →Deploy as-is Mixed → Healthy if: 1 commit in the last 180 days
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 "Great to learn from" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/hilen/tswechat)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/hilen/tswechat on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: hilen/TSWeChat
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:
- 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. - 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.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/hilen/TSWeChat 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
WAIT — Stale — last commit 7y ago
- 9 active contributors
- Distributed ownership (top contributor 42% of recent commits)
- MIT licensed
- ⚠ Stale — last commit 7y ago
- ⚠ No CI workflows detected
- ⚠ No test directory detected
<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 hilen/TSWeChat
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/hilen/TSWeChat.
What it runs against: a local clone of hilen/TSWeChat — 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 hilen/TSWeChat | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | 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 ≤ 2508 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of hilen/TSWeChat. If you don't
# have one yet, run these first:
#
# git clone https://github.com/hilen/TSWeChat.git
# cd TSWeChat
#
# 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 hilen/TSWeChat and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "hilen/TSWeChat(\\.git)?\\b" \\
&& ok "origin remote is hilen/TSWeChat" \\
|| miss "origin remote is not hilen/TSWeChat (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift — was MIT 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 "Podfile" \\
&& ok "Podfile" \\
|| miss "missing critical file: Podfile"
test -f "Pods/Alamofire/Source/SessionManager.swift" \\
&& ok "Pods/Alamofire/Source/SessionManager.swift" \\
|| miss "missing critical file: Pods/Alamofire/Source/SessionManager.swift"
test -f "Pods/ObjectMapper/Sources/Mappable.swift" \\
&& ok "Pods/ObjectMapper/Sources/Mappable.swift" \\
|| miss "missing critical file: Pods/ObjectMapper/Sources/Mappable.swift"
test -f "Pods/RxBlocking/RxBlocking/BlockingObservable.swift" \\
&& ok "Pods/RxBlocking/RxBlocking/BlockingObservable.swift" \\
|| miss "missing critical file: Pods/RxBlocking/RxBlocking/BlockingObservable.swift"
test -f "Pods/KeychainAccess/Lib/KeychainAccess/Keychain.swift" \\
&& ok "Pods/KeychainAccess/Lib/KeychainAccess/Keychain.swift" \\
|| miss "missing critical file: Pods/KeychainAccess/Lib/KeychainAccess/Keychain.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 2508 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~2478d)"
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/hilen/TSWeChat"
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).
⚡TL;DR
TSWeChat is a functional WeChat alternative written in Swift 5 that implements real-time messaging with rich media support (text, images, voice). It demonstrates iOS native UI patterns including custom input keyboards, image masking for chat cells, voice file conversion (WAV to AMR), and offline-first caching strategies using Kingfisher and Alamofire. MVC-style monolith organized by business domain: Classes/ contains ViewController + View subfolders split into Message, Address Book, Tabbar, Me, Login; Classes/CoreModule/ centralizes HttpManager, Models, and ApplicationManager; Helpers/ provides reusable extensions (UIView, UIImage); Resources/ holds JSON chat data, Assets, and plist config. Data flows from JSON files through ObjectMapper into Models.
👥Who it's for
iOS developers learning Swift 5 architecture patterns, particularly those building messaging apps who need reference implementations for custom input accessories, media handling, and chat UI components. Also useful for developers in China/Asia familiar with WeChat who want to understand native iOS equivalents.
🌱Maturity & risk
Experimental/learning project, not production-ready. The repo shows Swift 5 compatibility badges and targets iOS 8.0+ (now outdated—current iOS is 17+). No visible test suite, CI pipeline is referenced but appears minimal, and commit history is not shown—suggests this is a historical portfolio/educational project rather than actively maintained.
Moderate risk for learning/fork purposes. Heavy reliance on aging CocoaPods dependencies (Alamofire, Kingfisher, ObjectMapper, INTULocationManager)—many now have Swift Package Manager alternatives. Single maintainer (@hilenlai) with no visible test coverage means bugs in edge cases (voice conversion, media caching) are uncaught. Dependencies like KeychainAccess and Dollar.swift add complexity without clear necessity.
Active areas of work
No active development visible in file list. The README mentions Swift 5 update but shows legacy iOS 8.0 target compatibility, suggesting the last meaningful commit was 3+ years ago. The project appears frozen as a historical reference/portfolio piece.
🚀Get running
git clone https://github.com/hilen/TSWeChat.git
cd TSWeChat
pod install
open TSWeChat.xcworkspace
Then build and run in Xcode 10.0+ on iOS 10.0+ simulator or device.
Daily commands:
No traditional dev server. Run in Xcode: open TSWeChat.xcworkspace → select scheme → build to simulator (Cmd+B) or device (Cmd+R). App loads hardcoded JSON data from Resources/. No environment variables or config required beyond CocoaPods setup.
🗺️Map of the codebase
Podfile— Defines all CocoaPods dependencies (Alamofire, RxSwift, Kingfisher, ObjectMapper) essential to understanding the tech stack and build configurationPods/Alamofire/Source/SessionManager.swift— Core networking abstraction layer used throughout the app for all HTTP requests; understand this for any API integration workPods/ObjectMapper/Sources/Mappable.swift— Protocol-based JSON mapping framework used across data models; critical for understanding how API responses map to Swift objectsPods/RxBlocking/RxBlocking/BlockingObservable.swift— Reactive programming foundation used for asynchronous event streams in the chat architecturePods/KeychainAccess/Lib/KeychainAccess/Keychain.swift— Secure credential storage for authentication tokens and user data persistencePods/Kingfisher/Sources/Kingfisher.h— Image caching and asynchronous loading library critical for chat media (images, voice messages) performancePods/INTULocationManager/LocationManager/INTULocationManager/INTULocationManager.h— Location services API used for location sharing features in chat messages
🛠️How to make changes
Add a new API endpoint
- Create a data model struct conforming to ObjectMapper's Mappable protocol in your Models directory (
Pods/ObjectMapper/Sources/Mappable.swift) - Use Alamofire SessionManager in your API service to make HTTP requests and map responses (
Pods/Alamofire/Source/SessionManager.swift) - For complex transformations, define custom TransformType implementations for non-standard fields (
Pods/ObjectMapper/Sources/TransformType.swift) - Wrap API calls in RxBlocking observables for async handling throughout the app (
Pods/RxBlocking/RxBlocking/BlockingObservable.swift)
Add media caching (images/voice)
- Configure Kingfisher for image downloads with memory/disk cache in your app delegate (
Pods/Kingfisher/Sources/Kingfisher.h) - For voice messages, store file paths in Keychain for secure retrieval (
Pods/KeychainAccess/Lib/KeychainAccess/Keychain.swift) - Use Bag collections for managing multiple concurrent download subscriptions (
Pods/RxBlocking/Platform/DataStructures/Bag.swift)
Handle location-based messages
- Request location permissions and fetch coordinates using INTULocationManager (
Pods/INTULocationManager/LocationManager/INTULocationManager/INTULocationManager.h) - Create a Location model with Mappable conformance to serialize lat/lng to JSON (
Pods/ObjectMapper/Sources/Mappable.swift) - Send location as message payload via Alamofire POST request (
Pods/Alamofire/Source/SessionManager.swift)
Add functional utilities to message processing
- Use Dollar.swift utility functions for filtering/transforming message arrays (
Pods/Dollar/Sources/Dollar.swift) - Chain operations with RecursiveLock for thread-safe message list mutations (
Pods/RxBlocking/Platform/RecursiveLock.swift)
🔧Why these technologies
- Swift 5 — Modern, type-safe language for iOS native development with improved performance and concurrency
- Alamofire (HTTP client) — Simplified HTTP networking with automatic request/response serialization, certificate pinning, and connection pooling
- ObjectMapper (JSON parsing) — Declarative JSON-to-Swift object mapping avoiding boilerplate serialization code and type mismatches
- RxSwift/RxBlocking (reactive streams) — Composable async/reactive patterns for chat message streams, user presence, and real-time updates
- Kingfisher (image caching) — Optimized image download, memory + disk caching, and placeholder handling for smooth chat media rendering
- KeychainAccess (secure storage) — Encrypted credential/token storage in iOS Keychain avoiding insecure UserDefaults for auth tokens
- INTULocationManager (geolocation) — Abstracted location permission handling and coordinate acquisition for location-based message features
⚖️Trade-offs already made
-
CocoaPods over SPM
- Why: Broad legacy library compatibility and maturity at time of codebase creation
- Consequence: Larger build footprint and slower dependency resolution than Swift Package Manager; harder to integrate modern packages
-
ObjectMapper over Codable
- Why: Custom transformation logic and nested mapping flexibility for complex server schemas
- Consequence: Adds runtime reflection overhead vs compile-time Codable; more boilerplate than modern Codable patterns
-
RxBlocking observables for message sync
- Why: Centralized reactive stream management for real-time chat updates and subscription lifecycle
- Consequence: Learning curve for reactive patterns; potential for subscription leaks if not properly disposed
-
Separate image caching (Kingfisher) vs manual voice file caching
- Why: Kingfisher optimized for image rendering; voice requires Keychain security and custom playback integration
- Consequence: Dual caching strategies complicate invalidation logic; media type handling spread across frameworks
🚫Non-goals (don't propose these)
- End-to-end encryption (relies on server-side TLS only)
- Offline message persistence (no local SQLite DB visible in dependencies)
- Video calls (no WebRTC or video codec dependencies)
- Real-time presence sync (client polls server; no WebSocket dependency)
- macOS desktop client (iOS-only despite Podfile listing macOS 10.9+ support)
- Transcription of voice messages (no audio processing dependencies)
🪤Traps & gotchas
CocoaPods breaking changes: ObjectMapper, Alamofire, and Kingfisher have evolved significantly since Swift 5 initial release—Podfile versions may not install on Xcode 14+. Voice conversion: WAV→AMR conversion code (likely in Message classes) has OS-level dependencies (AudioToolbox framework) that vary by iOS version. Keychain issues: KeychainAccess may fail silently on simulator if not properly mocked. JSON-only data: App assumes JSON files in Resources/ exist and are well-formed—no error handling for missing/malformed chat data shown. No backend: All features are offline-first; adding real server sync requires rewriting HttpManager and caching strategy.
🏗️Architecture
💡Concepts to learn
- CALayer Masking (Mask Layer) — TSChatImageCell uses mask layers for rounded corners and chat bubble shapes—critical for understanding iOS Core Animation, enabling flexible chat backgrounds without hardcoded images
- Audio Format Conversion (WAV to AMR) — App automatically converts recorded WAV files to AMR for Android compatibility—demonstrates Audio Toolbox framework usage and cross-platform codec understanding
- Image Caching & MD5 Hashing — Kingfisher cache entries keyed by MD5 hash of image URLs—learn how to implement content-addressed storage for offline-first messaging
- ObjectMapper (Swift Model Serialization) — All Models use ObjectMapper for JSON↔Object bidirectional mapping—understanding this pattern is essential for working with data models in the app
- Custom UIResponder Chain & Input Accessory Views — Chat input keyboard and expression picker integrate via inputAccessoryView—critical for understanding iOS text input system and responder chain
- Keychain Secure Storage (KeychainAccess) — Login credentials and sensitive data stored via KeychainAccess wrapper—learn iOS Keychain API abstraction for credential persistence
- Lazy Image Loading & Download Resumption (Alamofire) — Voice cells trigger on-demand downloads with caching; Alamofire handles resumable downloads—demonstrates efficient mobile network usage patterns
🔗Related repos
SlackTextViewController/SlackTextViewController— Reference implementation for custom chat input accessory UIs in Swift; complements TSWeChat's keyboard customization approachMessageViewController/MessagesViewController— Modern Swift chat UI framework with message bubbles and media support; shows how to evolve TSWeChat's MVC approach to production architectureAlamofire/Alamofire— Official networking library used by TSWeChat; understanding its caching and error handling is critical for replacing mock JSONonevcat/Kingfisher— Image caching library TSWeChat depends on; study for understanding how chat image cells achieve performant displaySwiftyJSON/SwiftyJSON— Alternative to ObjectMapper for JSON parsing in Swift that's still actively maintained and could reduce dependency bloat
🪄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.
Modernize Podfile and update deprecated dependencies
The project uses older CocoaPods dependencies (Alamofire, ObjectMapper, Kingfisher) that have been significantly updated or replaced by modern Swift alternatives. The Podfile and dependency versions are not specified in the visible configuration. Updating to Swift Package Manager or modern dependency versions would improve maintainability and security.
- [ ] Audit Podfile for outdated dependency versions (Alamofire 4.x → 5.x+, ObjectMapper → Codable)
- [ ] Create a migration guide from Pods to SPM or update Podfile with pinned modern versions
- [ ] Update Podfile.lock and Pods/Manifest.lock to reflect changes
- [ ] Test build compatibility with iOS 12.0+ (Podfile currently shows iOS 8.0+ which is outdated)
Add GitHub Actions CI/CD workflow for Swift builds
The repo shows a Travis CI badge but no visible GitHub Actions workflow file. Modern Swift projects should have automated testing on every PR to catch regressions early, especially for a messaging app that handles networking, location, and keychain operations.
- [ ] Create .github/workflows/swift-build.yml with Swift build matrix (Xcode 12+, 13, 14+)
- [ ] Add SwiftLint static analysis to the workflow
- [ ] Configure workflow to test on multiple iOS versions
- [ ] Run CocoaPods installation and verify Podfile.lock consistency in CI
Add unit tests for networking layer (Alamofire integration)
The project depends heavily on Alamofire for HTTP requests but there are no visible test files. A messaging app's networking reliability is critical. Adding mock tests for request/response serialization and error handling would catch bugs before production.
- [ ] Create Tests/ directory with NetworkingTests.swift targeting Pods/Alamofire/Source/Request.swift and Response.swift
- [ ] Add mock tests for ResponseSerialization using ObjectMapper transforms
- [ ] Test error cases from AFError.swift with realistic WeChat API failures
- [ ] Add tests for SessionManager configuration and retry logic
🌿Good first issues
- Add unit tests for ObjectMapper Models in Classes/CoreModule/Models/—currently zero test coverage for data serialization logic that could fail silently with malformed JSON
- Extract reusable voice file conversion logic (WAV→AMR) from Message classes into a standalone AudioConverter utility in Helpers/—currently appears duplicated
- Document the custom input keyboard architecture in Classes/Message/Controller/ with a code walkthrough—no README explains how TSChatViewController manages input accessories and gesture recognizers
⭐Top contributors
Click to expand
Top contributors
- @Hilen — 24 commits
- @hilen — 19 commits
- @jkaunert — 3 commits
- @emerson233 — 3 commits
- @cdoky — 2 commits
📝Recent commits
Click to expand
Recent commits
a1d371a— Update readme (Hilen)287e882— Swift 5 compatibility. Including the libs (Hilen)27a9970— Modify readme (Hilen)92280d3— Merge branch 'kyknow-master' (Hilen)4b0e0db— Merge kyknow-master master (Hilen)e61aee1— Merge branch 'jkaunert-master' into develop (Hilen)4419a2c— Update README.md (jkaunert)f737048— (nit) Pods updated, /Pods removed from .gitignore (jkaunert)88ba741— (refactor) Updated to Swift 5.0 and iOS 10.0 (jkaunert)fac9d9e— - fixed:list无法滚动到最底部的问题 (cdoky)
🔒Security observations
- High · Outdated Dependencies with Known Vulnerabilities —
Podfile, Podfile.lock, Pods/. The project uses CocoaPods dependencies that appear to be outdated based on the file structure. Alamofire, Kingfisher, ObjectMapper, and other dependencies may contain known security vulnerabilities. The Podfile.lock indicates pinned versions, but without seeing the actual versions, older releases likely have unpatched CVEs. Fix: 1. Run 'pod outdated' to identify outdated pods. 2. Update all dependencies to their latest stable versions. 3. Review release notes and changelogs for security fixes. 4. Implement dependency scanning in CI/CD pipeline using tools like Dependabot or Snyk. - Medium · Use of ObjcExceptionBridging for Exception Handling —
Pods/ObjcExceptionBridging/. The project includes ObjcExceptionBridging dependency, which bridges Objective-C exceptions to Swift. Improper exception handling can mask critical errors and security issues. If not used carefully, it can lead to uncaught exceptions in production. Fix: 1. Review all usage of ObjcExceptionBridging in the codebase. 2. Ensure proper exception handling with try-catch blocks. 3. Log exceptions appropriately without exposing sensitive information. 4. Consider replacing with native Swift error handling where possible. - Medium · Keychain Access Implementation Risk —
Pods/KeychainAccess/. The project uses KeychainAccess library for credential storage. If not implemented correctly, sensitive data like authentication tokens, passwords, or encryption keys could be improperly stored or retrieved. Fix: 1. Audit all Keychain usage in the application code. 2. Ensure sensitive data is stored with appropriate access controls (kSecAttrAccessible). 3. Never store plaintext credentials. 4. Implement proper error handling for Keychain operations. 5. Use kSecAttrAccessibleWhenUnlockedThisDeviceOnly for most sensitive data. - Medium · Location Services Permission Risk —
Pods/INTULocationManager/. The project includes INTULocationManager for location tracking. Without proper permission handling and user consent, this poses privacy and security risks. Users may not understand why location is being requested. Fix: 1. Ensure Info.plist contains NSLocationWhenInUseUsageDescription or NSLocationAlwaysAndWhenInUseUsageDescription. 2. Implement permission checks before accessing location. 3. Only request location when necessary and document the use case. 4. Provide granular privacy controls to users. 5. Follow GDPR/CCPA compliance requirements for location data. - Low · Missing Security Headers Documentation —
Root configuration files. No visible security configuration files (Info.plist security settings, App Transport Security configuration) in the provided file structure. Missing HTTPS enforcement and certificate pinning documentation. Fix: 1. Verify Info.plist contains NSAppTransportSecurity with NSAllowsArbitraryLoads set to false. 2. Implement certificate pinning for API communications using Alamofire or similar. 3. Enforce HTTPS-only connections. 4. Document security configuration in a security.md file. - Low · No Visible Input Validation Framework —
Pods/ObjectMapper/. The file structure does not show obvious input validation or sanitization libraries. The use of ObjectMapper for JSON parsing without visible validation could lead to injection attacks if user input is not properly validated. Fix: 1. Implement input validation for all user-supplied data. 2. Use whitelisting for allowed characters/formats. 3. Sanitize data before processing. 4. Validate API responses using schemas. 5. Consider using libraries like SwiftValidators for comprehensive validation. - Low · Missing Code Obfuscation and Debug Symbol Stripping —
Build configuration. No evidence of code obfuscation or build-time security measures in the visible configuration. Debug symbols could expose sensitive information if not properly stripped in release builds. Fix: 1. Ensure Debug Symbols (dSYM) are stripped from release builds. 2. Enable bitcode for App Store builds. 3. Consider implementing code obfuscation for sensitive logic. 4. Configure Xcode to use Strip Debug Symbols in release schemes. 5. Manage d
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.