changing AFNetworking baseURL

caiman picture caiman · Jul 24, 2012 · Viewed 8k times · Source

I am using AFNetworking with the singleton model suggested in their example.

+ (SGStockRoomHTTPClient *)sharedClient
{
    static SGStockRoomHTTPClient *_sharedClient = nil;
    static dispatch_once_t oncePredicate;
    dispatch_once(&oncePredicate, ^{
        NSString *baseUrlString = [[NSUserDefaults standardUserDefaults] stringForKey:@"server_root_url_preference"];
        _sharedClient = [[self alloc] initWithBaseURL:[NSURL URLWithString:baseUrlString]];
    });

    return _sharedClient;
}

- (id)initWithBaseURL:(NSURL *)url {
    self = [super initWithBaseURL:url];
    if (!self) {
        return nil;
    }
    [self registerHTTPOperationClass:[AFJSONRequestOperation class]];
    [self setDefaultHeader:@"Accept" value:@"text/html"];
return self;
}

Initialization is done with a baseURL taken from the user defaults.

My problem is that the baseURL property is read-only. If the user goes to settings and changes the baseURL user default, how can I change it in my client?

Another similar case I have with a need to change the baseURL is an API which requires multiple calls and logic to determine to the right baseURL. And the base url can still change while the app is running (e.g. user changes networking environment requiring a change from local connection to 3G connection via external proxy server.).

I see why the baseURL property is read-only: there are things like networkReachabilityStatus that run in the background and are tied to that setting. This said, it seems fairly easy to have a setBaseURL method that stops monitoring, changes the value, then starts monitoring again...

I guess my design is not right, should I give-up the singleton in this case and re-create the client each time the baseURL should change?

Answer

Felix picture Felix · Jul 25, 2012

The class AFHTTPClient is designed to work with a single base URL. This is why it is readonly.

Here are some solutions if you have more than one base URL:

  • in your AFHTTPClient subclass override the property qualifier. Place this inside the @interface: @property (readwrite, nonatomic, retain) NSURL *baseURL;

  • Don't use AFHTTPClient at all

  • Create multiple instances of AFHTTPClient

  • When you create HTTP operations you can override the baseURL. Just set the full URL in the path instead of a relative path.