一旦数据被提取就移动到rootViewController

问题描述:

我是iOS中的新手 - Objective C,我试图实现登录功能。我的故事板图如下所示:一旦数据被提取就移动到rootViewController

enter image description here

所以,当有人点击帐户选项,进入个人资料视图控制器和viewWillAppear方法检查是否有用户数据。如果不是,它会执行到登录视图控制器的继续。

当用户点击登录按钮并且api调用成功时,我想返回到配置文件视图控制器。事情是,虽然我设法获取数据,但它不会让我回到配置文件视图控制器。

// code that creates the request and adds POST data and headers is not added to keep code sample to minimum 


    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; 
    NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:nil delegateQueue:nil]; 

    // execute data task 

    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { 

     NSDictionary *responseData = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; 
     if (responseData != nil) { 
      if ([[responseData valueForKey:@"status"] isEqualToString:@"OK"]) { 
       //delegate to pass the user data to Profile view controller 
       [self.delegate passUserDetails:[responseData objectForKey:@"user"]]; 
       [self.navigationController popToRootViewControllerAnimated:YES]; 

      } else if ([[responseData valueForKey:@"status"] isEqualToString:@"ERROR"]) { 
       NSLog(@"%@", [responseData valueForKey:@"error"]); 
      } 
     } else { 
      NSLog(@"Something went wrong, please try again"); 
     } 

    }]; 

    [dataTask resume]; 

我得到的问题是我的控制台上是

This application is modifying the autolayout engine from a background thread, which can lead to engine corruption and weird crashes.

我已经在先前的文章,我可以使用dispatch_async作为一种可能的解决问题的办法阅读,但我不明白确切地说。如果这是正确的,我是否需要将它用作我的completionHandler的包装?有什么我做错了(可能)?有没有其他方法来实现我的想法?

NSURLSession dataTaskWithRequest...调用上的completionHandler在后台线程上运行。大多数UIKit调用需要从主线程中完成。

括在这些电话:您的completionHandler内

dispatch_async(dispatch_get_main_queue(), ^{ 
// insert your code here 
}); 

你的情况:

NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { 

     NSDictionary *responseData = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; 
     if (responseData != nil) { 
      if ([[responseData valueForKey:@"status"] isEqualToString:@"OK"]) { 
       //delegate to pass the user data to Profile view controller 
       [self.delegate passUserDetails:[responseData objectForKey:@"user"]]; 
       dispatch_async(dispatch_get_main_queue(), ^{ 
        [self.navigationController popToRootViewControllerAnimated:YES]; 
       }; 

      } else if ([[responseData valueForKey:@"status"] isEqualToString:@"ERROR"]) { 
       NSLog(@"%@", [responseData valueForKey:@"error"]); 
      } 
     } else { 
      NSLog(@"Something went wrong, please try again"); 
     } 

    }]; 

如果passUserDetails使得该更新UI的任何电话,你需要将它包括在内。

+0

感谢您的澄清。我在'dispatch_async(dispatch_get_main_queue(),^ {});'内部封装了'NSURLSessionDataTask * dataTask',但不幸的是我仍然得到相同的错误。有任何想法吗? – kidA

+0

不,您需要在completionHandler内的'dispatch_async'调用中包装与UI相关的代码。 – jcaron

+0

更新的答案更加明确。 – jcaron

我认为你应该简单地呈现登录视图控制器的模态,并在登录成功后,你可以关闭登录视图控制器.....因为模式演示文稿是用于从用户的grabbibg短dat .so呈现登录控制器模态最好的实践。

如果你想返回到根视图控制器,那么你可能会使用下面的代码...我从我的手机回答,所以输入句子Ho避免命名约定错误。 [self.navigationController popTorootviewController];