在同步方法中使用NSURLSessionDataTask不会获取缩略图

时间:2019-08-19 20:49:02

标签: objective-c thumbnails nsurlsession nsurlsessiondatatask

我有一个继承的旧方法(responseForURL:error :),该方法写于15年。它使用一个URL并返回一个NSCachedURLResponse。该方法的工作方式是使用NSURLConnection进行Web服务调用。然后,它调用CFRunLoopRun()以便允许URL连接委托完成其数据的获取。一旦调用connectionDidFinishLoading:或connection:didFailWithError:委托方法,则将调用CFRunLoopStop(CFRunLoopGetCurrent)),从而允许responseForURL:error:方法继续运行并返回响应。换句话说,responseForURL:error:同步返回Web数据。该代码可以正常工作。

我使用NSURLSession更新了已弃用的NSURLConnect。此方法的功能与以前相同,但有一个例外:缩略图不再显示。

在调试前面的代码时,多次调用connection:didReceiveData :,直到完全下载了所有缩略图图像数据为止。 URLSession:dataTask:didReceiveData也被多次调用,像以前一样累积数据,但是缩略图为空白。我想了解的是为什么。

我不是使用CFRunLoopRun(),而是使用信号量来防止方法在检索到所有会话数据之前退出。

原始代码:

- (NSCachedURLResponse *)responseForURL:(NSURL*)url error:(NSError* __autoreleasing *)error {

    NSParameterAssert(url);  
    __block NSCachedURLResponse *responseToReturn = nil;

    dispatch_sync(_syncQueue, ^{
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:30];
        NSCachedURLResponse *cachedResponse = [self->_diskCache cachedResponseForRequest:request];

        if (cachedResponse) {
            NSHTTPURLResponse *actualResponse = (NSHTTPURLResponse*)[cachedResponse response];
            id etag = [[actualResponse allHeaderFields] objectForKey:@"Etag"];
            [request setValue:etag forHTTPHeaderField:@"If-None-Match"];
        }

        self->_response = nil;
        self->_error = nil;
        self->_responseData = [NSMutableData new];

        NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];
        [connection start];

        CFRunLoopRun();

        *error = self->_error;

        if (cachedResponse && ![self->_responseData length]) {
            responseToReturn = cachedResponse;
        } else {
            if (self->_response && self->_responseData) {
                responseToReturn = [[NSCachedURLResponse alloc] initWithResponse:self->_response data:self->_responseData];
                [self storeResponse:responseToReturn forRequest:request];
            }
        }
    });

    return responseToReturn;
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    _response = (NSHTTPURLResponse*)response;
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [_responseData appendData:data];
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    _error = error;
    CFRunLoopStop(CFRunLoopGetCurrent());
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    CFRunLoopStop(CFRunLoopGetCurrent());
}

新代码:

- (NSCachedURLResponse *)responseForURL:(NSURL*)url error:(NSError* __autoreleasing *)error {
    NSParameterAssert(url);
    __block NSCachedURLResponse *responseToReturn = nil;
    __weak typeof(self) weakSelf = self;

    dispatch_sync(_syncQueue, ^{
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:30];
        NSCachedURLResponse *cachedResponse = [weakSelf cachedResponseForRequest:request];

        if (cachedResponse) {
            NSHTTPURLResponse *actualResponse = (NSHTTPURLResponse *)[cachedResponse response];
            id etag = [[actualResponse allHeaderFields] objectForKey:URLCacheETag];

            [request setValue:etag forHTTPHeaderField:CCCURLCacheHTTPHeaderField];
        }

        weakSelf.semaphore = dispatch_semaphore_create(0);
        weakSelf.response = nil;
        weakSelf.responseData = [NSMutableData new];
        weakSelf.error = nil;

        NSURLSessionDataTask *dataTask = [weakSelf.session dataTaskWithRequest:request];
        [dataTask resume];

        dispatch_semaphore_wait(weakSelf.semaphore, DISPATCH_TIME_FOREVER);
        *error = weakSelf.error;

        if (cachedResponse && weakSelf.responseData.length == 0) {
            // Get cached response data.
            responseToReturn = cachedResponse;
        } else {
            if (weakSelf.response && weakSelf.responseData.length > 0) {
                // We got response data. Cache it!
                responseToReturn = [[NSCachedURLResponse alloc] initWithResponse:weakSelf.response data:weakSelf.responseData];
                [weakSelf storeResponse:responseToReturn forRequest:request];
            }
        }
    });

    return responseToReturn;
}

- (void)URLSession:(NSURLSession *)session dataTask:(nonnull NSURLSessionDataTask *)dataTask didReceiveResponse:(nonnull NSURLResponse *)response completionHandler:(nonnull void (^)(NSURLSessionResponseDisposition))completionHandler {
    self->_response = (NSHTTPURLResponse*)response;
    if (response) {
        completionHandler(NSURLSessionResponseAllow);
    } else {
        completionHandler(NSURLSessionResponseCancel);
    }
}

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
    [_responseData appendData:data];
}

- (void)URLSession:(NSURLSession *)session didBecomeInvalidWithError:(NSError *)error {
    _error = error;
    dispatch_semaphore_signal(_semaphore);
}

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
    _error = error;
    dispatch_semaphore_signal(_semaphore);
}

应提取返回的响应数据并将其转换为缩略图。相反,缩略图为空白。

0 个答案:

没有答案