Friends, tell me who knows - There is a custom class method that returns the NSData variable - responceData. It is initialized with a response from the server in the block code. The problem is that my method executes return and exits the method earlier than it enters the block with responds, thus returning nil.

What are the ways to solve this situation?

-(NSData *) getDataFromServer { __block NSData *responceData = nil; NSURLSessionConfiguration *sessionConfiguration= [NSURLSessionConfiguration defaultSessionConfiguration]; NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration delegate:self delegateQueue:[NSOperationQueue mainQueue]]; NSURL *url = [NSURL URLWithString:self.urlForResource]; NSURLSessionDataTask *dataTask = [session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { responceData = [[NSData alloc] initWithData:data]; }]; [dataTask resume]; return responceData; } 
  • one
    I do not even know which side to begin to explain. In short, with asynchronous execution, return does not work, as you already said, since your data from the server had not yet arrived at the time of the return. You need in your completionHandler to write a code that will send your responseData where you need to be - Max Mikheyenko
  • OK thanks. And so, for the general development - to dig in the direction of NSThread ?? is it possible to somehow point out the synchronous execution - as I understand it - until it is executed - the following code is not executed - MxTM

1 answer 1

I will support the answer from @ Max in the comments. I recommend that you remake asynchronous execution of c completionBlock . Like that:

 - (NSData *)getDataFromServer:(void(^)(NSData *))completion { //.. NSURLSessionDataTask *dataTask = [session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { // handle error completion(data); }]; [dataTask resume]; //.. } 

If you need to execute the code synchronously, you can do it in two ways. 1) Without using NSURLSession :

 NSData *data = [NSData dataWithContentsOfURL:url] 

2) Wait for the execution of the synchronous code. For example, using dispatch_group

 - (NSData *)getDataFromServer { __block NSData *responseData = nil; // модификатор __block, позволяет менять указатель внутри блока кода dispatch_group_t group = dispatch_group_create(); dispatch_group_enter(group); // добавляем в группу задачу NSURLSessionDataTask *dataTask = [session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { // handle error responseData = data; dispatch_group_leave(group); // наша задача завершена }]; dispatch_group_wait(group, DISPATCH_TIME_FOREVER); return responseData; } 
  • very interesting. Version with completion - MxTM
  • Option with completion - from my method I call the block in which I pass the response with NSData. How can this response be returned from the getDataFromServer method and bypass the time with returning nil ?? - MxTM
  • And the variant with NSData * data = [NSData dataWithContentsOfURL: url] is really a class. I do without NSURLSession at all. In this case, the code runs synchronously ?? What are the pitfalls of this method (compared to NSURLSession) ??? - MxTM
  • Interestingly, due to what is happening - 1. The response from the server takes the same time as in the case of NSData and NSURLSession. But in the case of NSData, the code is not executed until the answer has come, and in the NSURLSession - on the contrary? - MxTM
  • one
    dataWithContentsOfURL blocks the current thread until we get a response from the server. This is the minus of this method. If the main thread is blocked, the iPhone will not respond to pressing. NSURLSession essentially does the same thing, but without blocking. As the download ends, the code from the completion block will be called. I recommend reading about asynchronous code execution, for example, here raywenderlich.com/4295/… - Gralex