ios target c: Как заставить NSURLSession возвращать Content-Length (заголовок http) с сервера

Я уже пытался
https://stackoverflow.com/questions/36581495/how-to-get-nsurlsession-to-return-content-lengthhttp-header-from-server-objec

- (long long) getContentLength
{
    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
    NSURLSession *session = [NSURLSession sessionWithConfiguration:config];

    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:url]];
    request.HTTPMethod = @"HEAD";
    [request addValue:@"identity" forHTTPHeaderField:@"Accept-Encoding"];

    NSURLSessionDownloadTask *uploadTask
    = [session downloadTaskWithRequest:request
                     completionHandler:^(NSURL *url,NSURLResponse *response,NSError *error) {
                         NSLog(@"handler size: %lld", response.expectedContentLength);
                       totalContentFileLength = [[NSNumber alloc] initWithFloat:response.expectedContentLength].longLongValue;

                     }];
    NSLog(@"content length=%lld", totalContentFileLength);
    [uploadTask resume];
    return totalContentFileLength;
}

Я всегда получаю 0 из возвращаемого значения.


person S. S    schedule 02.12.2016    source источник


Ответы (2)


Это потому, что вы возвращаете значение функции вне completion handler, поэтому ваша функция возвращает значение до того, как она получит ответ от сервера. Теперь вы не можете вернуть значение из completion handler. Итак, вам нужно создать метод, который имеет пользовательский параметр completion handler в качестве параметра, например,

 - (void) getContentLength : (void(^)(long long returnValue))completionHandler
 {


NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:config];

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:url]];
request.HTTPMethod = @"HEAD";
[request addValue:@"identity" forHTTPHeaderField:@"Accept-Encoding"];

NSURLSessionDownloadTask *uploadTask
= [session downloadTaskWithRequest:request
                 completionHandler:^(NSURL *url,NSURLResponse *response,NSError *error) {

                     NSLog(@"handler size: %lld", response.expectedContentLength);
                     totalContentFileLength = [[NSNumber alloc] initWithFloat:response.expectedContentLength].longLongValue;

                     completionHandler(totalContentFileLength);

                 }];
NSLog(@"content length=%lld", totalContentFileLength);
[uploadTask resume];

}

и вы можете вызвать этот метод, например,

   [self getContentLength:^(long long returnValue) {

    NSLog(@"your content length : %lld",returnValue);

}];
person Ketan Parmar    schedule 02.12.2016

для swift 3.0: (используя простую функцию старого стиля..)

func getContentLengthOf(urlString: String,
                        completionHandler: @escaping (Int64?) -> ()  ) {

    let url = URL(string: urlString)
    var request = URLRequest(url: url!)
    request.httpMethod = "HEAD"
    request.addValue( "identity", forHTTPHeaderField: "Accept-Encoding")

    let session = URLSession(configuration: URLSessionConfiguration.default)

    let task = session.dataTask(with: request, completionHandler: {(data, response, error) -> Void in
        if let response = response as? HTTPURLResponse , 200...299 ~= response.statusCode {
            let contentLength : Int64 = response.expectedContentLength
            completionHandler(contentLength)

        } else {
            completionHandler(nil)
        }
    })

    task.resume()
}

и позвоните так:

....
        let URLString = "https://lh4.googleusercontent.com/-KdgJnz1HIdQ/AAAAAAAAAAI/AAAAAAAAA8s/31PBnNCL-qs/s0-c-k-no-ns/photo.jpg"

        getContentLengthOf(urlString: URLString) { (contentLength: Int64?) in
            if let contentLength = contentLength {
                print("size is: \(contentLength)")
            }else{
                print("error getting contentLength")
            }
        }

в обратном вызове вы получите необязательный Int64.

person ingconti    schedule 06.01.2017