我创建了一个带有一些默认设置的NSURLSessionConfiguration但是当我在自定义NSURLProtocol中看到使用该配置创建的请求对象时,似乎所有这些设置都没有被继承,我有点困惑。
NSURLSessionConfiguration* config = [NSURLSessionConfiguration defaultSessionConfiguration];
NSMutableArray *protocolsArray = [NSMutableArray arrayWithArray:config.protocolClasses];
[protocolsArray insertObject:[CustomProtocol class] atIndex:0];
config.protocolClasses = protocolsArray;
// ex. set some random parameters
[config setHTTPAdditionalHeaders:@{@"Authorization":@"1234"}];
[config setAllowsCellularAccess:NO];
[config setRequestCachePolicy:NSURLRequestReturnCacheDataElseLoad];
[config setHTTPShouldSetCookies:NO];
[config setNetworkServiceType:NSURLNetworkServiceTypeVoice];
[config setTimeoutIntervalForRequest:4321];
// Create a request with this configuration and start a task
NSURLSession* session = [NSURLSession sessionWithConfiguration:config];
NSURLRequest* request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://google.com"]];
NSURLSessionDataTask* task = [session dataTaskWithRequest:request];
[task resume];
在我注册的自定义NSURLProtocol中
- (void)startLoading {
...
// po [self.request valueForHTTPHeaderField:@"Authorization"] returns 1234
//
// However, I'm very confused why
//
// - allowsCellularAccess
// - cachePolicy
// - HTTPShouldHandleCookies
// - networkServiceType
// - timeoutInterval
//
// for the request return the default values unlike for the header
...
}
有没有办法检查我设置的那些参数是否被请求服从并继承?
答案 0 :(得分:0)
在处理http请求时,从基础知识开始是有帮助的,例如操作系统实际发出的请求,是否收到响应?这将部分有助于回答有关检查请求是否遵守设置参数的问题。
我会质疑您在短语中使用"继承" 这个词
有没有办法检查我设置的那些参数是否被请求服从并继承?
面向对象编程中的继承具有非常特定的含义。你实际上是否创建了具有特定属性的NSURLRequest的自定义子类(让它称之为SubClassA),然后是另一个子类(让它称之为SubClassB),并期望第二个子类(SubClassB)到从其父级(SubClassA)继承属性?如果是这样,肯定不会在您提供的代码中指出。
有几个HTTP代理程序可用于帮助确认是否正在发送HTTP请求,是否收到响应,还允许您检查请求和响应的详细信息。 Charles HTTP Proxy就是这样一个程序。使用Charles,我能够确定您提供的代码没有发出任何HTTP请求。因此,如果没有提出请求,您无法确认或拒绝任何参数。
通过将包含CustomProtocol的行注释掉作为NSURLSession配置的一部分,并使用或不使用这些行运行代码,我获得了一些可能有价值的信息:
dataTaskWithRequest
添加了一个完成块。当CustomProtocol配置行被注释掉时,此完成块被点击。 CustomProtocol的startLoading
方法未被点击。startLoading
方法已被命中。请参阅下面的代码(对原始问题中发布的代码进行了修改)。
NSURLSessionConfiguration* config = [NSURLSessionConfiguration defaultSessionConfiguration];
NSMutableArray *protocolsArray = [NSMutableArray arrayWithArray:config.protocolClasses];
//[protocolsArray insertObject:[CustomProtocol class] atIndex:0];
//config.protocolClasses = protocolsArray;
// ex. set some random parameters
[config setHTTPAdditionalHeaders:@{@"Authorization":@"1234"}];
[config setAllowsCellularAccess:NO];
[config setRequestCachePolicy:NSURLRequestReturnCacheDataElseLoad];
[config setHTTPShouldSetCookies:NO];
[config setNetworkServiceType:NSURLNetworkServiceTypeVoice];
[config setTimeoutIntervalForRequest:4321];
// Create a request with this configuration and start a task
NSURLSession* session = [NSURLSession sessionWithConfiguration:config];
NSURLRequest* request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://google.com"]];
NSURLSessionDataTask* task = [session dataTaskWithRequest:request
completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSString * auth = [request valueForHTTPHeaderField:@"Authorization"];
NSLog(@"Authorization: %@", auth);
BOOL allowsCellular = [request allowsCellularAccess];
NSString * allowsCellularString = allowsCellular ? @"YES" : @"NO";
NSLog(@"Allows cellular: %@", allowsCellularString);
}];
[task resume];
这将为您提供CustomProtocol未正确处理请求的信息。是的,当CustomProtocol配置为NSURLSession的一部分时,startLoading
方法内的断点被命中,但这并不是CustomProtocol正确处理请求的明确证据。使用CustomProtocol需要执行许多步骤,如Apple(Protocol Support,NSURLProtocol Class Reference所述,您应该确认您正在关注它。
要确保有些事情正在发挥作用:
例如:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
[NSURLProtocol registerClass:[CustomProtocol class]];
return YES;
}
下面是一个单元测试,用于验证NSURLSession
是否按预期运行(未明确使用我们的自定义协议)。请注意,此单元测试在添加到Apple自己的项目CustomHTTPProtocol的示例代码时确实通过,但未使用我们的非常裸骨CustomProtocol
- (void)testNSURLSession {
XCTestExpectation *expectation = [self expectationWithDescription:@"Testing standard NSURL Session"];
[[[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:@"https://www.apple.com/"] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
#pragma unused(data)
XCTAssertNil(error, @"NSURLSession test failed with error: %@", error);
if (error == nil) {
NSLog(@"success:%zd / %@", (ssize_t) [(NSHTTPURLResponse *) response statusCode], [response URL]);
[expectation fulfill];
}
}] resume];
[self waitForExpectationsWithTimeout:3.0 handler:^(NSError * _Nullable error) {
if(nil != error) {
XCTFail(@"NSURLSession test failed with error: %@", error);
}
}];
}
下面是一个单元测试,可用于在使用我们自己的NSURLSession
类进行配置时验证对CustomProtocol
所做的配置是否符合预期。同样,请注意,此测试使用CustomProtocol
的空实现失败,但如果使用测试驱动开发(首先创建测试,然后是允许测试通过的代码秒),这是预期的。
- (void)testCustomProtocol {
XCTestExpectation *expectation = [self expectationWithDescription:@"Testing Custom Protocol"];
NSURLSessionConfiguration* config = [NSURLSessionConfiguration defaultSessionConfiguration];
NSMutableArray *protocolsArray = [NSMutableArray arrayWithArray:config.protocolClasses];
[protocolsArray insertObject:[CustomProtocol class] atIndex:0];
config.protocolClasses = protocolsArray;
// ex. set some random parameters
[config setHTTPAdditionalHeaders:@{@"Authorization":@"1234"}];
[config setAllowsCellularAccess:NO];
[config setRequestCachePolicy:NSURLRequestReturnCacheDataElseLoad];
[config setHTTPShouldSetCookies:NO];
[config setNetworkServiceType:NSURLNetworkServiceTypeVoice];
[config setTimeoutIntervalForRequest:4321];
// Create a request with this configuration and start a task
NSURLSession* session = [NSURLSession sessionWithConfiguration:config];
NSURLRequest* request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://www.apple.com"]];
NSURLSessionDataTask* task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
#pragma unused(data)
XCTAssertNil(error, @"test failed: %@", error.description);
if (error == nil) {
NSLog(@"success:%zd / %@", (ssize_t) [(NSHTTPURLResponse *) response statusCode], [response URL]);
NSString * auth = [request valueForHTTPHeaderField:@"Authorization"];
NSLog(@"Authorization: %@", auth);
XCTAssertNotNil(auth);
BOOL allowsCellular = [request allowsCellularAccess];
XCTAssertTrue(allowsCellular);
XCTAssertEqual([request cachePolicy], NSURLRequestReturnCacheDataElseLoad);
BOOL shouldSetCookies = [request HTTPShouldHandleCookies];
XCTAssertTrue(shouldSetCookies);
XCTAssertEqual([request networkServiceType], NSURLNetworkServiceTypeVoice);
NSTimeInterval timeOutInterval = [request timeoutInterval];
XCTAssertEqualWithAccuracy(timeOutInterval, 4321, 0.01);
[expectation fulfill];
}
}];
[task resume];
[self waitForExpectationsWithTimeout:3.0 handler:^(NSError * _Nullable error) {
if(nil != error) {
XCTFail(@"Custom Protocol test failed with error: %@", error);
}
}];
}