EXIF.ER

publicado

Categories iOS
Stack SwiftUI, PhotosUI, PhotoKit, ImageIO, AVFoundation

overview

EXIF.ER começou como um script baseado na ferramenta exiftool de Phil Harvey. Eu criei essa automação inicialmente para organizar meus backups de fotos. Como tiro muitas fotos com o iPhone, logo adaptei o script para funcionar via o app Atalhos.

Mais tarde, na Apple Developer Academy, recebemos o desafio de criar uma ferramenta que resolvesse um problema prático real. A escolha foi natural: o que começou como um script era a base perfeita para virar um aplicativo completo.

Assim nasceu o EXIF.ER. Ele renomeia fotos e vídeos automaticamente usando as datas originais de captura (EXIF para imagens, QuickTime para vídeos), permitindo escolher entre dezenas de padrões de nome para facilitar a organização.

Todo o processamento é local (on-device, sem uploads ou servidores). O app integra-se tanto ao sistema de arquivos quanto à Fototeca e é compatível com uma ampla gama de formatos, de fotos RAW como o .DNG (Apple ProRAW) a vídeos .MOV e .MP4. Os arquivos são renomeados preservando a qualidade e os metadados originais.

Disponível em 6 idiomas, desenvolver o EXIF.ER foi um desafio técnico enriquecedor que cobriu o ciclo completo de criação: da interface e código à manipulação de dados. Tenho orgulho do resultado, não apenas por ser uma ferramenta que utilizo diariamente, mas por marcar minha estreia na App Store.

tech stack

SwiftUI
framework de UI
PhotosUI
seletor de fotos e vídeos
PhotoKit
caminho rápido da fototeca
ImageIO
extração de EXIF
AVFoundation
metadados de vídeo

code snippets

Os arquivos escolhidos são movidos para o diretório temporário do app para sobreviver à limpeza do sistema. Também declaro tipos de conteúdo para vídeo e imagem para obter o arquivo original sem transcodificação lenta.

struct PhotoFile: Transferable {
    let url: URL

    /// Move para o diretório temporário para sobreviver à limpeza do sistema.
    private static func importFile(from received: ReceivedTransferredFile) throws -> PhotoFile {
        let fileName = received.file.lastPathComponent
        let destURL  = FileManager.default.temporaryDirectory.appending(path: fileName)

        if FileManager.default.fileExists(atPath: destURL.path) {
            try? FileManager.default.removeItem(at: destURL)
        }

        // Mover é instantâneo no mesmo sistema de arquivos.
        try FileManager.default.moveItem(at: received.file, to: destURL)
        return PhotoFile(url: destURL)
    }

    static var transferRepresentation: some TransferRepresentation {
        // Declara tipos específicos para obter o arquivo original.
        // O tipo genérico `.item` causaria uma transcodificação lenta (HEVC → H.264).

        FileRepresentation(contentType: .movie) { SentTransferredFile($0.url) }
            importing: { try importFile(from: $0) }

        FileRepresentation(contentType: .image) { SentTransferredFile($0.url) }
            importing: { try importFile(from: $0) }
    }
}

design choices

palette

fosco #F2F2F7
obturador #1C1C1E
flash #FFFFFF

typography

SF Pro / interface via estilos semânticos do SwiftUI
Zebras jogam xadrez com o velho faquir
SF Pro · dígitos monoespaçados / timers e contadores
00:42 · 137 / 248

some fonts used in this project are proprietary and may not display correctly if they are not installed on your system.

rationale

O EXIF.ER é um utilitário simples: escolha arquivos, escolha um padrão, execute. O design existe para não atrapalhar esse fluxo. Não há cromos de marketing, nem ilustração decorativa, nem animação comemorativa ao final: apenas a lista de arquivos, a prévia da renomeação e um estado de progresso claro. Tratar a interface como suporte, e não como o produto em si, espelha o jeito como o exiftool e outras ferramentas forenses funcionam, e mantém o foco em saber se as datas certas serão gravadas nos arquivos certos.

Esse minimalismo se estende à paleta. O app se apoia inteiramente nas cores semânticas de fundo do iOS, como .secondarySystemBackground e .tertiarySystemBackground, fazendo a interface se adaptar ao modo claro e escuro sem que eu precise escolher manualmente um segundo conjunto de valores. Os destaques em branco de alto contraste e o tom quase preto do obturador fazem o resto, mantendo a lista de arquivos legível tanto na cama quanto sob o sol.

A tipografia segue a mesma disciplina. Cada elemento usa um estilo semântico do SF Pro (.body, .headline, .subheadline, .caption), o que mantém a hierarquia nativa e entrega de graça peso, escalonamento e Dynamic Type pelo sistema. A única exceção deliberada é o .monospacedDigit() no tempo decorrido e no contador de arquivos durante o processamento: os números ali mudam várias vezes por segundo, e travar a largura dos dígitos impede que o layout fique tremendo enquanto a fila passa.

credits

people

design · development · shipping
pedro wiezel

assets

iconography