iOS:在运行时找不到NSURLSession类别的方法
我想在NSURLSession上创build一个类别。 该应用程序编译好,但是当我试图调用我得到的类别方法
-[__NSCFURLSession doSomething]: unrecognized selector sent to instance 0xbf6b0f0 <unknown>:0: error: -[NSURLSession_UPnPTests testCategory] : -[__NSCFURLSession doSomething]: unrecognized selector sent to instance 0xbf6b0f0
很奇怪,这里是一个testing课,我用来展示这个问题。 NSString类别工作正常,但NSURLSession类别在运行时找不到方法。 我怀疑这是内在的东西。
意见请:-)
#import <XCTest/XCTest.h> @interface NSString (test) -(void) doSomethingHere; @end @implementation NSString (test) -(void) doSomethingHere { NSLog(@"Hello string"); } @end @interface NSURLSession (test) -(void) doSomething; @end @implementation NSURLSession (test) -(void) doSomething { NSLog(@"Hello!!!!"); } @end @interface NSURLSession_UPnPTests : XCTestCase @end @implementation NSURLSession_UPnPTests -(void) testCategory { [@"abc" doSomethingHere]; NSURLSession *session = [NSURLSession sharedSession]; [session doSomething]; } @end
我有类似的结果与NSURLSessionUploadTask
背景,在-URLSession:task:didCompleteWithError:
委托callback过程中,它被反序列化为__NSCFURLSessionUploadTask
。
如果我是你,我会放弃这种做法,并使用组合(即使NSURLSession
在另一个对象中NSURLSession
一个ivar)。 如果您需要使用NSURLSession
存储一些信息,则可以将一个JSON编码的字典填充到.sessionDescription
。
以下是我用来完成任务的代码:
#pragma mark - Storing an NSDictionary in NSURLSessionTask.description // This lets us attach some arbitrary information to a NSURLSessionTask by JSON-encoding // an NSDictionary, and storing it in the .description field. // // Attempts at creating subclasses or categories on NSURLSessionTask have not worked out, // because the –URLSession:task:didCompleteWithError: callback passes an // __NSCFURLSessionUploadTask as the task argument. This is the best solution I could // come up with to store arbitray info with a task. - (void)storeDictionary:(NSDictionary *)dict inDescriptionOfTask:(NSURLSessionTask *)task { NSData *data = [NSJSONSerialization dataWithJSONObject:dict options:0 error:nil]; NSString *stringRepresentation = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; [task setTaskDescription:stringRepresentation]; [stringRepresentation release]; } - (NSDictionary *)retrieveDictionaryFromDescriptionOfTask:(NSURLSessionTask *)task { NSString *desc = [task taskDescription]; if (![desc length]) { DDLogError(@"No description for %@", task); return nil; } NSData *data = [desc dataUsingEncoding:NSUTF8StringEncoding]; NSDictionary *dict = (data ? (id)[NSJSONSerialization JSONObjectWithData:data options:0 error:nil] : nil); if (!dict) { DDLogError(@"Could not parse dictionary from task %@, description\n%@", task, desc); } return dict; }
如果你真的想把类添加到NSURLSession中,这是一个替代解决scheme。 我从BETURLSession中find了这个解决scheme。 当然,你必须非常小心名称,以避免名称冲突。
代码为标题
#import <Foundation/Foundation.h> @interface NSURLSession (YTelemetry) -(void) hello; @end
实施守则
#import "NSURLSession+YTelemetry.h" @implementation NSObject (YTelemetry) -(void) hello { NSLog(@"hello world"); } @end
现在在代码中,我可以
NSURLSession *session = [NSURLSession sharedSession]; [session hello];
我试图做@粘土桥(即为每个任务存储一个userInfo NSDictionary
)相同,并使用NSURLSession
与会议configuration不同于背景时,它的作品很好。 如果您使用带有后台configuration的NSURLSession
,并且您的应用程序被终止或崩溃,则上传/下载将在后台继续,由操作系统pipe理。 当上传/下载完成时,如果我尝试检索先前存储的userInfo NSDictionary
,我什么也得不到。 我的解决scheme是使用NSURLProtocol
: +setProperty:forKey:inRequest:
在请求中存储自定义对象/ NSDictionary
,而不是任务,并且稍后使用以下方法检索信息:
id customObject = [NSURLProtocol propertyForKey:@"yourkey" inRequest:sessionTask.originalRequest];
您必须在您调用自定义方法的位置导入自定义类别
#import "NSURLSession+test.h"