Um relato de bug de filtro que virou três issues separadas
O relato era simples: “as configurações de filtro da playlist não estão sendo aplicadas”. Rastreei a cadeia inteira antes de assumir qualquer coisa, da tela de Settings até o view model, até a renderização real da lista, e cada elo se sustentava. Uma única instância compartilhada de SettingsStore, um passthrough getter/setter ao vivo, uma propriedade filtrada genuinamente computada (não cacheada), e a view de lista lendo a propriedade filtrada, não a crua. No papel, nada estava errado.
Então olhei para a tela de fato em vez de continuar lendo código. Não era a lista principal de Playlist de jeito nenhum, era a seção de sugestões “More from artist” dentro do sheet de detalhes do álbum, uma barra de filtro separada que eu tinha construído numa sessão anterior com um comentário dizendo, em outras palavras, “isso é intencionalmente independente do filtro da própria aba”. Correto como projetado, errado como vivenciado.
Essa distinção importou para o que aconteceu depois. Eu não simplesmente conectei o filtro independente ao principal e chamei de resolvido, isso teria revertido silenciosamente uma decisão deliberada anterior. Fiquei um tempo com as duas opções óbvias, unificar ou manter separados, e a resposta acabou não sendo nenhuma das duas: manter independentes, mas dar ao filtro independente seu próprio padrão dedicado nas Settings em vez de um “mostrar tudo” fixo no código. Um terceiro caminho que o enquadramento original nem tinha oferecido, e o certo.
A implementação foi pequena: mais um Set<RecordingType> persistido em SettingsStore seguindo o mesmo padrão que os outros dois já usavam, uma nova seção nas Settings, e um init customizado do SwiftUI para que o filtro @State local da seção parta do novo padrão em vez de um literal fixo no código, continuando local depois disso, para que mudanças dentro do sheet não vazem de volta para Settings. Verifiquei no simulador com automação de UI em vez de simplesmente confiar: defini o novo padrão para Album-only, abri um sheet de sugestões novo, confirmei que começava filtrado; ativei um chip dentro do sheet, voltei para Settings, confirmei que o padrão não tinha mudado.
Três issues saíram de um relato de bug, e só uma delas era de fato um bug no sentido que o relato queria dizer. As outras duas eram uma condição de corrida intermitente e uma decisão de escopo, e tratá-las como três coisas separadas em vez de enfiar fixes em qualquer issue que estivesse aberta na hora manteve cada uma honesta sobre o que ela realmente era.
Leitura relacionada
A configuração que funcionava perfeitamente e parecia completamente quebrada
Um filtro só era aplicado ao reabrir o app, porque uma TabView mantém os view models vivos e seu estado semeado fica congelado. A correção apagou um conceito.
Os botões não estavam quebrados: a main thread estava ocupada
118 testes verdes, uma passada limpa no simulador, e botões mortos num telefone de verdade. O bug era um serviço @MainActor fazendo trabalho síncrono entre awaits.
Desbloqueio vitalício com StoreKit 2 num app SwiftUI em Swift 6: três coisas que me pegaram
A API de compra é a parte fácil. As junções entre StoreKit 2, isolamento do Swift 6 e observação do SwiftUI foram onde o tempo foi.
Você também pode achar útil
Proton Mail
E-mail criptografado de ponta a ponta, com arquitetura de acesso zero.
Como parceiro da Proton, ganho com compras qualificadas dos serviços de privacidade e segurança da Proton (Pass, Mail, VPN, Drive).
Saiba maiseSIM Airalo
eSIM de dados local para viagens - sem necessidade de trocar um SIM físico.
Este é meu link de indicação da Airalo. Você recebe um desconto no seu primeiro eSIM e eu ganho crédito da Airalo para o meu.
Saiba maisProton VPN
VPN comercial com filtragem NetShield e interruptor de desligamento automático.
Como parceiro da Proton, ganho com compras qualificadas dos serviços de privacidade e segurança da Proton (Pass, Mail, VPN, Drive).
Saiba mais