1

I have a method, the method have return the nsdata value, but I don't known how to get the return value from NSURLSessionDataTask block. and how to call the getDownloadFileData methods.Code for task is :-

caller:

 NSData *getFileDataResult = [self getDownloadFileData:pathString];

method:

 - (NSData*) getDownloadFileData : (NSString*) filePath {

  NSURLSessionDataTask *downloadFile = [[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:filePath] completionHandler:^(NSData *fileData, NSURLResponse *response, NSError *error){
// .....
//  fileData should return out.

  [downloadFile resume];
  });
  // I want to return the fileData after download completion.
  // how to return?
 }

Have anyone can give me a hand?

Thank you very much.

Chanchal Warde
  • 983
  • 5
  • 17
SYUN
  • 11
  • 2
  • you can use completion blocks, have a look at http://stackoverflow.com/questions/21436831/how-to-write-an-objective-c-completion-block – Ravi Feb 22 '17 at 07:01

2 Answers2

3

Please check my answer, I hope this helpful

- (NSData *)getDownloadFileData:(NSString *)filePath {
    __block NSData *responseData = nil;

    dispatch_semaphore_t sema = dispatch_semaphore_create(0);
    NSURLSessionDataTask *downloadFile = [[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:filePath] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        responseData = data;
        dispatch_semaphore_signal(sema);
    }];
    [downloadFile resume];

    dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);

    return responseData;
}

- (void)whereToCall {
    // Because to prevent the semaphore blocks main thread
    dispatch_queue_t myQueue = dispatch_queue_create("com.abc", 0);
    dispatch_async(myQueue, ^{
        NSData *data = [self getDownloadFileData:@"urlString"];
    });
}

- (void)betterGetDownloadFileData:(NSString *)filePath completion:(void (^)(NSData * __nullable data))completion {
    NSURLSessionDataTask *downloadFile = [[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:filePath] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (completion) {
            completion(data);
        }
    }];
    [downloadFile resume];
}

I recommend you should design your code as my suggestion that using block instead.

HSG
  • 1,224
  • 11
  • 17
0

First of all you have put resume method at wrong place. It should be like this:

 - (NSData*) getDownloadFileData : (NSString*) filePath {
    NSURLSessionDataTask *downloadFile = [[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:filePath] completionHandler:^(NSData *fileData, NSURLResponse *response, NSError *error){
    // .....
    //  fileData should return out.


      });
[downloadFile resume];//NOTICE THE PLACEMENT HERE
      // I want to return the fileData after download completion.
      // how to return?
     }

Second thing is , you can simply create a NSData variable and assign it the value in completion block rather than passing data back.

OR

Simply do like this in completion block

if(fileData){
    return fileData;
}
Vishal Sonawane
  • 2,637
  • 2
  • 16
  • 21