2016-11-15 1 views
1

Я стартер в Цель - C, у меня есть методКак изменить sendSynchronousRequest: URLRequest потому осуждается

- (void)getAltitudeFromElevationFromAlt:(float)latitude Long:(float)longitude{ 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
     NSString *apiKey = @"IzaSyA5CDPUYC7GY5PzJdu_K4ouRy55gm3R5BO4"; 
     NSString *address = [NSString stringWithFormat:@"https://maps.googleapis.com/maps/api/elevation/json?locations=%f,%f&key=%@", latitude, longitude, apiKey]; 
     // Send a synchronous request 

     NSURLRequest * urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:address]]; 
     NSURLResponse * response = nil; 
     NSError * error = nil; 
     NSData * data = [NSURLConnection sendSynchronousRequest:urlRequest 
               returningResponse:&response 
                  error:&error]; 

     NSString *str = @"No Data"; 
     if (error == nil) 
     { 
      NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error]; 
      str = [NSString stringWithFormat:@"%@", dictionary[@"results"][0][@"elevation"]]; 
      // NSLog(@"text = %@", dictionary[@"results"][0][@"elevation"]); 
      NSLog(@"str = %@", str); 
      dispatch_async(dispatch_get_main_queue(), ^{ 
       _altitudeMeterLabel.text = str; 
      }); 
     } 
    }); 
} 

пожалуйста, помогите изменить эту последовательность

NSData * data = [NSURLConnection sendSynchronousRequest:urlRequest 
              returningResponse:&response 
                 error:&error]; 

ответ

2

NSURLSession Использование и асинхронный запрос:

- (void)getAltitudeFromElevationFromAlt:(float)latitude Long:(float)longitude { 

    NSString *apiKey = @"IzaSyA5CDPUYC7GY5PzJdu_K4ouRy55gm3R5BO4"; 
    NSString *address = [NSString stringWithFormat:@"https://maps.googleapis.com/maps/api/elevation/json?locations=%f,%f&key=%@", latitude, longitude, apiKey]; 
    // Send an ASYNCHRONOUS request 

    NSURLRequest * urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:address]]; 
    [[[NSURLSession sharedSession] dataTaskWithRequest:urlRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 
     NSString *str = @"No Data"; 
     if (error) { 
     NSLog(@"%@", error); 
     } else { 
     NSError * jsonError = nil; 
     NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&jsonError]; 
     if (jsonError) { 
      NSLog(@"%@", jsonError); 
     } else { 
      str = [NSString stringWithFormat:@"%@", dictionary[@"results"][0][@"elevation"]]; 
      // NSLog(@"text = %@", dictionary[@"results"][0][@"elevation"]); 
      NSLog(@"str = %@", str); 
     } 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      _altitudeMeterLabel.text = str; 
     }); 
     } 
    }] resume]; 
} 

Примечание:

Глобальный блок dispatch_async не требуется, так как задача данных отправляется в фоновый поток в любом случае.

+0

спасибо всем за помощь! –

0

Использование NSURLSession с dataTaskWithRequest

- (void)getAltitudeFromElevationFromAlt:(float)latitude Long:(float)longitude 
{ 
    NSString *apiKey = @"IzaSyA5CDPUYC7GY5PzJdu_K4ouRy55gm3R5BO4"; 
    NSString *address = [NSString stringWithFormat:@"https://maps.googleapis.com/maps/api/elevation/json?locations=%f,%f&key=%@", latitude, longitude, apiKey]; 

    NSURLRequest * request = [NSURLRequest requestWithURL:[NSURL URLWithString:address]]; 
    NSURLResponse * response = nil; 
    NSString *str = @"No Data"; 

    NSURLSession *session = [NSURLSession sharedSession]; 
    NSURLSessionDataTask *task = [session dataTaskWithRequest:request 
             completionHandler: 
    ^(NSData *data, NSURLResponse *response, NSError *error) { 
    if (error == nil) 
    { 
     NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error]; 
     str = [NSString stringWithFormat:@"%@", dictionary[@"results"][0][@"elevation"]]; 
     // NSLog(@"text = %@", dictionary[@"results"][0][@"elevation"]); 
     NSLog(@"str = %@", str); 
     dispatch_async(dispatch_get_main_queue(), ^{ 
      _altitudeMeterLabel.text = str; 
     }); 
    } 
    }]; 

    [task resume];  
}  
+0

Да, используйте 'dataTaskWithRequest'. Но у вас все равно есть 'sendSynchronousRequest' там! Весь этот код следует удалить. Кроме того, отправка в глобальную очередь не требуется. – Rob

0

Пожалуйста, попробуйте следующий код

- (void)getAltitudeFromElevationFromAlt:(float)latitude Long:(float)longitude{ 
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
    NSString *apiKey = @"IzaSyA5CDPUYC7GY5PzJdu_K4ouRy55gm3R5BO4"; 
    NSString *address = [NSString stringWithFormat:@"https://maps.googleapis.com/maps/api/elevation/json?locations=%f,%f&key=%@", latitude, longitude, apiKey]; 
    // Send a synchronous request 

    NSURLSession *session = [NSURLSession sharedSession]; 
    [[session dataTaskWithURL:[NSURL URLWithString:address] 
      completionHandler:^(NSData *data, 
           NSURLResponse *response, 
           NSError *error) { 
       NSString *str = @"No Data"; 
       if (error == nil) 
       { 
        NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error]; 
        str = [NSString stringWithFormat:@"%@", dictionary[@"results"][0][@"elevation"]]; 
        // NSLog(@"text = %@", dictionary[@"results"][0][@"elevation"]); 
        NSLog(@"str = %@", str); 
        dispatch_async(dispatch_get_main_queue(), ^{ 
         _altitudeMeterLabel.text = str; 
        }); 
       } 

      }] resume]; 
    }); 

}

+0

Да, это во многом право, хотя внешняя отправка в глобальную очередь больше не нужна. – Rob

0

Синхронные методы являются устаревшими с прошивкой 9, потому что он блокирует основной поток для то время. Поэтому не рекомендуется отправлять эту операцию синхронно.

Если вам действительно нужно, вы можете создать категорию NSUrlSession для синхронного выполнения запроса.

#import "NSURLSession+Sync.h" 

@implementation NSURLSession (Sync) 

+ (NSData *)sendSynchronousRequest:(NSURLRequest *)request 
       returningResponse:(__autoreleasing NSURLResponse **)responsePtr 
          error:(__autoreleasing NSError **)errorPtr { 
    dispatch_semaphore_t sem; 
    __block NSData *  result; 

    result = nil; 

    sem = dispatch_semaphore_create(0); 

    [[[NSURLSession sharedSession] dataTaskWithRequest:request 
            completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 
             if (errorPtr != NULL) { 
              *errorPtr = error; 
             } 
             if (responsePtr != NULL) { 
              *responsePtr = response; 
             } 
             if (error == nil) { 
              result = data; 
             } 
             dispatch_semaphore_signal(sem); 
            }] resume]; 

    dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER); 

    return result; 
} 
@end 

и использовать в коде, как следующее:

NSData * data = [NSURLSession sendSynchronousRequest:urlRequest returningResponse:&response error:&error]; 
+0

Семафоры - плохая привычка программирования, потому что они также блокируют поток. Нет необходимости вообще выполнять эту задачу синхронно. – vadian

+0

@iOS_devloper - он отправлял это в глобальную очередь (так что блокирующий синхронный запрос не блокировал основной поток, предположительно). Вместо того, чтобы использовать асинхронный метод, используя семафор, чтобы сделать его синхронным, а затем отправив его в глобальную очередь, чтобы сделать его асинхронным снова, он должен просто выполнить стандартный асинхронный шаблон и сделать с ним. – Rob

+0

Согласитесь, и вот почему я заявил, что не рекомендуется выполнять эту задачу синхронно. Но если вам это нужно, это так. – Darshana