I need to add method to NSURLSessionTask
. Here's my category which is supposed to do that:
// NSURLSessionTask+Extras.h
#import <Foundation/Foundation.h>
@interface NSURLSessionTask (Extras)
- (void)helloNSURLSessionTask;
@end
// NSURLSessionTask+Extras.m
#import "NSURLSessionTask+Extras.h"
@implementation NSURLSessionTask (Extras)
- (void)helloNSURLSessionTask {
NSLog(@"hello NSURLSessionTask!");
}
@end
Everything compiles well, autocomplete works, but when I call this method, my application crashes:
2014-06-27 12:32:23.916 Test[4333:60b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFLocalDataTask helloNSURLSessionTask]: unrecognized selector sent to instance 0x109723310'
Same approach works if I add category to NSObject
, and I can't seem to understand why it doesn't for NSURLSessionTask
.
Here's a test project which reproduces this problem for me: https://dl.dropboxusercontent.com/u/25100182/Test.zip
Unfortunately it doesn't seem that NSURLSession can support categories. I've run into a problem like that trying to add an associated object.
See also here.
I had similar issue at NSURLSessionDataTask category, when I reduced the scope to NSURLSessionTask it seems to be working correctly.
@interface NSURLSessionTask (iRemoteWallet)
@property (nonatomic, weak) id context;
@end
Hope this helps.
I believe I know what is the origin of this rather odd (to me at least) behaviour. I will provide an example that I've encountered with NSURLSessionDataTask in iOS 9.2.
When you try to use the method that you've added in a category -myMethod: you will see an exception like this:
[__NSCFLocalDataTask -myMethod]: unrecognised selector sent to instance
I've started digging and discovered that __NSCFLocalDataTask class that hides behind our NSURLSessionDataTask class at runtime is just casted to NSURLSessionDataTask but does not inherit from it. This class inheritance chain is __NSCFLocalDataTask : __NSCFLocalSessionTask : __NSCFURLSessionTask : NSObject. So my category does not apply to this class at all. No wonder it is unrecognised.
One solution to this might be to move your category to NSObject and make a bunch of checking. I did it like this:
if ([self respondsToSelector:@selector(response)]) {
id response = [self performSelector:@selector(response)];
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
return [NSString stringWithFormat:@"%td", ((NSHTTPURLResponse *)response).statusCode];
}
}
NSException *e =[NSException exceptionWithName:NSInternalInconsistencyException reason:@"errorCode: method should be only used on classes that implement -(NSHTTPURLResponse *)response: method." userInfo:nil];
@throw e;
Ugly? Yes! But it works for now.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With