0

Я выполняю проверку имени пользователя и пароля, пинговая сервер для файла JSON, а затем проверяя его на пару. Мой userDictionary не заполняется к тому времени, когда я его проверю. Я предполагаю, что это потому, что NSURLSession является асинхронным, и он просто не возвращает данные к моменту, когда он мне понадобится. В моей ServerCommunicationModel, у меня есть:NSDictionary не заполняется во времени

- (void)getUserDictionaryFromServer 
{ 
    NSString *userFileURLString = [NSString stringWithFormat:@"%@/userFile.json", REMOTE_PATH_TO_ROOT_APP_FOLDER]; 
    NSURL *userFileURL  = [NSURL URLWithString:userFileURLString]; 

    NSURLSessionDataTask *userFileTask = [self.session dataTaskWithURL:userFileURL 
                completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) 
                { 
                 NSDictionary *returnJSON = [NSJSONSerialization JSONObjectWithData:data 
                                options:0 
                                 error:nil]; 
                 self.userDictionary = [returnJSON objectForKey:@"users"]; 
                }]; 

    [userFileTask resume]; 
} 

Затем в контроллере представления:

- (IBAction)submitButtonPressed:(UIButton *)sender 
{ 
    _usernameEntered = self.usernameTextField.text; 
    _passwordEntered = self.passwordTextField.text; 

    // Make sure the user put something in for a username and password 
    if ([_usernameEntered isEqualToString:@""] || [_passwordEntered isEqualToString:@""]) 
    { 
     [self showAlertViewWithText:@"" :@"Please enter a username and password" :@"OK"]; 
    } 

    // Stow a spinner while checking credentials 
    [MBProgressHUD showHUDAddedTo:self.view animated:YES]; 
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 0.01 * NSEC_PER_SEC); 
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void) 
    { 
     // Get the user file from the server 
     WAServerCommunicationModel *server = [WAServerCommunicationModel sharedInstance]; 
     [server getUserDictionaryFromServer]; 
     self.users = [server userDictionary]; 

     if ([self goodUser]) 
     { 
      [self performSegueWithIdentifier:@"loginOK" sender:self]; 

     } else 
     { 
      [self showAlertViewWithText:@"" :@"Invalid Username or Password" :@"Try Again"]; 
     } 

     [MBProgressHUD hideHUDForView:self.view animated:YES]; 
    }); 
} 

ответ

3

Вы можете изменить getUserDictionaryFromServer метод и добавить параметры успеха/неуспеха, как это:

- (void)getUserDictionaryFromServerWithSuccess:(void (^)(NSDictionary * userDictionary))success 
             failure:(void (^)(NSError *error))failure; 

Тогда, вызывать соответствующий обратный вызов (успех/отказ) при получении ответа от сервера.

После этого, если вы вызываете [server userDictionary]; в блок успеха, он всегда будет заполняться правильно.

Редактировать: NSURLSession предоставляет API с завершениемHandler, который может быть полезен. Вы можете использовать его вместо делегирования: https://developer.apple.com/library/ios/documentation/Foundation/Reference/NSURLSession_class/index.html#//apple_ref/occ/instm/NSURLSession/dataTaskWithRequest:completionHandler:

- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request 
          completionHandler:(void (^)(NSData *data, 
                NSURLResponse *response, 
                NSError *error))completionHandler 
+0

Я отредактировал его, чтобы включить обработчик завершения (и изменил вопрос). У меня все еще есть проблема с тем, что он не был заполнен в первый раз, когда я нажимаю кнопку отправки. Он заполняется, если я снова нажимаю кнопку отправки. –

+0

@WillLuce Я не вижу, что вы добавили блоки успеха/отказа в метод getUserDictionaryFromServer, как я уже упоминал. После их добавления в вашем блоке finallyHandler вы можете вызвать блок успеха, если ошибка равна нулю. – pshah