| 
 | 1 | +# Mac Image Manager - Development Guidelines  | 
 | 2 | + | 
 | 3 | +> Last updated: October 2025  | 
 | 4 | +
  | 
 | 5 | +## 📋 Overview  | 
 | 6 | + | 
 | 7 | +This document provides comprehensive development guidelines for Mac Image Manager, a native macOS application built with SwiftUI. These guidelines ensure code consistency, maintainability, and adherence to Apple's Human Interface Guidelines.  | 
 | 8 | + | 
 | 9 | +## 🎯 Core Principles  | 
 | 10 | + | 
 | 11 | +### 1. Always Follow Apple Human Interface Guidelines (HIG)  | 
 | 12 | + | 
 | 13 | +- Prioritize native macOS UI patterns and behaviors  | 
 | 14 | +- Use system-provided controls and layouts whenever possible  | 
 | 15 | +- Ensure accessibility compliance with VoiceOver and other assistive technologies  | 
 | 16 | +- Follow Apple's visual design principles for spacing, typography, and color  | 
 | 17 | + | 
 | 18 | +### 2. Modern Swift & SwiftUI (2025 Standards)  | 
 | 19 | + | 
 | 20 | +- Use Swift 6.0+ language features and concurrency model  | 
 | 21 | +- Leverage SwiftUI 6.0+ framework capabilities  | 
 | 22 | +- Implement `@MainActor` isolation for UI-related code  | 
 | 23 | +- Use structured concurrency (`async/await`, `Task`) over legacy completion handlers  | 
 | 24 | +- Prefer value types (structs) over reference types (classes) when appropriate  | 
 | 25 | + | 
 | 26 | +### 3. Code Organization & Architecture  | 
 | 27 | + | 
 | 28 | +- Follow MVVM (Model-View-ViewModel) architecture pattern  | 
 | 29 | +- Use `@ObservableObject` and `@Published` for state management  | 
 | 30 | +- Organize code into logical directories: `Models/`, `Views/`, `ViewModels/` (if needed)  | 
 | 31 | +- Separate concerns: UI logic in Views, business logic in Models  | 
 | 32 | +- Use extensions to organize code by functionality  | 
 | 33 | + | 
 | 34 | +## 🏗️ Project Structure  | 
 | 35 | + | 
 | 36 | +### File Organization  | 
 | 37 | + | 
 | 38 | +```text  | 
 | 39 | +MacImageManager/  | 
 | 40 | +├── Models/           # Data models and business logic  | 
 | 41 | +├── Views/            # SwiftUI views and UI components  | 
 | 42 | +├── ViewModels/       # View models (if MVVM pattern requires)  | 
 | 43 | +├── Utilities/        # Helper functions and extensions  | 
 | 44 | +├── Resources/        # Assets, strings, configuration files  | 
 | 45 | +└── Tests/            # Unit and UI tests  | 
 | 46 | +```  | 
 | 47 | + | 
 | 48 | +### Naming Conventions  | 
 | 49 | + | 
 | 50 | +- **Files**: Use PascalCase (e.g., `BrowserModel.swift`, `PaneImageViewer.swift`)  | 
 | 51 | +- **Classes/Structs**: PascalCase (e.g., `FileItem`, `BrowserModel`)  | 
 | 52 | +- **Properties/Methods**: camelCase (e.g., `selectedImage`, `loadCurrentDirectory()`)  | 
 | 53 | +- **Constants**: camelCase for instance properties, SCREAMING_SNAKE_CASE for static constants  | 
 | 54 | +- **Enums**: PascalCase for type, camelCase for cases (e.g., `MediaType.staticImage`)  | 
 | 55 | + | 
 | 56 | +## 🎨 SwiftUI Best Practices  | 
 | 57 | + | 
 | 58 | +### View Structure  | 
 | 59 | + | 
 | 60 | +```swift  | 
 | 61 | +struct ExampleView: View {  | 
 | 62 | +    // MARK: - Properties  | 
 | 63 | +    @EnvironmentObject private var model: BrowserModel  | 
 | 64 | +    @State private var localState = ""  | 
 | 65 | +    @FocusState private var isFocused: Bool  | 
 | 66 | + | 
 | 67 | +    // MARK: - Computed Properties  | 
 | 68 | +    private var computedValue: String {  | 
 | 69 | +        // Implementation  | 
 | 70 | +    }  | 
 | 71 | + | 
 | 72 | +    // MARK: - Body  | 
 | 73 | +    var body: some View {  | 
 | 74 | +        // Implementation  | 
 | 75 | +    }  | 
 | 76 | + | 
 | 77 | +    // MARK: - Private Methods  | 
 | 78 | +    private func helperMethod() {  | 
 | 79 | +        // Implementation  | 
 | 80 | +    }  | 
 | 81 | +}  | 
 | 82 | + | 
 | 83 | +// MARK: - Preview  | 
 | 84 | +#Preview {  | 
 | 85 | +    ExampleView()  | 
 | 86 | +        .environmentObject(BrowserModel.preview)  | 
 | 87 | +}  | 
 | 88 | +```  | 
 | 89 | + | 
 | 90 | +### State Management Guidelines  | 
 | 91 | + | 
 | 92 | +- Use `@State` for local view state that doesn't need to be shared  | 
 | 93 | +- Use `@StateObject` for creating and owning observable objects  | 
 | 94 | +- Use `@ObservedObject` when the object is owned elsewhere  | 
 | 95 | +- Use `@EnvironmentObject` for app-wide shared state  | 
 | 96 | +- Use `@FocusState` for keyboard focus management  | 
 | 97 | +- Prefer `@Binding` for two-way data flow between parent and child views  | 
 | 98 | + | 
 | 99 | +### View Composition  | 
 | 100 | + | 
 | 101 | +- Keep views small and focused on a single responsibility  | 
 | 102 | +- Extract complex UI into separate view structs  | 
 | 103 | +- Use `@ViewBuilder` for conditional view building  | 
 | 104 | +- Prefer composition over inheritance  | 
 | 105 | +- Use view modifiers for reusable styling  | 
 | 106 | + | 
 | 107 | +## 📱 macOS-Specific Guidelines  | 
 | 108 | + | 
 | 109 | +### Window Management  | 
 | 110 | + | 
 | 111 | +- Set appropriate minimum window sizes using `.frame(minWidth:minHeight:)`  | 
 | 112 | +- Use `.windowResizability()` to control resize behavior  | 
 | 113 | +- Handle window lifecycle events appropriately  | 
 | 114 | +- Disable automatic window tabbing when inappropriate: `NSWindow.allowsAutomaticWindowTabbing = false`  | 
 | 115 | + | 
 | 116 | +### Menu Bar Integration  | 
 | 117 | + | 
 | 118 | +- Use `CommandGroup` to customize menu structure  | 
 | 119 | +- Provide keyboard shortcuts for common actions  | 
 | 120 | +- Follow macOS menu organization conventions  | 
 | 121 | +- Use `.keyboardShortcut()` modifiers consistently  | 
 | 122 | + | 
 | 123 | +### Keyboard Navigation  | 
 | 124 | + | 
 | 125 | +- Implement comprehensive keyboard navigation using `@FocusState`  | 
 | 126 | +- Use `.onKeyPress()` for custom key handling  | 
 | 127 | +- Support standard macOS keyboard shortcuts (⌘C, ⌘V, ⌘A, etc.)  | 
 | 128 | +- Ensure all interactive elements are keyboard accessible  | 
 | 129 | + | 
 | 130 | +### File System Integration  | 
 | 131 | + | 
 | 132 | +- Use `FileManager` for file operations  | 
 | 133 | +- Implement proper file access permissions and sandboxing  | 
 | 134 | +- Use `fileImporter`/`fileExporter` for user file selection  | 
 | 135 | +- Handle file system errors gracefully  | 
 | 136 | +- Support drag-and-drop operations where appropriate  | 
 | 137 | + | 
 | 138 | +## 🧬 Code Quality Standards  | 
 | 139 | + | 
 | 140 | +### Swift Language Features  | 
 | 141 | + | 
 | 142 | +```swift  | 
 | 143 | +// ✅ Good: Use modern Swift concurrency  | 
 | 144 | +@MainActor  | 
 | 145 | +class BrowserModel: ObservableObject {  | 
 | 146 | +    @Published var items: [FileItem] = []  | 
 | 147 | + | 
 | 148 | +    func loadDirectory() async {  | 
 | 149 | +        // Implementation using async/await  | 
 | 150 | +    }  | 
 | 151 | +}  | 
 | 152 | + | 
 | 153 | +// ✅ Good: Use proper access control  | 
 | 154 | +private func helperMethod() { }  | 
 | 155 | +internal var publicProperty: String = ""  | 
 | 156 | + | 
 | 157 | +// ✅ Good: Use type inference when clear  | 
 | 158 | +let items = [FileItem]()  | 
 | 159 | +let url = URL(fileURLWithPath: path)  | 
 | 160 | + | 
 | 161 | +// ✅ Good: Use guard statements for early returns  | 
 | 162 | +guard let url = selectedFile?.url else { return }  | 
 | 163 | +```  | 
 | 164 | + | 
 | 165 | +### Error Handling  | 
 | 166 | + | 
 | 167 | +- Use `Result` types for functions that can fail  | 
 | 168 | +- Throw specific, meaningful errors  | 
 | 169 | +- Handle errors gracefully in the UI  | 
 | 170 | +- Log errors appropriately for debugging  | 
 | 171 | +- Provide user-friendly error messages  | 
 | 172 | + | 
 | 173 | +### Performance Considerations  | 
 | 174 | + | 
 | 175 | +- Use lazy loading for large datasets  | 
 | 176 | +- Implement proper image caching for media files  | 
 | 177 | +- Use `Task` for background processing  | 
 | 178 | +- Cache expensive computations  | 
 | 179 | +- Optimize List and ScrollView performance with proper ID management  | 
 | 180 | + | 
 | 181 | +## 🎭 UI/UX Guidelines  | 
 | 182 | + | 
 | 183 | +### Visual Design  | 
 | 184 | + | 
 | 185 | +- Use system colors and semantic color roles  | 
 | 186 | +- Implement proper dark mode support  | 
 | 187 | +- Use SF Symbols for icons consistently  | 
 | 188 | +- Follow macOS spacing and sizing conventions  | 
 | 189 | +- Ensure proper contrast ratios for accessibility  | 
 | 190 | + | 
 | 191 | +### Animation & Transitions  | 
 | 192 | + | 
 | 193 | +- Use SwiftUI's built-in animations with `.animation()` modifier  | 
 | 194 | +- Keep animations subtle and purposeful  | 
 | 195 | +- Use appropriate animation curves (`.easeInOut`, `.spring()`)  | 
 | 196 | +- Ensure animations don't interfere with accessibility  | 
 | 197 | + | 
 | 198 | +### Loading States  | 
 | 199 | + | 
 | 200 | +- Show progress indicators for long-running operations  | 
 | 201 | +- Use skeleton loading states when appropriate  | 
 | 202 | +- Provide cancellation options for lengthy operations  | 
 | 203 | +- Display meaningful loading messages  | 
 | 204 | + | 
 | 205 | +## 🧪 Testing Guidelines  | 
 | 206 | + | 
 | 207 | +### Unit Testing  | 
 | 208 | + | 
 | 209 | +- Write tests for business logic in Models  | 
 | 210 | +- Test edge cases and error conditions  | 
 | 211 | +- Use dependency injection for testability  | 
 | 212 | +- Mock external dependencies (file system, network)  | 
 | 213 | + | 
 | 214 | +### UI Testing  | 
 | 215 | + | 
 | 216 | +- Create UI tests for critical user workflows  | 
 | 217 | +- Test keyboard navigation and accessibility  | 
 | 218 | +- Verify proper state management across views  | 
 | 219 | +- Test error handling and recovery scenarios  | 
 | 220 | + | 
 | 221 | +### Preview Testing  | 
 | 222 | + | 
 | 223 | +- Provide comprehensive SwiftUI previews  | 
 | 224 | +- Include different states and edge cases in previews  | 
 | 225 | +- Use preview data for consistent testing  | 
 | 226 | +- Test both light and dark mode appearances  | 
 | 227 | + | 
 | 228 | +## 📝 Documentation Standards  | 
 | 229 | + | 
 | 230 | +### Code Comments  | 
 | 231 | + | 
 | 232 | +```swift  | 
 | 233 | +/// Loads the current directory contents asynchronously  | 
 | 234 | +/// - Returns: Array of FileItem objects representing directory contents  | 
 | 235 | +/// - Throws: FileSystemError if directory cannot be accessed  | 
 | 236 | +@MainActor  | 
 | 237 | +func loadCurrentDirectory() async throws -> [FileItem] {  | 
 | 238 | +    // Implementation  | 
 | 239 | +}  | 
 | 240 | +```  | 
 | 241 | + | 
 | 242 | +### README and Documentation  | 
 | 243 | + | 
 | 244 | +- Keep README.md updated with current features  | 
 | 245 | +- Document API changes and breaking changes  | 
 | 246 | +- Provide setup and build instructions  | 
 | 247 | +- Include screenshots and usage examples  | 
 | 248 | + | 
 | 249 | +## 🔧 Development Tools & Workflow  | 
 | 250 | + | 
 | 251 | +### Xcode Configuration  | 
 | 252 | + | 
 | 253 | +- Use SwiftFormat or similar for code formatting  | 
 | 254 | +- Enable all relevant compiler warnings  | 
 | 255 | +- Use Xcode's built-in accessibility inspector  | 
 | 256 | +- Configure proper code signing for distribution  | 
 | 257 | + | 
 | 258 | +### Git Workflow  | 
 | 259 | + | 
 | 260 | +- Use descriptive commit messages  | 
 | 261 | +- Create feature branches for new development  | 
 | 262 | +- Use pull requests for code review  | 
 | 263 | +- Tag releases appropriately  | 
 | 264 | + | 
 | 265 | +### Dependencies  | 
 | 266 | + | 
 | 267 | +- Minimize external dependencies  | 
 | 268 | +- Prefer Apple frameworks over third-party solutions  | 
 | 269 | +- Document all dependencies and their purposes  | 
 | 270 | +- Keep dependencies updated and secure  | 
 | 271 | + | 
 | 272 | +## 🚀 Performance & Optimization  | 
 | 273 | + | 
 | 274 | +### Memory Management  | 
 | 275 | + | 
 | 276 | +- Use weak references to prevent retain cycles  | 
 | 277 | +- Implement proper cleanup in `onDisappear`  | 
 | 278 | +- Monitor memory usage in Instruments  | 
 | 279 | +- Cache frequently accessed data appropriately  | 
 | 280 | + | 
 | 281 | +### File Operations  | 
 | 282 | + | 
 | 283 | +- Perform file I/O operations on background queues  | 
 | 284 | +- Use proper file system caching  | 
 | 285 | +- Handle large files efficiently  | 
 | 286 | +- Implement progressive loading for large directories  | 
 | 287 | + | 
 | 288 | +## 🛡️ Security & Privacy  | 
 | 289 | + | 
 | 290 | +### Sandboxing  | 
 | 291 | + | 
 | 292 | +- Follow App Sandbox guidelines  | 
 | 293 | +- Request minimal necessary entitlements  | 
 | 294 | +- Handle security-scoped bookmarks properly  | 
 | 295 | +- Implement proper file access patterns  | 
 | 296 | + | 
 | 297 | +### User Privacy  | 
 | 298 | + | 
 | 299 | +- Request permissions before accessing user data  | 
 | 300 | +- Provide clear explanations for permission requests  | 
 | 301 | +- Respect user privacy preferences  | 
 | 302 | +- Implement proper data handling practices  | 
 | 303 | + | 
 | 304 | +## 📋 Code Review Checklist  | 
 | 305 | + | 
 | 306 | +Before submitting code for review, ensure:  | 
 | 307 | + | 
 | 308 | +- [ ] Code follows naming conventions and organization patterns  | 
 | 309 | +- [ ] SwiftUI views are properly structured and focused  | 
 | 310 | +- [ ] Accessibility is considered and implemented  | 
 | 311 | +- [ ] Error handling is comprehensive and user-friendly  | 
 | 312 | +- [ ] Performance implications are considered  | 
 | 313 | +- [ ] Code is properly documented  | 
 | 314 | +- [ ] Tests are written and passing  | 
 | 315 | +- [ ] Preview code is included and functional  | 
 | 316 | +- [ ] Memory management is proper (no retain cycles)  | 
 | 317 | +- [ ] File operations are secure and efficient  | 
 | 318 | + | 
 | 319 | +---  | 
 | 320 | + | 
 | 321 | +*This document should be updated as the project evolves and new patterns emerge. All team members should review and follow these guidelines to ensure consistent, high-quality code.*  | 
0 commit comments