On this page 19 sections
- 1. Concept and Purpose
- 2. SwiftUI Code Architecture Overview
- 3. UI Flow and Tab Layout
- 4. Code Quality and Practices
- 5. Haptic Feedback Logic and Precision
- 6. Color Handling and Night Mode
- 7. Layout Responsiveness
- 8. Performance
- 9. Educational Narrative
- 10. Accessibility and Localization
- 11. Readability and Maintenance
- 12. Feature Enhancements
- 13. Testing and Stability
- 14. Visual Identity and Branding
- 15. Privacy and Security
- 16. Cross‑Platform Opportunities
- 17. Design Reflection
- 18. Recommended Enhancements Summary
- 19. Final Verdict
Below is an honest, technical review of the app’s code design, UI structure, and performance characteristics, followed by constructive improvement suggestions and potential extensions.
1. Concept and Purpose
MetricEdition reimagines how humans perceive the passage of time. It’s both an educational tool and a minimalist clock that bridges the past (the French Decimal Time Revolution of 1793) and the present (the Apple Watch ecosystem of 2025). Rather than relying merely on numerics, the app visually associates time with the sun and moon’s cycle, adds haptic feedback for both standard and metric hours, and provides a toggleable “red night mode” — all while running offline, ad‑free, and with zero external dependencies.
This design philosophy deserves praise. Many modern apps overcomplicate simple ideas with cloud integrations and analytics. MetricEdition, by contrast, focuses on self‑contained functionality, teaching and visualizing at the same time.
2. SwiftUI Code Architecture Overview
The entire app lives inside the ContentView struct. Its simplicity makes the logic easy to follow; the structure is perfect for a one‑person project or portfolio app.
@State private var selectedTab = 1
@State private var fractionOfDay: Double = 0.0
@State private var isHapticsOn = false
@State private var isMetricHapticsOn = false
@State private var isNightModeOn = false
@State private var previousMetricHour: Int?The view uses a one‑second Combine timer and calls a render() method that calculates the fraction of the day and handles haptic feedback at metric and standard hour boundaries.
3. UI Flow and Tab Layout
The TabView organizes the app into four clean sections:
- Main Clock View – sun/moon animation and live metric time.
- Settings – Night Mode and haptic toggles.
- Historical Context – explains metric time’s origins in 1793 France.
- About – project credits, privacy statement, and support contact.
The UI is compact and swipe‑friendly, consistent with watchOS design language.
4. Code Quality and Practices
Comments are well written, naming conventions intuitive, and state management purely SwiftUI. For longevity, consider splitting logic into composable child views. Example:
struct TimeDisplayView: View {
let fractionOfDay: Double
let isNightModeOn: Bool
var body: some View {
VStack {
Text(timeString(from: fractionOfDay))
.font(.system(size: 32, weight: .bold))
.foregroundColor(isNightModeOn ? Color(hex: "ea3323") : Color(hex: "685b4f"))
}
}
private func timeString(from fractionOfDay: Double) -> String {
let hh = Int(fractionOfDay * 10)
let mm = Int((fractionOfDay * 10 - Double(hh)) * 100)
let ss = Int((fractionOfDay * 100000).truncatingRemainder(dividingBy: 100))
return "\(hh):\(String(format: "%02d", mm)):\(String(format: "%02d", ss))"
}
}This keeps your main content view concise and modular.
5. Haptic Feedback Logic and Precision
if isHapticsOn && date.minutes == 0 && date.seconds == 0 {
WKInterfaceDevice.current().play(.success)
}The logic works well but may drift slightly. Improve precision via TimelineView:
TimelineView(.periodic(from: .now, by: 1)) { context in
let fraction = fractionOfDay(from: context.date)
TimeDisplayView(fractionOfDay: fraction, isNightModeOn: isNightModeOn)
}6. Color Handling and Night Mode
The Color(hex:) extension is elegant. Make it failable for safer parsing:
extension Color {
init?(hex: String) {
let cleaned = hex.trimmingCharacters(in: CharacterSet.alphanumerics.inverted)
guard let int = UInt64(cleaned, radix: 16) else { return nil }
self.init(
.sRGB,
red: Double((int >> 16) & 0xFF) / 255,
green: Double((int >> 8) & 0xFF) / 255,
blue: Double(int & 0xFF) / 255,
opacity: 1
)
}
}You may eventually wish to replace colorMultiply with explicit color sets to preserve OLED pixel integrity in Night Mode.
7. Layout Responsiveness
GeometryReader { geometry in
Image("sunmoon")
.resizable()
.scaledToFit()
.frame(width: geometry.size.width * 0.4)
.rotationEffect(.degrees(-360 * fractionOfDay))
}This ensures visuals adapt gracefully to all watch sizes.
8. Performance
- Cache static images to avoid redraws.
- Suspend timer updates when backgrounded using
@Environment(\.scenePhase). - Avoid redundant animation blocks on every tick.
9. Educational Narrative
The historical copy is concise and valuable, but consider chunking paragraphs into swipeable pages:
TabView {
ForEach(historyParagraphs, id: \.self) { paragraph in
Text(paragraph)
.padding()
.multilineTextAlignment(.leading)
}
}.tabViewStyle(PageTabViewStyle())10. Accessibility and Localization
Text(timeString)
.accessibilityLabel("Metric time")
.accessibilityValue("\(hh) hours, \(mm) minutes, and \(ss) seconds")Externalize all copy in Localizable.strings for multi‑language support (French translations would tie in nicely with the app’s origin story).
11. Readability and Maintenance
Refactor date constants and formatters:
private let millisecondsPerDay: Double = 86_400_000
fractionOfDay = timeOfDay / millisecondsPerDayUsing constants increases clarity and prevents “magic numbers.”
12. Feature Enhancements
a) Complication Support
struct MetricTimeComplication: Widget {
var body: some WidgetConfiguration {
StaticConfiguration(kind: "metricTime", provider: MetricProvider()) { entry in
MetricComplicationView(entry: entry)
}
.supportedFamilies([.circularSmall, .modularSmall])
}
}b) Data Visualization
Integrate Apple Charts to visualize activity patterns in metric units.
c) Custom Themes
enum Theme: String, CaseIterable {
case day, night, red, gold
}13. Testing and Stability
#if DEBUG
print("Debug info: metric hour – \(metricHour)")
#endiffunc testFractionToMetricTime() {
let fraction = 0.5
let time = MetricConverter.timeString(from: fraction)
XCTAssertEqual(time, "5:00:00")
}14. Visual Identity and Branding
StromaScape’s warm palette complements the scientific theme. You can enhance transitions with a little animation:
.animation(.easeInOut(duration: 0.5), value: isNightModeOn)15. Privacy and Security
Clearly stating that no analytics or ads exist builds user trust. Consider listing the same on Apple’s privacy “nutrition label” for extra transparency.
16. Cross‑Platform Opportunities
Web Version (Example JS)
const updateMetricTime = () => {
const now = new Date();
const fraction = (now.getHours() * 3600 + now.getMinutes() * 60 + now.getSeconds()) / 86400;
const metricHour = Math.floor(fraction * 10);
const metricMinute = Math.floor((fraction * 1000) % 100);
document.getElementById('metricClock').textContent =
`${metricHour}:${metricMinute.toString().padStart(2, '0')}`;
};
setInterval(updateMetricTime, 1000);
updateMetricTime();Embedding the above snippet on stromascape.com lets visitors explore metric time interactively.
17. Design Reflection
MetricEdition combines curiosity, clarity, and craftsmanship, re‑introducing a 230‑year‑old temporal idea using contemporary UI metaphors. Every design choice— from red‑hued night lighting to the rotating solar disc— heightens the user’s awareness of time’s flow.
18. Recommended Enhancements Summary
| Area | Current Approach | Suggested Improvement |
|---|---|---|
| Architecture | Single file | Split into modular SwiftUI views |
| Timer precision | Combine timer | Use TimelineView / Swift Concurrency |
| Night mode | colorMultiply | Use explicit theme palettes |
| Accessibility | Minimal | Add VoiceOver & Dynamic Type |
| Localization | English only | Add Localizable.strings |
| Performance | Always on timer | Suspend in background |
| Testing | Manual | Unit tests for time conversion |
| Branding | Static colors | Add animated theme transitions |
| Future scope | Watch‑only | Add WidgetKit & iPhone companion |
19. Final Verdict
MetricEdition demonstrates how a single developer can merge art, history, and technology. Its transparent privacy model and lack of bloat are rare virtues. As a first SwiftUI project, the app already meets a professional baseline and only needs modularization and accessibility upgrades to be feature‑store ready.
If time ever needed re‑education, this is exactly the kind of app to teach it — simply, beautifully, mathematically.
Formerly on leejohnson.it. Written by Lee Johnson.