16

我将 AFNetworking 与他们示例中建议的单例模型一起使用。

+ (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;
}

使用取自用户默认值的 baseURL 完成初始化。

我的问题是 baseURL 属性是只读的。如果用户转到设置并更改 baseURL 用户默认值,我如何在我的客户端中更改它?

我需要更改 baseURL 的另一个类似情况是一个 API,它需要多次调用和逻辑来确定正确的 baseURL。并且在应用程序运行时,基本 url 仍然可以更改(例如,用户更改网络环境需要通过外部代理服务器从本地连接更改为 3G 连接。)。

我明白为什么 baseURL 属性是只读的:诸如 networkReachabilityStatus 之类的东西在后台运行并与该设置相关联。这就是说,似乎很容易有一个 setBaseURL 方法停止监视,更改值,然后再次开始监视......

我想我的设计不对,在这种情况下我是否应该放弃单例并在每次 baseURL 发生变化时重新创建客户端?

4

2 回答 2

23

该类AFHTTPClient旨在使用单个基本 URL。这就是为什么它是只读的。

如果您有多个基本 URL,以下是一些解决方案:

  • 在您的AFHTTPClient子类中覆盖属性限定符。将其放在@interface 中:@property (readwrite, nonatomic, retain) NSURL *baseURL;

  • AFHTTPClient完全不要使用

  • 创建多个实例AFHTTPClient

  • 创建 HTTP 操作时,您可以覆盖 baseURL。只需在路径中设置完整的 URL 而不是相对路径。

于 2012-07-25T12:08:08.207 回答
0

希望这可以帮助你。

@interface EFApiClient : AFHTTPSessionManager
@property (nonatomic,assign)BOOL isTestEnvironment ;
+ (instancetype)sharedMClient;
@end


@implementation EFApiClient
+ (instancetype)sharedMClient
{
    if ([EFApiClient sharedClient].isTestEnvironment) {
        return [EFApiClient sharedTestClient] ;
    }
    else{
        return [EFApiClient sharedClient];
    }
}   

+ (instancetype)sharedClient
{
    static EFApiClient *_sharedMClient = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _sharedMClient = [[EFApiClient alloc] initWithBaseURL:[NSURL URLWithString:@"https://xxx.xxx.com"]];
        [EFApiClient clientConfigWithManager:_sharedMClient];
    });
    return _sharedMClient;
}
+ (instancetype)sharedTestClient
{
    static EFApiClient *_sharedMClient = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _sharedMClient = [[EFApiClient alloc] initWithBaseURL:[NSURL URLWithString:@"https://test.xxx.xxx.com"]];
        [EFApiClient clientConfigWithManager:_sharedMClient];
    });
    return _sharedMClient;
}

+ (void)clientConfigWithManager:(EFApiClient *)client
{
    AFSecurityPolicy* policy = [[AFSecurityPolicy alloc] init];
    [policy setAllowInvalidCertificates:YES];
    [policy setValidatesDomainName:NO];
    [client setSecurityPolicy:policy];
    client.requestSerializer = [AFHTTPRequestSerializer serializer];
    client.responseSerializer = [AFHTTPResponseSerializer serializer];
    //client.requestSerializer.HTTPMethodsEncodingParametersInURI = [NSSet setWithArray:@[@"POST", @"GET", @"HEAD"]];
    client.responseSerializer = [AFJSONResponseSerializer serializer];
    client.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/x-javascript",@"application/json", @"text/json", @"text/html", nil];
}
@end
于 2018-01-31T02:46:33.497 回答