iOS实现HTTP拦截器

需求背景

目前项目中有一个模块使用Cordova实现Hybrid方案,由于该模块访问后端的时候是需要验证用户信息的,但是用户的登录的又是在原生端,为了使该模块和原生共享一个token,由此产生了这样一个需求:实现一个HTTP拦截器,为该模块的接口请求动态注入token。

NSURLProtocol

官方说明:NSURLProtocol对象用于处理特定URL协议的数据加载,NSURLProtocol类本身是一个抽象类,你需要为自己的应用创建它的子类。你不用直接实例化NSURLProtocol类的子类,你只需要在应用启动的时候调用 NSURLProtocol的registerClass:类方法就可以了。

示例代码

static NSString * const CLURLProtocolHandleKey = @"CLURLProtocolHandleKey";

@interface CLURLProtocol ()

@property (nonatomic, strong) NSMutableData *responseData;
@property (nonatomic, strong) NSURLConnection *connection;

@end

@implementation CLURLProtocol

+ (BOOL)canInitWithRequest:(NSURLRequest *)request {
	 //这里需要填写自己的判断逻辑,因为现实情况是满足某些条件的请求才去处理。
	BOOL condition = .....;
    if (condition && ![NSURLProtocol propertyForKey: CLURLProtocolHandleKey inRequest:request]) {
        return YES;
    }
    return NO;
}

+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request {
    NSMutableURLRequest *mutableRequest = [request mutableCopy];
    //这里实现了URL的重定向,看具体的需求,
    NSURL *host = [NSURL URLWithString:@"your domain"];
    if (host) {
        mutableRequest.URL = [NSURL URLWithString:[NSString stringWithFormat:@"%@%@", host.absoluteString, [request.URL.absoluteString stringByReplacingOccurrencesOfString:@"file://" withString:@""]]];
        [mutableRequest setValue:yourToken forHTTPHeaderField:@"token"];
        return mutableRequest;
    } else {
        return request;
    }
}

- (void)startLoading {
    NSMutableURLRequest *mutableReqeust = [[self request] mutableCopy];
    //标示改request已经处理过了,防止无限循环
    [NSURLProtocol setProperty:@YES forKey:CLURLProtocolHandleKey inRequest:mutableReqeust];
    self.connection = [NSURLConnection connectionWithRequest:mutableReqeust delegate:self];
}

- (void)stopLoading {
    [self.connection cancel];
}

#pragma mark- NSURLConnectionDelegate
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    [self.client URLProtocol:self didFailWithError:error];
}

#pragma mark - NSURLConnectionDataDelegate
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    self.responseData = [[NSMutableData alloc] init];
    [self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [self.responseData appendData:data];
    [self.client URLProtocol:self didLoadData:data];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    [self.client URLProtocolDidFinishLoading:self];
}
参考资料

Updated:

Comments