0

In my project I am working on it since last 6 months , i was using #define to define all URL in a FileManager class.but Now I came to know that I have to use two different URL depend on condition so dynamically I can not change #define values.so I decided to Use extern variables in FileManager class instead of #define.

as in interface file

       extern NSString *Url;
       extern NSString *loginUrl;

in m file

        @implementation UrlManager
        + (void) initialize{
        Url=@"http://xxxxxxxxxx.com";
        loginUrl=[NSString stringWithFormat:@"%@%@",Url,@"/ipad.php?method=audLogin&username="];
             }

but when I am importing URLManager.h , and using loginUrl, still its null , please help me how can I initialize extern variables so that I can use these in app.

Ali
  • 10,774
  • 10
  • 56
  • 83
  • In the .m file, do you have the lines: `NSString *Url;` and `NSString *loginUrl;` before the `@implementation` line? Are you using ARC or MRC? – rmaddy May 24 '13 at 16:29
  • Side note - why not initialize `loginURL` this way: `loginUrl=[NSString stringWithFormat:@"%@/ipad.php?method=audLogin&username=", Url];` – rmaddy May 24 '13 at 16:31
  • See http://stackoverflow.com/questions/15035932/using-an-extern-global-before-it-is-properly-initialized for a possible cause of your issue. The last paragraph of the answer by "bbum" mentions this. – rmaddy May 24 '13 at 22:29

1 Answers1

2

First, if you have a URL, use NSURL to reference it.

Secondly, name your globals consistently and descriptively. AliRootURL and AliLoginURL would be descriptive and has a prefix (Ali -- change it) to make it easy to recognize.

Finally, don't use globals at all. Instead, have class methods on your URLManager class (which really should be prefixed, too) that return the URLs:

@interface AliURLManager:NSObject
+(NSURL*)rootURL; // no need to prefix methods in your custom classes
+(NSURL*)loginURL;
@end

That way, you can implement those methods to initially return URLs directly:

+(NSURL*)rootURL
{
     // use a static and dispatch_once() if you want only one instance
     return [NSURL URLWithString:@"http://foobar.com/"];
}
+(NSURL*)loginURL
{
     NSURL* root = [self rootURL];
     NSURL* loginURL;
     ... calculate loginURL here... (http://stackoverflow.com/questions/718429/creating-url-query-parameters-from-nsdictionary-objects-in-objectivec)
    return loginURL;
}

That way, you could easily refactor your code to, say, read URLs from the defaults database or have a different configuration for development.


Bummer -- but I can understand the desire to not change lots of files. Should be search and replaceable, though (at least, would be if your variables were a bit more descriptive).

If you are going to initialize the globals via +initialize, you need to ensure that the class is tickled. Add [URLManager class]; to your applicationDidFinishLaunching:

bbum
  • 162,346
  • 23
  • 271
  • 359
  • No I cant use methods now ,as i want to change only one file , doing this I have to change 100 of files – Ali May 24 '13 at 17:03