-
Notifications
You must be signed in to change notification settings - Fork 1
Coding Standards
ronb12 edited this page Nov 25, 2025
·
2 revisions
← Back to Home | Development Guides | Contributing Guidelines
This document outlines the coding standards and best practices for Faith Journal development.
This guide ensures code consistency, readability, and maintainability across the Faith Journal project. All contributors should follow these standards.
- Clarity: Code should be clear and readable
- Consistency: Follow established patterns
- Simplicity: Prefer simple solutions
- Documentation: Document complex logic
// ✅ Good
class JournalEntry { }
struct PrayerRequest { }
enum PrayerStatus { }
// ❌ Bad
class journalEntry { }
struct prayer_request { }// ✅ Good
var journalEntry: JournalEntry
func createJournalEntry() { }
// ❌ Bad
var JournalEntry: JournalEntry
func CreateJournalEntry() { }// ✅ Good
let maxEntries = 100
let defaultTheme = "light"
// ❌ Bad
let MAX_ENTRIES = 100
let DefaultTheme = "light"// 1. Imports
import SwiftUI
import SwiftData
// 2. Type definition
struct JournalView: View {
// 3. Properties
@Query var entries: [JournalEntry]
// 4. Body
var body: some View {
// ...
}
// 5. Private methods
private func filterEntries() { }
}-
@Stateproperties -
@StateObjectproperties -
@ObservedObjectproperties -
@Queryproperties -
@Environmentproperties - Regular properties
- Computed properties
// ✅ Good: Break into smaller views
struct JournalView: View {
var body: some View {
VStack {
HeaderView()
EntryListView()
FooterView()
}
}
}
// ❌ Bad: Everything in one view
struct JournalView: View {
var body: some View {
VStack {
// 500 lines of code...
}
}
}// ✅ Good: Use appropriate property wrappers
@State private var searchText = ""
@StateObject private var viewModel = JournalViewModel()
@Query var entries: [JournalEntry]
// ❌ Bad: Overuse of @StateObject
@StateObject private var searchText = "" // Should be @State// ✅ Good: Clear model with proper types
@Model
final class JournalEntry {
var id: UUID = UUID()
var title: String = ""
var content: String = ""
var date: Date = Date()
}
// ❌ Bad: Unclear types
@Model
final class JournalEntry {
var id: Any
var title: Any
}// ✅ Good: Clear query with sorting
@Query(sort: [SortDescriptor(\JournalEntry.date, order: .reverse)])
var entries: [JournalEntry]
// ❌ Bad: No sorting
@Query var entries: [JournalEntry]// ✅ Good: Proper error handling
func fetchVerse() async throws -> BibleVerse {
do {
return try await service.fetchVerse(reference: "John 3:16")
} catch {
ErrorHandler.handle(error, context: "BibleService")
throw error
}
}
// ❌ Bad: Ignoring errors
func fetchVerse() async -> BibleVerse? {
return try? await service.fetchVerse(reference: "John 3:16")
}/// Fetches a Bible verse by reference.
/// - Parameters:
/// - reference: The verse reference (e.g., "John 3:16")
/// - translation: Optional translation (defaults to selected translation)
/// - Returns: A BibleVerseResponse containing the verse
/// - Throws: An error if the fetch fails
func fetchVerse(reference: String, translation: String? = nil) async throws -> BibleVerseResponse {
// Implementation
}- Complex algorithms
- Business logic that's not obvious
- Workarounds for bugs
- Public API documentation
// ✅ Good: Clear, concise comments
// Calculate the verse index based on day of year
let verseIndex = (dayOfYear - 1) % verses.count
// ❌ Bad: Obvious comments
// Set the verse index
let verseIndex = (dayOfYear - 1) % verses.count// ✅ Good: Lazy loading for expensive operations
lazy var expensiveComputation: String = {
// Expensive computation
return result
}()
// ❌ Bad: Eager computation
var expensiveComputation: String {
// Expensive computation - runs every time
return result
}// ✅ Good: Compress images before saving
func saveImage(_ image: UIImage) {
guard let compressed = image.jpegData(compressionQuality: 0.8) else { return }
// Save compressed data
}
// ❌ Bad: Save full resolution
func saveImage(_ image: UIImage) {
// Saves full resolution - wastes space
}// ✅ Good: Descriptive test names
func testJournalEntryCreationWithValidData() { }
func testPrayerRequestStatusUpdate() { }
// ❌ Bad: Unclear test names
func test1() { }
func testEntry() { }// ✅ Good: Arrange-Act-Assert pattern
func testJournalEntryCreation() {
// Arrange
let title = "Test Entry"
let content = "Test Content"
// Act
let entry = JournalEntry(title: title, content: content)
// Assert
XCTAssertEqual(entry.title, title)
XCTAssertEqual(entry.content, content)
}- Follows naming conventions
- Has appropriate comments
- Handles errors properly
- Has tests (if applicable)
- Updates documentation
- No performance issues
- Follows SwiftUI best practices
- Respects privacy and security
- Use Xcode's built-in warnings
- Enable all recommended warnings
- Fix warnings before committing
- Use Xcode's automatic formatting (Ctrl+I)
- Consistent indentation (4 spaces)
- Remove trailing whitespace