Skip to content

Commit

Permalink
Update logging logic and .podspec
Browse files Browse the repository at this point in the history
  • Loading branch information
kubatruhlar committed Sep 22, 2016
1 parent 616e68f commit 465b64e
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 43 deletions.
37 changes: 18 additions & 19 deletions AFNetworking+RetryPolicy.podspec
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
Pod::Spec.new do |s|
s.name = 'AFNetworking+RetryPolicy'
s.version = '1.0.0'
s.summary = 'Nice category that adds the ability to set the retry interval, retry count and progressive.'

s.description = 'If the request timed out, you usually have to call the request again by yourself. AFNetworking+RetryPolicy handles that for you. Adds the ability to set the retry interval, retry count and progressive.'

s.homepage = 'https://github.com/kubatru/AFNetworking-RetryPolicy'
s.screenshots = 'https://raw.githubusercontent.com/kubatru/AFNetworking-RetryPolicy/master/Images/logo.png'

s.license = { :type => 'MIT', :file => 'LICENSE.md' }
s.author = 'Jakub Truhlar'
s.social_media_url = 'http://kubatruhlar.cz'
s.platform = :ios, '7.0'
s.source = { :git => 'https://github.com/kubatru/AFNetworking-RetryPolicy.git', :tag => '1.0.0' }
s.source_files = 'AFNetworking+RetryPolicy/*'
s.framework = 'Foundation'
s.dependency 'AFNetworking', '~> 3.0'
s.requires_arc = true
Pod::Spec.new do |spec|
spec.name = 'AFNetworking+RetryPolicy'
spec.version = '1.0.0'
spec.summary = 'Nice category that adds the ability to set the retry interval, retry count and progressive.'
spec.description = 'If the request timed out, you usually have to call the request again by yourself. AFNetworking+RetryPolicy handles that for you. Adds the ability to set the retry interval, retry count and progressive.'
spec.homepage = 'https://github.com/kubatru/AFNetworking-RetryPolicy'
spec.screenshots = 'https://raw.githubusercontent.com/kubatru/AFNetworking-RetryPolicy/master/Images/logo.png'
spec.license = {:type => 'MIT', :file => 'LICENSE.md'}
spec.author = 'Jakub Truhlar'
spec.social_media_url = 'http://kubatruhlar.cz'
spec.platform = :ios, '7.0'
spec.source = {:git => 'https://github.com/kubatru/AFNetworking-RetryPolicy.git', :tag => '1.0.0'}
spec.source_files = 'AFNetworking+RetryPolicy/*.{h,m}'
spec.framework = 'Foundation'
spec.requires_arc = true
# Dependencies (Operators =, >=, >, <=, < and ~>)
spec.dependency 'AFNetworking', '~> 3.0'
spec.dependency 'ObjcAssociatedObjectHelpers', '2.0.1'
end
12 changes: 7 additions & 5 deletions AFNetworking+RetryPolicy/AFHTTPSessionManager+RetryPolicy.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
// - Copyright (c) 2016 Jakub Truhlar. All rights reserved.
//

#import "Foundation/Foundation.h"
#import "AFHTTPSessionManager.h"
#import <Foundation/Foundation.h>
#import <AFNetworking/AFHTTPSessionManager.h>

typedef int (^RetryDelayCalcBlock)(int, int, int); // int totalRetriesAllowed, int retriesRemaining, int delayBetweenIntervalsModifier

Expand All @@ -27,8 +27,10 @@ typedef int (^RetryDelayCalcBlock)(int, int, int); // int totalRetriesAllowed, i
*/
@interface AFHTTPSessionManager (RetryPolicy)

@property (strong) id tasksDict;
@property (copy) id retryDelayCalcBlock;
/**
* Turns retry policy log messages on. Only in `DEBUG` target. Default is `false`.
*/
@property (nonatomic, assign) bool retryPolicyLogMessagesEnabled;

/**
* Adds the ability to set the retry interval, retry count and progressive (uses power rule e.g. interval = 3 -> 3, 9, 27 etc.). `failure` is called no earlier than `retryCount` = 0, only `fatalStatusCodes` finishes the request earlier.
Expand Down Expand Up @@ -65,4 +67,4 @@ typedef int (^RetryDelayCalcBlock)(int, int, int); // int totalRetriesAllowed, i
*/
- (NSURLSessionDataTask *)DELETE:(NSString *)URLString parameters:(NSDictionary *)parameters success:(void (^)(NSURLSessionDataTask *task, id responseObject))success failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure retryCount:(NSInteger)retryCount retryInterval:(NSTimeInterval)retryInterval progressive:(bool)progressive fatalStatusCodes:(NSArray<NSNumber *> *)fatalStatusCodes;

@end
@end
48 changes: 31 additions & 17 deletions AFNetworking+RetryPolicy/AFHTTPSessionManager+RetryPolicy.m
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,32 @@
// - Copyright (c) 2016 Jakub Truhlar. All rights reserved.
//

#import <ObjcAssociatedObjectHelpers/ObjcAssociatedObjectHelpers.h>

#import "AFHTTPSessionManager+RetryPolicy.h"
#import "ObjcAssociatedObjectHelpers.h"

static bool const kDebugLoggingEnabled = false;
@interface AFHTTPSessionManager()

@property (strong) id tasksDict;
@property (copy) id retryDelayCalcBlock;

@end

@implementation AFHTTPSessionManager (RetryPolicy)

SYNTHESIZE_ASC_OBJ(__tasksDict, setTasksDict);
SYNTHESIZE_ASC_OBJ(__retryDelayCalcBlock, setRetryDelayCalcBlock);
SYNTHESIZE_ASC_PRIMITIVE(__retryPolicyLogMessagesEnabled, setRetryPolicyLogMessagesEnabled, bool);

static inline void RetryPolicyLog(NSString *log, ...) {
#ifdef DEBUG
if (kDebugLoggingEnabled) {
va_list args;
va_start(args, log);
va_end(args);
NSLogv([NSString stringWithFormat:@"RetryPolicy: %@", log], args);
- (void)logMessage:(NSString *)message, ... {
if (!self.__retryPolicyLogMessagesEnabled) {
return;
}
#ifdef DEBUG
va_list args;
va_start(args, message);
va_end(args);
NSLogv([NSString stringWithFormat:@"RetryPolicy: %@", message], args);
#endif
}

Expand Down Expand Up @@ -56,6 +64,13 @@ - (id)tasksDict {
return self.__tasksDict;
}

- (bool)retryPolicyLogMessagesEnabled {
if (!self.__retryPolicyLogMessagesEnabled) {
[self setRetryPolicyLogMessagesEnabled:false];
}
return self.__retryPolicyLogMessagesEnabled;
}

- (BOOL)isErrorFatal:(NSError *)error {
switch (error.code) {
case kCFHostErrorHostNotFound:
Expand Down Expand Up @@ -124,21 +139,20 @@ - (BOOL)isErrorFatal:(NSError *)error {
- (NSURLSessionDataTask *)requestUrlWithRetryRemaining:(NSInteger)retryRemaining maxRetry:(NSInteger)maxRetry retryInterval:(NSTimeInterval)retryInterval progressive:(bool)progressive fatalStatusCodes:(NSArray<NSNumber *> *)fatalStatusCodes originalRequestCreator:(NSURLSessionDataTask *(^)(void (^)(NSURLSessionDataTask *, NSError *)))taskCreator originalFailure:(void(^)(NSURLSessionDataTask *task, NSError *))failure {
void(^retryBlock)(NSURLSessionDataTask *, NSError *) = ^(NSURLSessionDataTask *task, NSError *error) {
if ([self isErrorFatal:error]) {
RetryPolicyLog(@"Request failed with fatal error: %@ - Will not try again!", error.localizedDescription);
failure(task, error);
[self logMessage:@"Request failed with fatal error: %@ - Will not try again!", error.localizedDescription];
return;
}

NSHTTPURLResponse *response = (NSHTTPURLResponse *)task.response;
for (NSNumber *fatalStatusCode in fatalStatusCodes) {
if (response.statusCode == fatalStatusCode.integerValue) {
RetryPolicyLog(@"Request failed with fatal error: %@ - Will not try again!", error.localizedDescription);
[self logMessage:@"Request failed with fatal error: %@ - Will not try again!", error.localizedDescription];
failure(task, error);
return;
}
}

RetryPolicyLog(@"Request failed: %@, %ld attempt/s left", error.localizedDescription, retryRemaining);
[self logMessage:@"Request failed: %@, %ld attempt/s left", error.localizedDescription, retryRemaining];
if (retryRemaining > 0) {
void (^addRetryOperation)() = ^{
[self requestUrlWithRetryRemaining:retryRemaining - 1 maxRetry:maxRetry retryInterval:retryInterval progressive:progressive fatalStatusCodes:fatalStatusCodes originalRequestCreator:taskCreator originalFailure:failure];
Expand All @@ -147,11 +161,11 @@ - (NSURLSessionDataTask *)requestUrlWithRetryRemaining:(NSInteger)retryRemaining
dispatch_time_t delay;
if (progressive) {
delay = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(pow(retryInterval, (maxRetry - retryRemaining) + 1) * NSEC_PER_SEC));
RetryPolicyLog(@"Delaying the next attempt by %.0f seconds …", pow(retryInterval, (maxRetry - retryRemaining) + 1));
[self logMessage:@"Delaying the next attempt by %.0f seconds …", pow(retryInterval, (maxRetry - retryRemaining) + 1)];

} else {
delay = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(retryInterval * NSEC_PER_SEC));
RetryPolicyLog(@"Delaying the next attempt by %.0f seconds …", retryInterval);
[self logMessage:@"Delaying the next attempt by %.0f seconds …", retryInterval];
}

// Not accurate because of "Timer Coalescing and App Nap" - which helps to reduce power consumption.
Expand All @@ -164,7 +178,7 @@ - (NSURLSessionDataTask *)requestUrlWithRetryRemaining:(NSInteger)retryRemaining
}

} else {
RetryPolicyLog(@"No more attempts left! Will execute the failure block.");
[self logMessage:@"No more attempts left! Will execute the failure block."];
failure(task, error);
}
};
Expand Down Expand Up @@ -223,4 +237,4 @@ - (NSURLSessionDataTask *)DELETE:(NSString *)URLString parameters:(NSDictionary
return task;
}

@end
@end
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
## Installation
1. There are two ways to add the **AFNetworking+RetryPolicy** library to your project. Add it as a regular library or install it through **CocoaPods** with `pod 'AFNetworking+RetryPolicy'`

2. Use `#import "AFNetworking+RetryPolicy.h"`
2. Use `#import "AFHTTPSessionManager+RetryPolicy.h"`

## Usage (Example)
- Simple `GET` request will look like this.
Expand All @@ -42,7 +42,7 @@
} retryCount:5 retryInterval:2.0 progressive:false fatalStatusCodes:@[@401, @403]];
```
- You can also turn on the logging in the category to see what happens (`kDebugLoggingEnabled = true`).
- You can also turn on logging to see what is going on by setting the `AFHTTPSessionManager`’s `retryPolicyLogMessagesEnabled` property to `true`. Is off by default.
## Author and credit
- This library is open-sourced and maintained by [Jakub Truhlar](http://kubatruhlar.cz).
Expand Down

0 comments on commit 465b64e

Please sign in to comment.