Alternativa rápida para o diagnóstico de #pragma clang
Problema
Encontrei recentemente um aviso em um utilitário de terceiros (WEPopover) neste trecho de código:
_effectivePopoverContentSize = _contentViewController.contentSizeForViewInPopover;
Isso estava gerando o seguinte aviso:
warning: 'contentSizeForViewInPopover' is deprecated: first deprecated in iOS 7.0 - Use UIViewController.preferredContentSize instead. [-Wdeprecated-declarations]
_effectivePopoverContentSize = _contentViewController.contentSizeForViewInPopover;
Uma correção temporária para isso no Objective-C é usar o diagnóstico de pragma clang para silenciar o erro (deixarei o autor do código lidar com uma correção verdadeira). Revisei o código da seguinte forma:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
_effectivePopoverContentSize = _contentViewController.contentSizeForViewInPopover;
#pragma clang diagnostic pop
Pergunta, questão
O que funciona muito bem, mas isso me levou a considerar o que se existe alguma alternativa onde seria necessário silenciar um aviso falso positivo semelhante ao codificar em Swift?
Considerações
Observei o fato de que posso desativar esses avisos em todo o projeto (usando as configurações do Xcode), mas quero considerar o problema interno, conforme observado acima. Também considerei adicionar um #define em um arquivo .bridging-header.h no meu projeto Swift e, de alguma forma, usá-lo; no entanto, estou procurando uma solução específica do Swift para esse problema. Entendo que o pragma não está mais disponível e procurei no SO e encontrei perguntas semelhantes, mas não duplicadas.
RESOLUÇÃO ATUALIZADA: Swift 2.0
A resposta fornecida trata da minha preocupação com avisos embutidos. O comando de disponibilidade deve permitir que tais problemas sejam evitados por completo, porque um seria avisado em tempo de compilação.
O livro Swift da Apple afirma definitivamente:
“Você usa uma condição de disponibilidade em uma instrução if ou guard para executar condicionalmente um bloco de código, dependendo se as APIs que você deseja usar estão disponíveis em tempo de execução. O compilador usa as informações da condição de disponibilidade quando verifica se as APIs nesse “bloco de código estão disponíveis.
if #available(iOS 9, OSX 10.10, *) {
// Use iOS 9 APIs on iOS, and use OS X v10.10 APIs on OS X
} else {
// Fall back to earlier iOS and OS X APIs
}
”
Trecho de: Apple Inc. “A linguagem de programação Swift (pré-lançamento do Swift 2).” IBooks.https://itun.es/us/k5SW7.l ”
Pode-se até usar a declaração de guarda combinada com a disponibilidade para sair do escopo mais cedo, a menos que as condições disponíveis sejam atendidas.
guard #available(iOS 8.0, OSX 10.10, *) else { return }
Trecho de: Apple Inc. “Usando Swift com cacau e Objective-C (pré-lançamento do Swift 2).” IBooks.https://itun.es/us/utTW7.l
Além disso, minhas preocupações relacionadas ao manuseio de macros são abordadas conforme observado abaixo. Tendo em mente que o Swift não tem pré-processador, essas ferramentas parecem o caminho a seguir.
“Macros simples
Onde você normalmente usava a diretiva #define para definir uma constante primitiva em C e Objective-C, no Swift você usa uma constante global. Por exemplo, a definição constante #define FADE_ANIMATION_DURATION 0.35 pode ser melhor expressa em Swift com a tecla FADE_ANIMATION_DURATION = 0.35. Como macros simples do tipo constante são mapeadas diretamente para variáveis globais do Swift, o compilador importa automaticamente macros simples definidas nos arquivos de origem C e Objective-C. ”
Trecho de: Apple Inc. “Usando Swift com cacau e Objective-C (pré-lançamento do Swift 2).” IBooks.https://itun.es/us/utTW7.l
“Macros complexas
Macros complexas são usadas em C e Objective-C, mas não têm contrapartida no Swift. Macros complexas são macros que não definem constantes, incluindo macros entre parênteses, semelhantes a funções. Você usa macros complexas em C e Objective-C para evitar restrições de verificação de tipo ou para redigitar grandes quantidades de código padrão. No entanto, as macros podem dificultar a depuração e refatoração. No Swift, você pode usar funções e genéricos para obter os mesmos resultados sem comprometer. Portanto, as "macros complexas que estão nos arquivos de origem C e Objective-C não são disponibilizadas para o seu código Swift".
Trecho de: Apple Inc. “Usando Swift com cacau e Objective-C (pré-lançamento do Swift 2).” IBooks.https://itun.es/us/utTW7.l
O desenvolvedor da API poderá marcar a disponibilidade de funções no Swift usando:
available(iOS 8.0, OSX 10.10, *)
func useShinyNewFeature() {
// ...
}
Trecho de: Apple Inc. “Usando Swift com cacau e Objective-C (pré-lançamento do Swift 2).” IBooks.https://itun.es/us/utTW7.l
Adicionar esses marcadores a funções reescritas para o Swift parece ser uma boa maneira de manter a compatibilidade com versões anteriores do Frameworks. A combinação guarda / disponível permitirá que os usuários dessas estruturas ajustem a lógica conforme necessário. O que me deixa à vontade para lidar com avisos em linha, fallback de API e macros em geral.