RepoPilotOpen in app →

allenwong/30DaysofSwift

A self-taught project to learn Swift.

Concerns

Stale and unlicensed — last commit 4y ago

worst of 4 axes
Use as dependencyConcerns

no license — legally unclear; last commit was 4y ago…

Fork & modifyConcerns

no license — can't legally use code; no tests detected…

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isConcerns

no license — can't legally use code; last commit was 4y ago…

  • 17 active contributors
  • Distributed ownership (top contributor 31% of recent commits)
  • Stale — last commit 4y ago
Show 3 more →
  • No license — legally unclear to depend on
  • No CI workflows detected
  • No test directory detected
What would change the summary?
  • Use as dependency ConcernsMixed if: publish a permissive license (MIT, Apache-2.0, etc.)
  • Fork & modify ConcernsMixed if: add a LICENSE file
  • Deploy as-is ConcernsMixed if: add a LICENSE file

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.

RepoPilot: Great to learn from
[![RepoPilot: Great to learn from](https://repopilot.app/api/badge/allenwong/30daysofswift?axis=learn)](https://repopilot.app/r/allenwong/30daysofswift)

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/allenwong/30daysofswift on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: allenwong/30DaysofSwift

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/allenwong/30DaysofSwift 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

AVOID — Stale and unlicensed — last commit 4y ago

  • 17 active contributors
  • Distributed ownership (top contributor 31% of recent commits)
  • ⚠ Stale — last commit 4y ago
  • ⚠ No license — legally unclear to depend on
  • ⚠ 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 allenwong/30DaysofSwift repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/allenwong/30DaysofSwift.

What it runs against: a local clone of allenwong/30DaysofSwift — 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 allenwong/30DaysofSwift | Confirms the artifact applies here, not a fork | | 2 | Default branch master exists | Catches branch renames | | 3 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 4 | Last commit ≤ 1479 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>allenwong/30DaysofSwift</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of allenwong/30DaysofSwift. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/allenwong/30DaysofSwift.git
#   cd 30DaysofSwift
#
# 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 allenwong/30DaysofSwift and re-run."
  exit 2
fi

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

# 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 "Project 01 - SimpleStopWatch/StopWatch/ViewController.swift" \\
  && ok "Project 01 - SimpleStopWatch/StopWatch/ViewController.swift" \\
  || miss "missing critical file: Project 01 - SimpleStopWatch/StopWatch/ViewController.swift"
test -f "Project 01 - SimpleStopWatch/StopWatch/AppDelegate.swift" \\
  && ok "Project 01 - SimpleStopWatch/StopWatch/AppDelegate.swift" \\
  || miss "missing critical file: Project 01 - SimpleStopWatch/StopWatch/AppDelegate.swift"
test -f "Project 02 - CustomFont/CustomFont/ViewController.swift" \\
  && ok "Project 02 - CustomFont/CustomFont/ViewController.swift" \\
  || miss "missing critical file: Project 02 - CustomFont/CustomFont/ViewController.swift"
test -f "Project 03 - PlayLocalVideo/PlayLocalVideo/ViewController.swift" \\
  && ok "Project 03 - PlayLocalVideo/PlayLocalVideo/ViewController.swift" \\
  || miss "missing critical file: Project 03 - PlayLocalVideo/PlayLocalVideo/ViewController.swift"
test -f "Project 01 - SimpleStopWatch/StopWatch/Base.lproj/Main.storyboard" \\
  && ok "Project 01 - SimpleStopWatch/StopWatch/Base.lproj/Main.storyboard" \\
  || miss "missing critical file: Project 01 - SimpleStopWatch/StopWatch/Base.lproj/Main.storyboard"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 1479 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~1449d)"
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/allenwong/30DaysofSwift"
  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

30DaysofSwift is a self-taught Swift learning project containing 30+ progressive iOS app implementations demonstrating UIKit-based features: stopwatch timers, custom fonts, video playback, gesture animations, carousel effects, CoreLocation integration, pull-to-refresh, and gradient animations. It's a hands-on learning journey translating design thinking into working Swift applications. Monorepo structure with 30+ independent Xcode projects, each in a folder like Project NN - FeatureName/ (e.g., Project 01 - SimpleStopWatch, Project 02 - CustomFont). Each project is a complete .xcodeproj bundle with its own AppDelegate.swift, Main.storyboard, and Assets.xcassets. No shared code library; each day's project is isolated.

👥Who it's for

Junior iOS developers and designers learning Swift fundamentals through concrete, runnable examples. Product designers transitioning into iOS development (the creator is a product designer) who want pattern-based learning rather than theoretical tutorials.

🌱Maturity & risk

This is a completed learning archive, not an active project—it's a historical record of one developer's 30-day Swift learning sprint. No active maintenance, commits, or issue tracking visible; the projects use UIKit and storyboards (older iOS patterns) rather than SwiftUI. Suitable as a reference/inspiration archive, not as a production dependency or template.

High risk for production use: single-author hobby project with no test suite, CI/CD, or versioning strategy. Projects use deprecated UIKit storyboard patterns and likely target older iOS versions (based on project structure). No dependency management visible (no Podfile, Package.swift); all projects appear self-contained. Not maintained—treat as educational snapshots, not reusable components.

Active areas of work

This project is not actively developed—it's a completed 30-day learning sprint archived on GitHub. The README shows it was inspired by Sam Lu's 100 Days of Swift initiative. No recent commits, pull requests, or issues are visible in the provided metadata.

🚀Get running

Clone the repo and open any single project in Xcode: git clone https://github.com/allenwong/30DaysofSwift.git && cd '30DaysofSwift/Project 01 - SimpleStopWatch' && open StopWatch.xcodeproj. Then build and run on an iOS simulator (Xcode 11+, Swift 4.2+).

Daily commands: Open any .xcodeproj in Xcode (e.g., Project 01 - SimpleStopWatch/StopWatch.xcodeproj). Press Cmd+R to build and run on the selected simulator. Projects have no external build step—all are Xcode-native.

🗺️Map of the codebase

  • Project 01 - SimpleStopWatch/StopWatch/ViewController.swift — Primary entry point for the first project demonstrating Swift fundamentals with a stopwatch timer implementation and UI state management.
  • Project 01 - SimpleStopWatch/StopWatch/AppDelegate.swift — Application lifecycle handler that initializes the app and sets up the initial view controller for the stopwatch project.
  • Project 02 - CustomFont/CustomFont/ViewController.swift — Core implementation showing how to load and apply custom fonts (OTF/TTF) in Swift, a key learning pattern for the second project.
  • Project 03 - PlayLocalVideo/PlayLocalVideo/ViewController.swift — Demonstrates video playback using AVFoundation framework, representing progression to multimedia handling in Swift.
  • Project 01 - SimpleStopWatch/StopWatch/Base.lproj/Main.storyboard — UI layout definition for the stopwatch app containing button and label constraints essential for understanding the visual structure.
  • Project 02 - CustomFont/CustomFont/Info.plist — Configuration file declaring custom font files to iOS system, critical for font registration pattern used across projects.

🛠️How to make changes

Add a New Swift Project (New Day)

  1. Create a new Xcode project directory following naming convention 'Project XX - ProjectName' (Project 01 - SimpleStopWatch/StopWatch.xcodeproj)
  2. Generate AppDelegate.swift following the template from existing projects to set up app lifecycle (Project 01 - SimpleStopWatch/StopWatch/AppDelegate.swift)
  3. Create ViewController.swift with your Swift logic implementation (Project 01 - SimpleStopWatch/StopWatch/ViewController.swift)
  4. Design UI layout in Main.storyboard using Interface Builder (Project 01 - SimpleStopWatch/StopWatch/Base.lproj/Main.storyboard)
  5. Add required assets (images, fonts, videos) to Assets.xcassets (Project 01 - SimpleStopWatch/StopWatch/Assets.xcassets/Contents.json)
  6. Configure app metadata and resource declarations in Info.plist (Project 01 - SimpleStopWatch/StopWatch/Info.plist)

Integrate Custom Fonts into a Project

  1. Add font files (TTF/OTF) directly to the project bundle (Project 02 - CustomFont/CustomFont/Gaspar Regular.otf)
  2. Declare fonts in Info.plist under 'Fonts provided by application' array (Project 02 - CustomFont/CustomFont/Info.plist)
  3. Load font in ViewController using UIFont(name:size:) with the exact font filename (Project 02 - CustomFont/CustomFont/ViewController.swift)
  4. Apply loaded font to UILabel or UITextView using the .font property (Project 02 - CustomFont/CustomFont/Base.lproj/Main.storyboard)

Implement Media Playback (Video/Audio)

  1. Import AVFoundation framework in your ViewController (Project 03 - PlayLocalVideo/PlayLocalVideo/ViewController.swift)
  2. Create AVPlayer instance and configure it with local media URL from app bundle (Project 03 - PlayLocalVideo/PlayLocalVideo/ViewController.swift)
  3. Add AVPlayerViewController or custom player controls to UI via storyboard (Project 03 - PlayLocalVideo/PlayLocalVideo/Base.lproj/Main.storyboard)
  4. Add thumbnail previews to Assets.xcassets for video selection UI (Project 03 - PlayLocalVideo/PlayLocalVideo/Assets.xcassets/videoScreenshot01.imageset/Contents.json)

Create a Timer-Based Application

  1. Use Foundation's Timer class to schedule periodic callbacks in ViewController (Project 01 - SimpleStopWatch/StopWatch/ViewController.swift)
  2. Implement start, pause, and reset methods with Timer.invalidate() for cleanup (Project 01 - SimpleStopWatch/StopWatch/ViewController.swift)
  3. Design UI with UILabel for timer display and buttons for controls in storyboard (Project 01 - SimpleStopWatch/StopWatch/Base.lproj/Main.storyboard)
  4. Add button images (play/pause icons) to Assets.xcassets (Project 01 - SimpleStopWatch/StopWatch/Assets.xcassets/play.imageset/play.pdf)

🔧Why these technologies

  • Swift — Primary language for iOS app development; enables type-safe, modern syntax for learning fundamental concepts.
  • UIKit (Storyboard + ViewController) — Traditional iOS UI framework used across all projects; demonstrates interface design, view lifecycle, and event handling.
  • Foundation Framework (Timer) — Provides Timer class essential for Project 01 stopwatch implementation; teaches scheduling and time management.
  • AVFoundation (AVPlayer) — Media playback framework for Project 03; introduces multimedia handling and state management in iOS.
  • Xcode & Interface Builder — Official iOS development environment; enables visual UI design and project management.

⚖️Trade-offs already made

  • Use Storyboard instead of Programmatic Layout

    • Why: Simplifies learning curve for beginners; visual design aids understanding of constraints and view hierarchy.
    • Consequence: Less flexible for complex dynamic layouts; slower for large teams but ideal for learning single-developer projects.
  • No external dependencies or CocoaPods

    • Why: Reduces complexity and focuses on native Swift/iOS frameworks; demonstrates pure framework capabilities.
    • Consequence: No advanced third-party libraries; requires manual implementation of common patterns but reinforces foundational knowledge.
  • Separate projects per concept rather than single monolithic app

    • Why: Allows focused learning on one feature per 'day'; easier to review and understand isolated concepts.
    • Consequence: Code duplication across AppDelegate/ViewController templates; harder to refactor and reuse components across projects.
  • Include font files in bundle vs. download at runtime

    • Why: Ensures offline availability and simplifies font management for learning purposes.
    • Consequence: Increases app bundle size; not scalable for apps with many fonts but appropriate for educational projects.

🚫Non-goals (don't propose these)

  • Production-grade error handling or crash recovery
  • Network-based data fetching or remote API integration
  • Persistent data storage with Core Data or databases
  • Real-time synchronization across devices
  • Accessibility features (VoiceOver, dynamic type)
  • Localization or multi-language support
  • Advanced testing frameworks or CI/CD pipelines
  • SwiftUI or modern declarative UI (UIKit only)

🪤Traps & gotchas

No external dependency management: Projects use only Apple frameworks (UIKit, Core Location, AVKit); no CocoaPods or SPM. Storyboard-only UI: All projects use .storyboard XIB files; no programmatic constraints or SwiftUI. Deployment target unclear: Info.plist values not exposed; likely iOS 10–11 era based on API usage. No tests: Zero test bundles (*.xctest) in visible structure. Xcode version drift: Projects may not open in latest Xcode without SDK retargeting.

🏗️Architecture

💡Concepts to learn

  • UIKit Storyboard MVC — All 30 projects use storyboards and view controllers; understanding outlet/action connections and lifecycle methods is foundational before learning SwiftUI
  • DispatchSourceTimer — Project 01 uses this for the stopwatch tick loop; essential for precise timing in Swift without external libraries
  • Core Location (CLLocationManager) — Project 06 demonstrates GPS authorization, location updates, and map integration—critical for location-aware apps
  • UIGestureRecognizer — Projects 04–05 use pan/swipe recognizers for menu animations and carousel interactions; fundamental touch handling pattern
  • AVPlayer / AVPlayerViewController — Project 03 uses these for local video playback; shows how to integrate media frameworks without building custom players
  • UIScrollView Paging — Project 05 carousel relies on pagingEnabled and transform for smooth scrolling effects; key for content-heavy UIs
  • Custom UIView Subclasses — Project 02 (custom fonts) and others extend UIView/UILabel for reusable components; essential pattern for design system implementation
  • samvlu/100-days-of-swift — Direct inspiration: the 100-day Swift learning challenge that motivated this 30-day fork; likely contains similar app patterns but with more projects
  • raywenderlich/swift-algorithm-club — Complementary learning resource covering algorithms and data structures in Swift, useful for advancing beyond UI-focused projects
  • vapor/vapor — Swift backend framework; for learners ready to move beyond iOS UI into server-side Swift development
  • pointfreeco/swift-composable-architecture — Modern Swift architecture (TCA/MVVM+Redux); shows how to structure state and side effects—a natural progression from these basic UIKit apps
  • apple/swift-book — Official Swift language reference; essential for deepening language fundamentals beyond these app-focused 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.

Create a comprehensive .gitignore for Xcode projects

The repo currently tracks Xcode user data files (xcuserdata, .xcworkspace/xcuserdata, Breakpoints_v2.xcbkptlist, UserInterfaceState.xcuserstate) that should never be committed. This causes merge conflicts and clutters the repo. A proper .gitignore will reduce noise and follow Swift/iOS best practices.

  • [ ] Update .gitignore to exclude *.xcuserdata, *.xcworkspace/xcuserdata, Breakpoints_v2.xcbkptlist, and UserInterfaceState.xcuserstate patterns
  • [ ] Remove committed xcuserdata directories from Project 01-03 and any other projects using git rm --cached
  • [ ] Add standard Xcode exclusions: *.swiftpm, .DS_Store, build/, DerivedData/, and *.playground

Add README documentation for each project directory

While the main README exists, individual projects (Project 01 - SimpleStopWatch, Project 02 - CustomFont, Project 03 - PlayLocalVideo, etc.) lack their own README files explaining objectives, key concepts learned, and how to run them. This helps new learners understand the progression and purpose of each 30-day challenge.

  • [ ] Create README.md in Project 01 - SimpleStopWatch/ explaining Timer implementation, UIKit patterns used, and screenshots
  • [ ] Create README.md in Project 02 - CustomFont/ documenting custom font loading in Info.plist and the included font files (Gaspar, MFJinHei, MFTongXin, MFZhiHei)
  • [ ] Create README.md in Project 03 - PlayLocalVideo/ (and subsequent projects) with learning objectives and setup instructions

Consolidate duplicate font files from Project 02

Project 02 - CustomFont has font files duplicated at two levels: both in the project directory and in the Xcode bundle (Project 02 - CustomFont/CustomFont/). This creates maintenance overhead and confusion. Consolidating them will clean up the repo structure.

  • [ ] Verify that all font files in Project 02 - CustomFont/ directory are also present in Project 02 - CustomFont/CustomFont/
  • [ ] Remove the duplicate font files from the outer Project 02 - CustomFont/ directory (Gaspar Regular.otf, MFJinHei*.ttf, MFTongXin*.ttf, MFZhiHei*.ttf)
  • [ ] Update the project README to document the correct font file locations and ensure ViewController.swift references the correct bundle paths

🌿Good first issues

  • Modernize Project 01 to SwiftUI: Rewrite Project 01 - SimpleStopWatch/StopWatch/ViewController.swift and Main.storyboard as a SwiftUI @State-based timer to learn the paradigm shift from UIKit to declarative UI.
  • Add unit tests for timer logic: Create StopWatchTests.xctest bundle testing elapsed time calculation, pause/resume transitions, and reset behavior—currently zero test coverage.
  • Document each project's learning goal: Add README.md to each Project NN - FeatureName/ folder explaining what iOS capability it teaches (Core Location, gestures, etc.) and which official Apple docs to reference.

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 8f5b1d7 — Update README.md (allenwong)
  • dc33410 — Update README.md (allenwong)
  • 515141a — Update README.md (allenwong)
  • c7d6259 — Update README.md (allenwong)
  • 7b1a36e — Merge pull request #72 from woshiqyb/master (allenwong)
  • 31438d4 — 大结局 (qianyb)
  • 021f7e9 — 修复问题,可以正常使用了 (qianyb)
  • 83e9203 — 第29天 —- 改到吐血,终于可以编译通过,但是点击头像会crash (qianyb)
  • 8823930 — 第28天———spotlight (qianyb)
  • 0bc7583 — 第27天— TabBar app (qianyb)

🔒Security observations

The 30 Days of Swift learning project demonstrates a reasonable security posture overall. No critical or high-severity vulnerabilities were identified in the accessible file structure. The main concerns are minor: (1) developer-specific Xcode user data and debugging configurations are tracked in version control when they should be ignored, and (2) some organizational redundancy in asset files. The project lacks external dependencies and package managers (no Podfile, Cartfile, or Package.swift detected), which reduces supply chain risk. However, a comprehensive security assessment would require review of actual source code implementation to identify potential injection risks, insecure data handling, or improper use of native APIs. As a self-taught learning project, the codebase should be regularly updated with current Swift best practices and security patterns.

  • Low · User Data and Project Files in Version Control — Project */*/xcuserdata/ directories, Project */**/UserInterfaceState.xcuserstate, Breakpoints_v2.xcbkptlist. The repository contains user-specific Xcode files including .xcuserdata directories with UserInterfaceState, breakpoints, and debugging information. These files should typically be excluded via .gitignore to prevent exposure of development environment details and potential sensitive debugging configurations. Fix: Add *.xcuserdata, *.xcworkspace/xcuserdata/, and other user-specific Xcode files to .gitignore. Use a standard Xcode.gitignore template.
  • Low · Duplicate Font Files in Repository — Project 02 - CustomFont/ and root directory duplicate font files. Custom font files (.otf, .ttf) are present in both the project directory and at the root level (Project 02 - CustomFont/). This creates redundancy and increases repository size. While not a direct security issue, it indicates poor repository organization that could lead to maintenance issues. Fix: Remove duplicate font files. Keep fonts in the project directory only and ensure they are properly referenced in the Xcode project configuration.
  • Low · Incomplete Security Analysis - Limited Source Code Access — AppDelegate.swift, ViewController.swift, and other Swift source files. Only the file structure is visible without access to actual Swift source code (.swift files) or detailed configuration. While the basic structure appears sound, a comprehensive security assessment requires reviewing actual implementation code for potential injection vulnerabilities, insecure data handling, or API misconfigurations. Fix: Conduct a detailed code review of all Swift implementation files, particularly focusing on: data persistence (CoreData usage), network requests (URLSession), user input handling, and any third-party framework integrations.

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.

Concerning signals · allenwong/30DaysofSwift — RepoPilot