TNLExample/TAPI/TAPIRequest.m (181 lines of code) (raw):
//
// TAPIRequest.m
// TwitterNetworkLayer
//
// Created on 10/17/14.
// Copyright © 2020 Twitter. All rights reserved.
//
#import "TAPIRequest.h"
#import "TNL_Project.h"
NSString * const TAPIRequestDomainDefault = @"api.twitter.com";
NSString * const TAPIRequestVersion1_1 = @"1.1";
@interface TAPIRetryPolicyProvider : NSObject <TNLRequestRetryPolicyProvider>
@end
@implementation TAPIRequest
{
NSString *_baseURLString;
TNLParameterCollection *_parameters;
}
- (NSString *)scheme
{
return @"https";
}
- (NSString *)domain
{
return TAPIRequestDomainDefault;
}
- (NSString *)version
{
return TAPIRequestVersionDefault;
}
- (NSString *)endpoint
{
// Requires override
[self doesNotRecognizeSelector:_cmd];
return nil;
}
- (TNLParameterCollection *)parameters
{
if (!_parameters) {
TNLMutableParameterCollection *params = [[TNLMutableParameterCollection alloc] init];
[self prepareParameters:params];
_parameters = [params copy];
}
return _parameters;
}
- (void)prepareParameters:(TNLMutableParameterCollection *)params
{
}
- (TNLHTTPMethod)HTTPMethodValue
{
return TNLHTTPMethodGET;
}
- (NSDictionary *)allHTTPHeaderFields
{
NSMutableDictionary *d = [NSMutableDictionary dictionary];
d[@"Accept"] = TNLHTTPContentTypeJSON;
if (self.HTTPMethodValue == TNLHTTPMethodPOST) {
d[@"Content-Type"] = TNLHTTPContentTypeURLEncodedString;
}
return d;
}
+ (Class)responseClass
{
return Nil;
}
- (NSString *)baseURLString
{
if (_baseURLString) {
return _baseURLString;
}
NSMutableString *URLString = [NSMutableString string];
NSString *component;
component = self.scheme;
if (0 == component.length) {
return nil;
}
[URLString appendString:component];
[URLString appendString:@"://"];
component = self.domain;
if (0 == component.length) {
return nil;
}
[URLString appendString:component];
component = self.version;
if (0 != component.length) {
[URLString appendString:@"/"];
[URLString appendString:component];
}
component = self.endpoint;
if (0 == component.length) {
return nil;
}
[URLString appendString:@"/"];
[URLString appendString:component];
_baseURLString = [URLString copy];
return _baseURLString;
}
- (NSURL *)URL
{
NSMutableString *URLString = (id)[self.baseURLString mutableCopy];
if (!URLString) {
return nil;
}
TNLParameterCollection *parameters = self.parameters;
if (parameters.count > 0 && TNLHTTPMethodPOST != self.HTTPMethodValue) {
NSString *component = [parameters stableURLEncodedStringValue];
if (0 != component.length) {
[URLString appendString:@"?"];
[URLString appendString:component];
}
}
return [NSURL URLWithString:URLString];
}
- (NSData *)HTTPBody
{
NSData *body = nil;
if (TNLHTTPMethodPOST == self.HTTPMethodValue) {
@autoreleasepool {
TNLParameterCollection *parameters = self.parameters;
if (parameters.count > 0) {
NSString *URLParameters = [parameters stableURLEncodedStringValue];
if (URLParameters.length > 0) {
body = [URLParameters dataUsingEncoding:NSUTF8StringEncoding];
}
}
}
}
return body;
}
+ (TNLRequestConfiguration *)configuration
{
static TNLRequestConfiguration *sDefaultConfig;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
TNLMutableRequestConfiguration *config = [TNLMutableRequestConfiguration defaultConfiguration];
config.URLCache = nil;
config.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
config.redirectPolicy = TNLRequestRedirectPolicyRedirectToSameHost;
sDefaultConfig = [config copy];
});
return sDefaultConfig;
}
+ (id<TNLRequestRetryPolicyProvider>)retryPolicyProvider
{
return nil;
}
- (id)copyWithZone:(NSZone *)zone
{
return self;
}
@end
@implementation TAPIRetriableRequest
+ (id<TNLRequestRetryPolicyProvider>)retryPolicyProvider
{
static TAPIRetryPolicyProvider *sActionRetryPolicyProvider;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sActionRetryPolicyProvider = [[TAPIRetryPolicyProvider alloc] init];
});
return sActionRetryPolicyProvider;
}
@end
@implementation TAPIRetryPolicyProvider
{
TNLRequestRetryPolicyConfiguration *_config;
}
- (instancetype)init
{
self = [super init];
if (self) {
_config = [[TNLRequestRetryPolicyConfiguration alloc] initWithRetriableMethods:@[@"POST"]
statusCodes:@[@503]
URLErrorCodes:TNLStandardRetriableURLErrorCodes()
POSIXErrorCodes:TNLStandardRetriablePOSIXErrorCodes()];
}
return self;
}
- (BOOL)tnl_shouldRetryRequestOperation:(TNLRequestOperation *)op withResponse:(TNLResponse *)response
{
// one retry
if (response.metrics.attemptCount != 0) {
return NO;
}
return [_config requestCanBeRetriedForResponse:response];
}
- (NSTimeInterval)tnl_delayBeforeRetryForRequestOperation:(TNLRequestOperation *)op withResponse:(TNLResponse *)response
{
return 1.0;
}
@end