A maioria dos modelos em meu aplicativo iOS consulta um servidor web. Eu gostaria de ter um arquivo de configuração armazenando a URL base do servidor. Vai parecer algo assim:
// production
// static NSString* const baseUrl = "http://website.com/"
// testing
static NSString* const baseUrl = "http://192.168.0.123/"
Comentando uma linha ou outra, posso alterar instantaneamente para qual servidor meus modelos apontam. Minha pergunta é: qual é a prática recomendada para armazenar constantes globais no iOS? Na programação Android, temos esse arquivo de recurso de strings integrado . Em qualquer Activity (o equivalente a um UIViewController ), podemos recuperar essas constantes de string com:
String string = this.getString(R.string.someConstant);
Eu queria saber se o iOS SDK tem um lugar análogo para armazenar constantes. Se não, qual é a melhor prática em Objective-C para fazer isso?
"constants.h"
abordagem, declarandostatic
variáveis com base em#ifdef VIEW_CONSTANTS ... #endif
. Portanto, tenho um arquivo de constantes para todo o aplicativo, mas cada um dos meus outros arquivos de código contém#define
diferentes conjuntos de constantes a serem incluídos antes#include
do arquivo de constantes (interrompe todos os avisos do compilador "definidos, mas não usados").#decalare
, recebi um erro de compilação dizendo " declaração de diretiva de pré-processamento inválida ". Então mudei para#define
. O outro problema é usar a constante. Eu queria criar outra constante comstatic NSString* const fullUrl = [NSString stringWithFormat:@"%@%@", kbaseUrl, @"script.php"]
, mas aparentemente é ilegal criar consts com uma expressão. Recebo o erro "o elemento inicializador não é constante ".#define kBaseURL @"http://192.168.0.123/";
Bem, você quer a declaração local para as interfaces às quais se relaciona - o arquivo de constantes do aplicativo não é uma coisa boa.
Além disso, é preferível simplesmente declarar um
extern NSString* const
símbolo, em vez de usar um#define
:SomeFile.h
SomeFile.m
Além da omissão da declaração Extern compatível com C ++, isso é o que geralmente você verá sendo usado nos frameworks Obj-C da Apple.
Se a constante precisa ser visível para apenas um arquivo ou função, então
static NSString* const baseUrl
em seu*.m
é bom.fonte
@"foo"
não é o mesmo que[[NSString alloc] initWithCString:"foo"]
.#define
é usada (ou seja, a igualdade do ponteiro pode falhar) - não que uma expressão literal NSString produza um temporário sempre que executada.A maneira como defino constantes globais:
AppConstants.h
AppConstants.m
Em seguida, em seu arquivo {$ APP} -Prefix.pch:
Se você tiver problemas, primeiro certifique-se de que a opção Cabeçalho do prefixo de pré-compilação esteja definida como NÃO.
fonte
Você também pode concatenar constantes de string como esta:
fonte
Eu acho que outra maneira de fazer isso é muito mais simples e você apenas incluirá isso nos arquivos em que precisa que eles sejam incluídos, não em TODOS os arquivos, como com o arquivo de prefixo .pch:
Depois disso, você inclui esse arquivo de cabeçalho no arquivo de cabeçalho que deseja. Você o inclui no arquivo de cabeçalho para a classe específica em que deseja que ele seja incluído:
fonte
"error: use of undeclared identifier .."
#define BASEURl @"http://myWebService.appspot.com/xyz/xx"
em seguida, em qualquer lugar do projeto para usar BASEURL:
Atualizado: No Xcode 6 você não encontrará o arquivo .pch padrão criado em seu projeto. Portanto, use o arquivo PCH no Xcode 6 para inserir o arquivo .pch em seu projeto.
Atualizações: Para SWIFT
& Declarar / definir imediatamente o membro
Exemplo:
fonte
Declarações globais são interessantes, mas, para mim, o que mudou profundamente minha maneira de codificar foi ter instâncias globais de classes. Levei alguns dias para entender realmente como trabalhar com isso, então rapidamente resumi aqui
Eu uso instâncias globais de classes (1 ou 2 por projeto, se necessário), para reagrupar o acesso aos dados principais ou algumas lógicas comerciais.
Por exemplo, se você deseja que um objeto central manipule todas as mesas de restaurante, você cria seu objeto na inicialização e é isso. Este objeto pode manipular acessos ao banco de dados OU manipulá-lo na memória se você não precisar salvá-lo. É centralizado, você mostra apenas interfaces úteis ...!
É uma grande ajuda, orientada a objetos e uma boa maneira de colocar todas as suas coisas no mesmo lugar
Algumas linhas de código:
e implementação de objeto:
para usá-lo é muito simples:
fonte
A resposta aceita tem 2 pontos fracos. Primeiro, como outros apontaram, o uso
#define
é mais difícil de depurar, use aextern NSString* const kBaseUrl
estrutura. Segundo, ele define um único arquivo para constantes. IMO, isso está errado porque a maioria das classes não precisa de acesso a essas constantes ou para acessar todas elas, mais o arquivo pode ficar inchado se todas as constantes forem declaradas lá. Uma solução melhor seria modularizar constantes em 3 camadas diferentes:Camada do sistema:
SystemConstants.h
ouAppConstants.h
que descreve constantes em escopo global, que podem ser acessadas por qualquer classe do sistema. Declare aqui apenas as constantes que devem ser acessadas de classes diferentes que não estão relacionadas.Camada
ModuleNameConstants.h
de módulo / subsistema : descreve um conjunto de constantes típicas de um conjunto de classes relacionadas, dentro de um módulo / subsistema.Camada de classe: as constantes residem na classe e são usadas apenas por ela.
Apenas 1,2 estão relacionados à pergunta.
fonte
Uma abordagem que usei antes é criar um arquivo
Settings.plist
e carregá-loNSUserDefaults
ao iniciar usandoregisterDefaults:
. Você pode acessar seu conteúdo com o seguinte:Embora eu não tenha feito nenhum desenvolvimento para Android, parece que isso é análogo ao arquivo de recurso de strings que você descreveu. A única desvantagem é que você não pode usar o pré-processador para alternar entre as configurações (por exemplo, no
DEBUG
modo). Suponho que você possa carregar um arquivo diferente.NSUserDefaults
documentação.fonte
NSString
,NSNumber
, etc.). Claro, você poderia embrulhar seus programas#define
para fazer a mesma coisa, mas eles não são tão fáceis de editar. Aplist
interface de edição também é boa. :) Embora eu concorde que você não deve colocar coisas supersecretas como chaves de criptografia lá, não estou muito preocupado com os usuários que estão bisbilhotando em lugares onde não deveriam estar - se eles quebrarem o aplicativo, é sua própria culpa .#define
s para retornar o tipo correto, mas estou acostumado a editar esses arquivos de constantes, já que sempre aprendi a colocar constantes globais como esse em um arquivo de constantes separado, desde os dias em que aprendi Pascal em um velho 286 :) E quanto ao usuário que bisbilhota em todos os lugares, eu também concordo, a culpa é dele. É só uma questão de gosto, na verdade.Para um número, você pode usá-lo como
fonte
Eu usaria um objeto de configuração que inicializa a partir de um
plist
. Por que incomodar outras classes com coisas externas irrelevantes?Eu criei apenas
eppz!settigns
por esse motivo. Veja o artigo Maneira avançada, porém simples de salvar em NSUserDefaults para incorporar valores padrão de aplist
.fonte