Pierre Felgines apresenta uma nova abordagem para simplificar a API do UIAlertController em Swift, utilizando o recurso de Function Builders introduzido na versão 5.1 da linguagem. O objetivo é criar um código mais legível e conciso, similar ao estilo SwiftUI, eliminando a necessidade de múltiplas instâncias de UIAlertAction.
porRedação
20 de julho de 2026
Compartilhar
Escrito por Pierre Felgines
em
UIAlertController com Construtores de Função
Sempre achei a API do UIAlertController muito verbosa. Você primeiro tem que criar uma instância de UIAlertController, depois criar várias instâncias de UIAlertAction e finalmente adicionar as ações ao controlador.
Neste post, mostrarei como podemos aproveitar a nova funcionalidade do Swift 5.1 de Construtores de Função para criar uma API simplificada e altamente legível.
Nosso objetivo
Vamos usar este código de exemplo:
letalertController=UIAlertController(title:"Deleção",message:"Você tem certeza?",preferredStyle:.alert)letdeleteAction=UIAlertAction(title:"Deletar",style:.destructive){_in// Executar deleção}letcancelAction=UIAlertAction(title:"Cancelar",style:.cancel)alertController.addAction(deleteAction)alertController.addAction(cancelAction)present(alertController,animated:true)
Imagem 1. Resultado
Como disse anteriormente, há muito o que escrever e podemos fazer melhor. Podemos melhorar a API com padrões regulares do Swift patterns, mas o objetivo aqui é usar construtores de função para criar este código semelhante ao SwiftUI:
Esta nova funcionalidade introduzida no Swift 5.1 ainda não está totalmente implementada. Em vez da anotação pública @functionBuilder, você deve usar a privada @_functionBuilder. No entanto, você pode encontrar os detalhes da proposta aqui.
Para entender melhor o propósito desta funcionalidade, este trecho destaca os casos de uso dos construtores de função:
Esta proposta não visa habilitar todos os tipos de DSL embutidos no Swift. Ela se concentra em um tipo específico de problema que pode ser significativamente melhorado com o uso de uma DSL: criar listas e árvores (geralmente heterogêneas) de dados a partir de padrões regulares. Isso é uma necessidade comum em várias áreas diferentes, incluindo geração de dados estruturados (por exemplo, XML ou JSON), hierarquias de visualização da interface do usuário (notavelmente incluindo o novo framework SwiftUI da Apple, que obviamente é um forte motivador para os autores) e casos semelhantes.
A proposta se concentra em uma DSL para representar árvores HTML aqui, mas também é amplamente usada no SwiftUI para criar hierarquias de visualização com o atributo @ViewBuilderaqui.
A documentação não é oficial, mas após algumas pesquisas, aqui estão os métodos que podemos implementar:
buildEither(first: Component) -> Component e buildEither(second: Component) -> Component, opcionais
O buildExpression, buildDo e buildFunction não têm efeito no momento.
Na prática
O que queremos construir no nosso caso é uma lista de ações de alerta. Uma Ação é composta por um título, um estilo (default, destructive ou cancel) e uma função, acionada quando o usuário toca no botão de alerta na tela.
Agora que temos um array de Ação, podemos criar um controlador de alerta com este método-fábrica:
funcmakeAlertController(title:String,message:String,style:UIAlertController.Style,actions:[Action])->UIAlertController{letcontroller=UIAlertController(title:title,message:message,preferredStyle:style)foractioninactions{letuiAction=UIAlertAction(title:action.Note: Se pensarmos em views e SwiftUI, isso faz sentido. De múltiplas subviews (os componentes para o @ViewBuilder), o buildBlock criará uma superview que contém todas as subviews.
No nosso caso, o tipo Component é um array de ações, então o método buildBlock pode ser escrito da seguinte forma:
E isso faz nosso código compilar novamente com condições if / else.
Loops
No momento, não temos nenhuma maneira de iterar sobre um array de strings e criar ações com elas.
Se tentarmos, sempre encontramos o mesmo erro do compilador.
let alertController = Alert(title: "Title", message: "Message") { for string in ["Action1", "Action2"] { Action.default(string) { print(string) } } }
// erro: closure containing control flow statement cannot be used with function builder
Uma maneira de resolver este problema é criar uma função auxiliar que gera uma lista de ações para cada elemento de uma sequência e, em seguida, agrupa todas essas listas de ações em uma única.
funcForIn<S
Fonte original
Conteúdo traduzido e adaptado pela redação do Notícias Mobile. Confira também a matéria na fonte original.
Usamos cookies essenciais e, com seu consentimento, cookies de analytics e publicidade. Você pode aceitar tudo, manter apenas o básico ou recusar cookies não essenciais. Consulte a Política de Privacidade.