Skip to content
This repository has been archived by the owner on Jan 17, 2023. It is now read-only.

Commit

Permalink
Fix AFNetworkActivityIndicatorManager for iOS 7...dubiously
Browse files Browse the repository at this point in the history
This swizzle used to assume that all `NSURLSessionTask` instances had
a superclass named `NSURLSessionTask`. That is not true on iOS
7 devices. Therefore, we need to somehow swizzle the the superclass,
which is `__NSCFLocalSessionTask` on iOS 7. This is a way to do it
without explicitly mentioning or calling any private API.

However, it does end up adding and swizzling methods on
`__NSCFLocalSessionTask`. Is this legal? I cannot say for sure.
  • Loading branch information
Phil Tang authored and tangphillip committed Feb 15, 2015
1 parent 3a1785c commit 27964aa
Showing 1 changed file with 14 additions and 6 deletions.
20 changes: 14 additions & 6 deletions AFNetworking/AFURLSessionManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -272,19 +272,27 @@ static inline void af_swizzleSelector(Class class, SEL originalSelector, SEL swi
}
}

static inline void af_addMethod(Class class, SEL selector, Method method) {
class_addMethod(class, @selector(af_resume), method_getImplementation(method), method_getTypeEncoding(method));
}

static NSString * const AFNSURLSessionTaskDidResumeNotification = @"com.alamofire.networking.nsurlsessiontask.resume";
static NSString * const AFNSURLSessionTaskDidSuspendNotification = @"com.alamofire.networking.nsurlsessiontask.suspend";

@interface NSURLSessionTask (_AFStateObserving)
@interface NSURLSessionDataTask (_AFStateObserving)
@end

@implementation NSURLSessionTask (_AFStateObserving)
@implementation NSURLSessionDataTask (_AFStateObserving)

+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
af_swizzleSelector([self class], @selector(resume), @selector(af_resume));
af_swizzleSelector([self class], @selector(suspend), @selector(af_suspend));
NSURLSessionDataTask *dataTask = [[NSURLSession sessionWithConfiguration:nil] dataTaskWithURL:nil];
Class taskClass = [dataTask superclass];
af_addMethod(taskClass, @selector(af_resume), class_getInstanceMethod(self, @selector(af_resume)));
af_addMethod(taskClass, @selector(af_suspend), class_getInstanceMethod(self, @selector(af_suspend)));
af_swizzleSelector(taskClass, @selector(resume), @selector(af_resume));
af_swizzleSelector(taskClass, @selector(suspend), @selector(af_suspend));
});
}

Expand Down Expand Up @@ -402,7 +410,7 @@ - (NSString *)taskDescriptionForSessionTasks {

- (void)taskDidResume:(NSNotification *)notification {
NSURLSessionTask *task = notification.object;
if ([task isKindOfClass:[NSURLSessionTask class]]) {
if ([task respondsToSelector:@selector(taskDescription)]) {
if ([task.taskDescription isEqualToString:self.taskDescriptionForSessionTasks]) {
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingTaskDidResumeNotification object:task];
Expand All @@ -413,7 +421,7 @@ - (void)taskDidResume:(NSNotification *)notification {

- (void)taskDidSuspend:(NSNotification *)notification {
NSURLSessionTask *task = notification.object;
if ([task isKindOfClass:[NSURLSessionTask class]]) {
if ([task respondsToSelector:@selector(taskDescription)]) {
if ([task.taskDescription isEqualToString:self.taskDescriptionForSessionTasks]) {
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingTaskDidSuspendNotification object:task];
Expand Down

0 comments on commit 27964aa

Please sign in to comment.