2011-04-13 9 views
29

Soy nuevo en Objective-C. Básicamente, quiero almacenar un conjunto de URL de punto final como cadenas para su uso en mi aplicación, pero necesito un dominio diferente en función de si la aplicación está en modo DEPURADOR o no. Pensé que podría ser útil usar un archivo de cabecera (Common.h por ejemplo) con unos simples define así:Cómo # #define un NSString para uso global?

#ifdef DEBUG 
    #define kAPIEndpointHost @"http://example.dev" 
#else 
    #define kAPIEndpointHost @"http://www.example.com" 
#endif 

#define kAPIEndpointLatest   [kAPIEndpointHost stringByAppendingString:@"/api/latest_content"] 
#define kAPIEndpointMostPopular  [kAPIEndpointHost stringByAppendingString:@"/api/most_popular"] 

Obviamente esto no funciona ya que no puede basar una constante en el valor de otra de las constantes aparentemente.

¿Cuál es la forma "correcta" de hacer esto? ¿Tendría más sentido simplemente tener una clase adecuada con métodos de clase que devuelvan los valores de punto final correctos?

EDIT: Para que quede claro, las cadenas "último" y "mostPopular" que son basado en la cadena del host son lo que yo estoy teniendo más problemas con. Al compilador no le gusta la parte stringByAppendingString de #defines.

+0

no veo lo que está mal con esto, TBPH. –

+0

El compilador se queja de la parte 'stringByAppendingString'. Supongo que no puedes # definir una constante basada en otra constante como esta. – markquezada

+2

¿Cuál es el mensaje de error del compilador real? Acabo de usar el fragmento de código anterior y se compiló/ejecutó muy bien. –

Respuesta

63

Si acaba de concatenación de cadenas, puede utilizar el tiempo de compilación de concatenación de cadenas:

#ifdef DEBUG 
    #define kAPIEndpointHost @"http://example.dev" 
#else 
    #define kAPIEndpointHost @"http://www.example.com" 
#endif 

#define kAPIEndpointLatest   (kAPIEndpointHost @"/api/latest_content") 
#define kAPIEndpointMostPopular  (kAPIEndpointHost @"/api/most_popular") 
+0

Supongo que esto era realmente lo que estaba preguntando. ¡Gracias! – markquezada

+0

Ahora, ¿qué ocurre si quiero usar una variable en lugar de una URL codificada? P.ej. #define kAPIEndpointHost VariableName donde VariableName se inicializa en la vista anterior. –

+0

@JayprakashDubey Antes que nada, evitaría usar elementos externos en macros. Debería usar un método NSString ya que la concatenación de este tipo solo funciona en tiempo de compilación.Me gustaría '#define kAPILatestPath @"/api/latest_content "' y compilarlo en la función usando 'NSString * APIEndpointLatest = [variableName stringByAppendingString: APILatestPath];' – cobbal

11

En el archivo de cabecera:

extern NSString *const kAPIEndpointHost; 
extern NSString *const kAPIEndpointLatestPath; 
extern NSString *const kAPIEndpointMostPopularPath; 

En el archivo de aplicación:

#ifdef DEBUG 
    NSString *const kAPIEndpointHost = @"http://example.dev"; 
#else 
    NSString *const kAPIEndpointHost = @"http://www.example.com"; 
#endif 

NSString *const kAPIEndpointLatestPath = @"/api/latest_content"; 
NSString *const kAPIEndpointMostPopularPath = @"/api/most_popular"; 
+0

Gracias por la respuesta. Sin embargo, todavía no estoy seguro de cómo definir las constantes Latest y MostPopular basadas en el valor del host. – markquezada

+0

@mirthlab, simplemente los combinaría en código cuando estén creando el objeto 'NSURL'. –

+0

+1 Parece que esta es la forma más correcta de definir las constantes de cadena para uso externo, supongo que realmente estaba buscando más cómo concatenar las cadenas en tiempo de compilación. Aprecio la respuesta! – markquezada

19

No me gusta usar #defines para las constantes de cadena. Si desea constantes globales y compilación de tiempo de compilación. Me gustaría utilizar el siguiente: archivo

Cabecera: archivo

extern NSString *const kAPIEndpointHost; 
extern NSString *const kAPIEndpointLatestPath; 
extern NSString *const kAPIEndpointMostPopularPath; 

Implementación:

#ifdef DEBUG 
#define API_ENDPOINT_HOST @"http://example.dev" 
#else 
#define API_ENDPOINT_HOST @"http://www.example.com" 
#endif 

NSString *const kAPIEndpointHost = API_ENDPOINT_HOST; 
NSString *const kAPIEndpointLatestPath = (API_ENDPOINT_HOST @"/api/latest_content"); 
NSString *const kAPIEndpointMostPopularPath = (API_ENDPOINT_HOST @"/api/most_popular"); 
+0

Gracias por el enfoque alternativo. ¿Cuidar para explicar por qué esto es más deseable que definir la cadena usando un #define? – markquezada

+5

Una definición es solo una macro, por lo que cada vez que aparece la macro, se está creando una nueva cadena. A const NSString crea solo una referencia de cadena. También encuentro que las constantes son más fáciles de usar en todos los archivos y en el caso de las claves, el valor real de la constante puede ocultarse en el archivo de implementación, ya que su valor real es irrelevante para la implementación. – Eric

+0

Impresionante, gracias. +1 para la enseñanza :) – markquezada