|
| 1 | +# GitHub Copilot Instructions |
| 2 | + |
| 3 | +This file provides guidance to GitHub Copilot when working with code in this repository. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +V2er is a V2EX forum client for iOS built with SwiftUI. The app follows a Redux-like unidirectional data flow architecture for state management. |
| 8 | + |
| 9 | +**Key Technologies:** |
| 10 | +- SwiftUI for UI |
| 11 | +- Redux-like state management pattern |
| 12 | +- Swift Package Manager for dependencies |
| 13 | +- Xcode project structure |
| 14 | + |
| 15 | +## Code Style and Conventions |
| 16 | + |
| 17 | +### Swift Style |
| 18 | +- Follow Swift API Design Guidelines |
| 19 | +- Use descriptive variable and function names |
| 20 | +- Prefer `let` over `var` when possible |
| 21 | +- Use type inference where it improves readability |
| 22 | +- Keep files focused on single responsibility |
| 23 | + |
| 24 | +### SwiftUI Patterns |
| 25 | +- Use `@EnvironmentObject` for accessing the Store |
| 26 | +- Separate view logic from business logic |
| 27 | +- Keep views small and composable |
| 28 | +- Use custom view modifiers for reusable styling |
| 29 | + |
| 30 | +### State Management |
| 31 | +The app uses a centralized Redux-like pattern: |
| 32 | + |
| 33 | +1. **Store** (`V2er/State/DataFlow/Store.swift`): Single source of truth |
| 34 | +2. **Actions** (`V2er/State/DataFlow/Actions/`): Define state mutations |
| 35 | +3. **Reducers** (`V2er/State/DataFlow/Reducers/`): Handle state updates |
| 36 | +4. **States** (`V2er/State/`): Individual feature state containers |
| 37 | + |
| 38 | +When implementing new features: |
| 39 | +1. Define actions in appropriate `*Actions.swift` file |
| 40 | +2. Create/update state in `*State.swift` |
| 41 | +3. Implement reducer logic in `*Reducer.swift` |
| 42 | +4. Connect to views using `@EnvironmentObject` Store |
| 43 | + |
| 44 | +## Project Structure |
| 45 | + |
| 46 | +``` |
| 47 | +V2er/ |
| 48 | +├── State/ # State management |
| 49 | +│ ├── DataFlow/ # Redux-like architecture |
| 50 | +│ └── Networking/ # API services |
| 51 | +├── View/ # SwiftUI views by feature |
| 52 | +│ ├── Feed/ # Main topic feed |
| 53 | +│ ├── FeedDetail/ # Topic details and replies |
| 54 | +│ ├── Login/ # Authentication flow |
| 55 | +│ ├── Me/ # User profile |
| 56 | +│ ├── Message/ # Notifications |
| 57 | +│ ├── Explore/ # Discovery |
| 58 | +│ ├── Settings/ # App preferences |
| 59 | +│ └── Widget/ # Reusable UI components |
| 60 | +├── Config/ # Configuration files |
| 61 | +└── www/ # Web content assets |
| 62 | +``` |
| 63 | + |
| 64 | +## Architecture Components |
| 65 | + |
| 66 | +### API Integration |
| 67 | +- **APIService** (`V2er/State/Networking/APIService.swift`): Central API handling |
| 68 | +- **Endpoints** defined in `Endpoint.swift` |
| 69 | +- HTML responses parsed using SwiftSoup into Swift models |
| 70 | +- Network errors handled via `NetworkException.swift` |
| 71 | + |
| 72 | +### Authentication |
| 73 | +- Supports V2EX standard login and two-step verification |
| 74 | +- Login state in `LoginState.swift` and `LoginReducer.swift` |
| 75 | +- Credentials persisted via `Persist.swift` |
| 76 | + |
| 77 | +### Content Parsing |
| 78 | +- V2EX HTML content parsed with SwiftSoup |
| 79 | +- Rich text rendering: `RichText.swift` and `HtmlView.swift` |
| 80 | +- Special handling for V2EX-specific formats |
| 81 | + |
| 82 | +## Dependencies |
| 83 | + |
| 84 | +Managed via Swift Package Manager: |
| 85 | +- **Kingfisher**: Image loading and caching |
| 86 | +- **SwiftSoup**: HTML parsing |
| 87 | +- **SwiftUI-WebView**: Web content display |
| 88 | +- **Atributika**: Rich text attributes |
| 89 | + |
| 90 | +## Development Commands |
| 91 | + |
| 92 | +### Building |
| 93 | +```bash |
| 94 | +# Build the project |
| 95 | +xcodebuild -project V2er.xcodeproj -scheme V2er -configuration Debug build |
| 96 | + |
| 97 | +# Build for simulator |
| 98 | +xcodebuild -project V2er.xcodeproj -scheme V2er -sdk iphonesimulator -configuration Debug |
| 99 | + |
| 100 | +# Clean build |
| 101 | +xcodebuild clean -project V2er.xcodeproj -scheme V2er |
| 102 | +``` |
| 103 | + |
| 104 | +### Testing |
| 105 | +```bash |
| 106 | +# Run tests |
| 107 | +xcodebuild test -project V2er.xcodeproj -scheme V2er -destination 'platform=iOS Simulator,name=iPhone 14' |
| 108 | +``` |
| 109 | + |
| 110 | +Test locations: |
| 111 | +- `V2erTests/`: Unit tests |
| 112 | +- `V2erUITests/`: UI tests |
| 113 | + |
| 114 | +### Archiving |
| 115 | +```bash |
| 116 | +# Archive for App Store |
| 117 | +xcodebuild archive -project V2er.xcodeproj -scheme V2er -archivePath V2er.xcarchive |
| 118 | +``` |
| 119 | + |
| 120 | +## Release Management |
| 121 | + |
| 122 | +### Version Management |
| 123 | +Version info is centralized in `V2er/Config/Version.xcconfig`: |
| 124 | +- `MARKETING_VERSION`: User-facing version (e.g., 1.1.1) |
| 125 | +- `CURRENT_PROJECT_VERSION`: Build number (auto-incremented by CI) |
| 126 | + |
| 127 | +### Release Process |
| 128 | +1. **Update Version.xcconfig** |
| 129 | + ```bash |
| 130 | + # Edit V2er/Config/Version.xcconfig |
| 131 | + MARKETING_VERSION = 1.2.0 |
| 132 | + ``` |
| 133 | + |
| 134 | +2. **Update CHANGELOG.md** |
| 135 | + Add a new section at the top: |
| 136 | + ```markdown |
| 137 | + ## v1.2.0 (Build XX) |
| 138 | + 1. Feature: Description of new feature |
| 139 | + 2. Fix: Description of bug fix |
| 140 | + 3. Improvement: Description of enhancement |
| 141 | + ``` |
| 142 | + |
| 143 | +3. **Commit and push** |
| 144 | + ```bash |
| 145 | + git add V2er/Config/Version.xcconfig CHANGELOG.md |
| 146 | + git commit -m "chore: bump version to 1.2.0" |
| 147 | + git push origin main |
| 148 | + ``` |
| 149 | + |
| 150 | +**Important:** CHANGELOG.md is required for all releases. The build will fail if the current version is missing from the changelog. |
| 151 | + |
| 152 | +### Fastlane Commands |
| 153 | +```bash |
| 154 | +# Build and upload to TestFlight (requires changelog) |
| 155 | +fastlane beta |
| 156 | + |
| 157 | +# Distribute existing build to beta testers |
| 158 | +fastlane distribute_beta |
| 159 | + |
| 160 | +# Sync certificates and provisioning profiles |
| 161 | +fastlane sync_certificates |
| 162 | +``` |
| 163 | + |
| 164 | +## Common Patterns |
| 165 | + |
| 166 | +### Making API Calls |
| 167 | +```swift |
| 168 | +// 1. Define endpoint in Endpoint.swift |
| 169 | +// 2. Call via APIService |
| 170 | +// 3. Parse HTML response with SwiftSoup |
| 171 | +// 4. Update state via action/reducer |
| 172 | +``` |
| 173 | + |
| 174 | +### Adding a New Feature |
| 175 | +```swift |
| 176 | +// 1. Create *Actions.swift with action types |
| 177 | +// 2. Create *State.swift with state model |
| 178 | +// 3. Create *Reducer.swift with state logic |
| 179 | +// 4. Create SwiftUI view |
| 180 | +// 5. Connect view to Store with @EnvironmentObject |
| 181 | +``` |
| 182 | + |
| 183 | +### State Updates |
| 184 | +```swift |
| 185 | +// Always dispatch actions to update state |
| 186 | +dispatch(SomeActions.UpdateState(newValue)) |
| 187 | + |
| 188 | +// Never mutate state directly |
| 189 | +// state.value = newValue // ❌ Don't do this |
| 190 | +``` |
| 191 | + |
| 192 | +## Important Constraints |
| 193 | + |
| 194 | +- **Minimum iOS version**: iOS 15.0 |
| 195 | +- **Architectures**: armv7, arm64 |
| 196 | +- **Orientation**: Portrait only on iPhone, all on iPad |
| 197 | +- **UI Style**: Light mode enforced |
| 198 | +- **Submodules**: `website/` directory is a separate repository |
| 199 | + |
| 200 | +## Pull Request Guidelines |
| 201 | + |
| 202 | +- Always use English for PR titles and descriptions |
| 203 | +- Follow conventional commit format |
| 204 | +- Include changelog entry for version changes |
| 205 | +- Ensure tests pass before submitting |
| 206 | +- Keep changes focused and atomic |
| 207 | + |
| 208 | +## Workflows |
| 209 | + |
| 210 | +The repository includes several GitHub Actions workflows: |
| 211 | + |
| 212 | +- **iOS Build & Test**: Runs on push/PR to main |
| 213 | +- **PR Validation**: SwiftLint, conventional commits, PR sizing |
| 214 | +- **Release**: Manual trigger for TestFlight/App Store |
| 215 | +- **Dependency Updates**: Weekly automated updates |
| 216 | +- **Code Quality**: SwiftFormat and coverage reporting |
| 217 | + |
| 218 | +See `.github/workflows/README.md` for details. |
| 219 | + |
| 220 | +## Getting Help |
| 221 | + |
| 222 | +- Check existing documentation in CLAUDE.md, VERSIONING.md |
| 223 | +- Review similar patterns in the codebase |
| 224 | +- Refer to V2EX API documentation for endpoint details |
| 225 | +- Check workflows README for CI/CD questions |
0 commit comments