La mayoría de los modelos de mi aplicación iOS consultan un servidor web. Me gustaría tener un archivo de configuración que almacene la URL base del servidor. Se verá algo como esto:
// production
// static NSString* const baseUrl = "http://website.com/"
// testing
static NSString* const baseUrl = "http://192.168.0.123/"
Al comentar una línea u otra, puedo cambiar instantáneamente a qué servidor apuntan mis modelos. Mi pregunta es, ¿cuál es la mejor práctica para almacenar constantes globales en iOS? En la programación de Android, tenemos este archivo de recursos de cadenas integrado . En cualquier actividad (el equivalente de un UIViewController ), podemos recuperar esas constantes de cadena con:
String string = this.getString(R.string.someConstant);
Me preguntaba si el SDK de iOS tiene un lugar análogo para almacenar constantes. Si no es así, ¿cuál es la mejor práctica en Objective-C para hacerlo?
"constants.h"
enfoque, declarandostatic
variables basadas en#ifdef VIEW_CONSTANTS ... #endif
. Así que tengo un archivo de constantes para toda la aplicación, pero cada uno de mis otros archivos de código tiene#define
diferentes conjuntos de constantes para incluir antes de#include
-ing el archivo de constantes (detiene todas esas advertencias del compilador "definidas pero no utilizadas").#decalare
, recibí un error de compilación que decía " declaración de directiva de preprocesamiento no válida ". Así que lo cambié a#define
. El otro problema es usar la constante. Quería crear otra constante constatic NSString* const fullUrl = [NSString stringWithFormat:@"%@%@", kbaseUrl, @"script.php"]
, pero aparentemente es ilegal crear consts con una expresión. Recibo el error "el elemento inicializador no es constante ".#define kBaseURL @"http://192.168.0.123/";
Bueno, desea que la declaración sea local para las interfaces con las que se relaciona; el archivo de constantes de toda la aplicación no es algo bueno.
Además, es preferible simplemente declarar un
extern NSString* const
símbolo, en lugar de usar un#define
:SomeFile.h
SomeFile.m
Aparte de la omisión de la declaración Extern compatible con C ++, esto es lo que generalmente verá utilizado en los marcos Obj-C de Apple.
Si la constante debe ser visible para un solo archivo o función, entonces
static NSString* const baseUrl
en su*.m
es bueno.fuente
@"foo"
no es lo mismo que[[NSString alloc] initWithCString:"foo"]
.#define
se usa (es decir, la igualdad de puntero podría fallar), no es que una expresión literal NSString produzca un temporal siempre que se ejecute.La forma en que defino las constantes globales:
AppConstants.h
AppConstants.m
Luego, en su archivo {$ APP} -Prefix.pch:
Si tiene algún problema, primero asegúrese de tener la opción Precompile Prefix Header configurada en NO.
fuente
También puede concatenar constantes de cadena como esta:
fuente
Creo que otra forma de hacer esto es mucho más simple y solo lo incluirá en los archivos en los que necesita que estén incluidos, no TODOS los archivos, como con el archivo de prefijo .pch:
Después de eso, incluya este archivo de encabezado en el archivo de encabezado que desee. Lo incluye en el archivo de encabezado para la clase específica en la que desea que se incluya:
fuente
"error: use of undeclared identifier .."
#define BASEURl @"http://myWebService.appspot.com/xyz/xx"
luego en cualquier lugar del proyecto para usar BASEURL:
Actualizado: en Xcode 6 no encontrará el archivo .pch predeterminado creado en su proyecto. Entonces, use el archivo PCH en Xcode 6 para insertar el archivo .pch en su proyecto.
Actualizaciones: para SWIFT
& De inmediato declarar / definir miembro
Ejemplo:
fuente
Las declaraciones globales son interesantes pero, para mí, lo que cambió profundamente mi forma de codificar fue tener instancias globales de clases. Me tomó un par de días entender realmente cómo trabajar con él, así que lo resumí rápidamente aquí.
Utilizo instancias globales de clases (1 o 2 por proyecto, si es necesario), para reagrupar el acceso a los datos centrales o algunas lógicas comerciales.
Por ejemplo, si desea tener un objeto central que maneje todas las mesas del restaurante, cree su objeto al inicio y eso es todo. Este objeto puede manejar accesos a la base de datos O manejarlo en memoria si no necesita guardarlo. ¡Está centralizado, solo muestra interfaces útiles ...!
Es una gran ayuda, está orientada a objetos y es una buena manera de conseguir todas tus cosas en el mismo lugar.
Algunas líneas de código:
e implementación de objetos:
para usarlo es realmente simple:
fuente
La respuesta aceptada tiene 2 puntos débiles. Primero, como otros señalaron, su uso
#define
es más difícil de depurar, use en su lugar laextern NSString* const kBaseUrl
estructura. En segundo lugar, define un solo archivo para constantes. En mi opinión, esto es incorrecto porque la mayoría de las clases no necesitan acceso a esas constantes o para acceder a todas ellas, más el archivo puede hincharse si todas las constantes se declaran allí. Una mejor solución sería modularizar constantes en 3 capas diferentes:Capa del sistema:
SystemConstants.h
oAppConstants.h
que describe las constantes en el ámbito global, a las que puede acceder cualquier clase del sistema. Declare aquí solo aquellas constantes a las que se debe acceder desde diferentes clases que no están relacionadas.Capa
ModuleNameConstants.h
de módulo / subsistema : describe un conjunto de constantes que son típicas de un conjunto de clases relacionadas, dentro de un módulo / subsistema.Capa de clase: las constantes residen en la clase y solo las usa.
Solo 1,2 están relacionados con la pregunta.
fuente
Un enfoque que he usado antes es crear un archivo
Settings.plist
y cargarloNSUserDefaults
al iniciarlo usandoregisterDefaults:
. A continuación, puede acceder a su contenido con lo siguiente:Si bien no he realizado ningún desarrollo de Android, parece que esto es análogo al archivo de recursos de cadenas que describió. El único inconveniente es que no puede usar el preprocesador para cambiar entre configuraciones (por ejemplo, en
DEBUG
modo). Sin embargo, supongo que podrías cargar en un archivo diferente.NSUserDefaults
documentación.fuente
NSString
,NSNumber
, etc.). Claro, podrías ajustar tus correos#define
electrónicos para hacer lo mismo, pero no son tan fáciles de editar. Laplist
interfaz de edición también es agradable. :) Si bien estoy de acuerdo en que no debes poner cosas súper secretas, como claves de cifrado, no me preocupan demasiado los usuarios que están hurgando en lugares donde no deberían estar; si rompen la aplicación, es su propia culpa. .#define
s para devolver el tipo correcto, pero estoy acostumbrado a editar tales archivos de constantes, ya que siempre he aprendido a poner constantes globales como este en un archivo de constantes separado, desde los días en que aprendí Pascal en un viejo 286 :) Y en cuanto al usuario que hurga en todas partes, yo también estoy de acuerdo, es su culpa. En realidad, es solo una cuestión de gustos.Para un número puedes usarlo como
fuente
Usaría un objeto de configuración que se inicializa desde un
plist
. ¿Por qué molestar a otras clases con cosas externas irrelevantes?He creado
eppz!settigns
Soley por esta razón. Consulte el artículo Forma avanzada pero sencilla de guardar en NSUserDefaults para incorporar valores predeterminados de unplist
.fuente