2014-10-14 2 views
0

В основном я получил 2 NSURLConnections. Первый получает токен от моего API, а второй получает некоторые события из API, но для этого нужен токен. В настоящее время я изучаю объекты C/Ios, поэтому это не настоящее приложение. То, что я пытаюсь сделать, состоит в том, чтобы различать два соединения по моему свойству current_connection.Несколько NSURLConnection в строке

1) Мой первый вопрос: есть ли лучший способ сделать это?

2) Второй вопрос: безопасно ли сделать 2 таких соединения? Поскольку это должно произойти в этом порядке, я не знаю, будет ли IOS всегда это делать, если мой код будет таким. Например, если первые запросы занимают очень много времени, он уже запускает второй? Это было бы проблемой без наличия токена.

3) Я прочитал около https://github.com/AFNetworking/AFNetworking - должен ли я использовать его?

Мой код:

HomeViewController.h

#import <UIKit/UIKit.h> 

@interface HomeViewController : UIViewController 
    @property (nonatomic, strong) NSString* current_connection; 
@end 

Мой HomeViewController.m

#import "HomeViewController.h" 

@interface HomeViewController() 

@end 

@implementation HomeViewController 

@synthesize current_connection; 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    //get user token 
    NSString *post = [NSString stringWithFormat:@"&email=%@&password=%@",[[NSUserDefaults standardUserDefaults] objectForKey:@"email"], [[NSUserDefaults standardUserDefaults] objectForKey:@"password"]]; 
    NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]; 
    NSString *postLength = [NSString stringWithFormat:@"%lu",(unsigned long)[postData length]]; 
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init]; 
    [request setURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://localhost:3000/api/v1/sessions"]]]; 
    [request setHTTPMethod:@"POST"]; 
    [request setValue:postLength forHTTPHeaderField:@"Content-Length"]; 
    [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Current-Type"]; 
    [request setHTTPBody:postData]; 
    current_connection = @"token"; 
    NSURLConnection *conn = [[NSURLConnection alloc]initWithRequest:request delegate:self]; 

    //load events 
    NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; 
    NSString *url =[NSString stringWithFormat:@"http://localhost:3000/api/v1/events/start_events?user_email=%@&user_token=%@",[[NSUserDefaults standardUserDefaults] objectForKey:@"email"], [[NSUserDefaults standardUserDefaults] objectForKey:@"token"]]; 
    NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]]; 
    [req setHTTPMethod:@"GET"]; 
    current_connection = @"event"; 
    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:req delegate:self]; 
} 

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData*)data { 
    NSError *error; 
    NSMutableDictionary *cdata = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers|NSJSONReadingMutableLeaves error:&error]; 

    if(error) 
    { 
     NSLog(@"%@", [error localizedDescription]); 
    } 
    else { 
     if ([current_connection isEqual: @"token"]) { 
      NSString *token = cdata[@"token"]; 
      NSLog(@"%@", token); 
      //save token to user defaults 
      NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; 
      [defaults setObject:token forKey:@"token"]; 
      [defaults synchronize]; 
     } 
     else { 
      //display events 
      NSLog(@"%@", cdata[@"events"]); 
     } 
    } 
} 
@end 

ответ

1

В ответ на вопросы:

  1. Да, там лучше способы сделай это. Есть целый ряд вопросов:

    • Ваши два запросы на соединение будет вызывать один и тот же объект делегата, и они будут шаг друг с другом, если вы не очень осторожны.

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

      Прямо сейчас ваши два запроса эффективно работают одновременно (у вас нет официальной гарантии того, что будет выполнено в первую очередь). Вы хотите изменить это так, чтобы они выполнялись последовательно.

    • Вы обрабатываете ответы в диапазоне didReceiveData. Это опасно, потому что иногда для тела ответа требуется более одного вызова didReceiveData. Обычно вы (a) создаете объект NSMutableData перед началом запроса; (b) didReceiveData просто добавляет полученные данные к этому NSMutableData; и (c) только в connectionDidFinishLoading вы бы попытались использовать весь NSMutableData и обработать это для ответа веб-службы.

    Нижняя линия, это на основе делегата реализации имеет ряд проблем, и я предлагаю использовать sendAsynchronousRequest (хорошую реализацию на основе блока, который получает вас из этих сорняков) или AFNetworking (хорошее обертыванием делегирование на основе объектов NSOperation). Вы можете исправить эту реализацию на основе делегата, но было бы проще использовать один из вышеупомянутых.

  2. Нет, это не разумно использовать один и тот же объект-делегат для выдачи двух одновременных запросов.Теперь, оказывается, вы, вероятно, не хотите, чтобы они были параллельными, так или иначе, но в качестве общего принципа проектирования жизнь проще, если у вас есть другой объект-делегат для каждого запроса NSURLConnection.

  3. Да, AFNetworking, вероятно, стоит попробовать. Это не идеально, но это избавляет вас от сорняков программирования NSURLConnectionDataDelegate. Если вам не нужно полное богатство AFNetworking, вы также можете запросить простые запросы с помощью метода класса NSURLConnectionsendAsynchronousRequest.

1

его лучше использовать + (void)sendAsynchronousRequest:(NSURLRequest*) request queue:(NSOperationQueue*) queue completionHandler:(void (^)(NSURLResponse* response, NSData* data, NSError* connectionError)) handler NS_AVAILABLE(10_7, 5_0); вместо использования делегатов.

Вы можете создать столько же соединения, сколько хотите, нет проблем.

AFNetworking - замечательная библиотека, которая поможет вам сделать так много вещей, таких как проверка доступности сети и загрузка материалов асинхронно. В зависимости от вашего использования вы можете решить. Если в вашем приложении так много сетевых действий, и вам нужно обрабатывать различные условия ошибки, лучше пойти на AFNetwork.

Смежные вопросы