📷 Camera App

Referências Técnicas

Documentação técnica aprofundada sobre implementação, performance e decisões de arquitetura.


📚 Documentos Disponíveis

🔄 Fluxo de Dados

Como os dados fluem através da aplicação, diagramas de sequência e ciclos de vida.

Ver documentação →

⚡ Performance

Otimizações aplicadas, benchmarks e best practices para manter a app performática.

Ver documentação →

🎯 Escolhas Técnicas

Decisões de arquitetura, trade-offs e justificativas técnicas.

Ver documentação →

🐛 Troubleshooting

Guia completo de debugging e solução de problemas comuns.

Ver documentação →

🎓 Tópicos Avançados

AVFoundation

SwiftUI + UIKit

Core Image


🧵 Threading Deep Dive

Queues Utilizadas

Queue Label Tipo Uso
Main com.apple.main-thread Serial UI updates, @Published
Session camera.session.queue Serial AVFoundation config
UserInitiated .userInitiated Concurrent Thumbnails
Utility .utility Concurrent Video export

Sincronização

// ViewModel → Controller (async) controller.setZoomFactor(2.0, animated: true) // Controller → ViewModel (main thread callback) DispatchQueue.main.async { self.isSessionRunning = true } // Heavy work → Main thread DispatchQueue.global(qos: .userInitiated).async { let thumbnail = generateThumbnail() DispatchQueue.main.async { self.segments.append(segment) } } 

📊 Performance Metrics

Configuração Inicial

Operação Tempo Típico Thread
Request Permissions ~100ms Main
Configure Session ~300ms sessionQueue
Start Session ~200ms sessionQueue
Total ~600ms Mixed

Gravação

Operação Tempo Thread
Start Recording ~50ms sessionQueue
Stop Recording ~100ms sessionQueue
Generate Thumbnail ~150ms Background
Append to UI ~10ms Main

Export

Operação Tempo (30s vídeo) Thread
Create Composition ~50ms Main
Export (sem filtro) ~5s Background
Export (com filtro) ~15s Background
Save to Photos ~500ms Main

🔧 Extensibilidade

Adicionar Novo Filtro

// 1. Adicionar case no enum enum VideoFilter: String, CaseIterable { case none case mono case sepia // ← Novo } // 2. Implementar no applyFilter switch filterType { case .sepia: let filter = CIFilter.sepiaTone() filter.intensity = 0.8 filter.inputImage = src output = filter.outputImage // ... } 

Adicionar Nova Feature de Câmera

// 1. Propriedade no ViewModel @Published var isGridEnabled: Bool = false // 2. Método de controle func toggleGrid() { isGridEnabled.toggle() } // 3. UI na ContentView if model.isGridEnabled { GridOverlay() } 

📈 Benchmarking

Como Medir Performance

import os.signpost let log = OSLog(subsystem: "com.pedro.Camera", category: "Performance") // Iniciar medição let signpostID = OSSignpostID(log: log) os_signpost(.begin, log: log, name: "VideoExport", signpostID: signpostID) // Operação... exporter.exportAsynchronously { ... } // Terminar medição os_signpost(.end, log: log, name: "VideoExport", signpostID: signpostID) 

Ver resultados: Instruments → Points of Interest


🏗️ Padrões Arquiteturais

MVVM

Vantagens:

Trade-offs:

Delegation

Quando usar:

Alternativa: Closures para callbacks simples

Coordinator Pattern

Quando usar:


🔍 Debugging Tips

AVFoundation Issues

// Print todos os formatos disponíveis for format in device.formats { print("Format: \(format)") print("FPS ranges: \(format.videoSupportedFrameRateRanges)") } // Print configuração atual print("Active format: \(device.activeFormat)") print("Active frame rate: \(device.activeVideoMaxFrameDuration)") print("Zoom factor: \(device.videoZoomFactor)") 

Threading Issues

// Assert main thread dispatchPrecondition(condition: .onQueue(.main)) // Assert background thread dispatchPrecondition(condition: .notOnQueue(.main)) // Print current thread print("Thread: \(Thread.current)") 

Memory Leaks

// Use weak self em closures controller.configureSession { [weak self] error in guard let self = self else { return } // ... } // Instruments → Leaks para detectar 

📚 Recursos Adicionais

Apple Documentation

WWDC Sessions


← Guias Fluxo de Dados →