iOS: NSURLSession category methods not being found at runtime

匿名 (未验证) 提交于 2019-12-03 01:12:01

问题:

I wanted to create a category on NSURLSession. The app compiles ok, but when I attempt to call the category methods I get

-[__NSCFURLSession doSomething]: unrecognized selector sent to instance 0xbf6b0f0 :0: error: -[NSURLSession_UPnPTests testCategory] : -[__NSCFURLSession doSomething]: unrecognized selector sent to instance 0xbf6b0f0 

Very strange, here is a test class I built to show the issue. The category on the NSString works fine, but the category on NSURLSession fails to find the method at runtime. I suspect this is something internal.

Opinions please :-)

#import   @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 

回答1:

I've had similar results with backgrounded NSURLSessionUploadTasks, which get deserialized as __NSCFURLSessionUploadTasks during the -URLSession:task:didCompleteWithError: delegate callback.

If I were you, I'd give up on that approach, and use composition (i.e. make the NSURLSession an ivar in another object). If you need to store some info with the NSURLSession, you could stuff a JSON-encoded dictionary into the .sessionDescription.

Here's the code that I used to do that for a task:



回答2:

Here is an alternative solution if you really want to add category to NSURLSession. I found this solution from BETURLSession. Of course, you have to be really careful about the name to avoid name conflicting.

Code for header

#import   @interface NSURLSession (YTelemetry)  -(void) hello; @end 

Code for implementation

#import "NSURLSession+YTelemetry.h"  @implementation NSObject (YTelemetry)  -(void) hello {     NSLog(@"hello world");  } @end 

Now in the code, I can

NSURLSession *session = [NSURLSession sharedSession];  [session hello]; 


回答3:

I tried to do the same as @clay-bridges (i.e. storing a userInfo NSDictionary for each task), and it works great when using a NSURLSession with a session configuration different from background. If you use a NSURLSession with a background configuration, and your app is terminated or crashes, the upload/download continues in the background, managed by the OS. When the upload/download finishes, if I try to retrieve the userInfo NSDictionary previously stored, I get nothing. My solution is to store that custom object/NSDictionary in the request, not the task, using NSURLProtocol: , and later on, retrieve the information using:

id customObject = [NSURLProtocol propertyForKey:@"yourkey" inRequest:sessionTask.originalRequest];



回答4:

you must import the your custom category where you call the custom methods

#import "NSURLSession+test.h" 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!