2015-09-06 3 views
1

Мне нужно «getUserInfo» для завершения, прежде чем выполнить следующий раздел кода (нажатие на раскадровку). В настоящее время «getUserInfo» все еще находится в процессе, когда выполняется нажатие на раскадровку. Как я могу выполнить их в порядке? Мне нужно сохранить эти 2 функции отдельно, поэтому размещение кода в обработчике завершения loginUser не является хорошим решением. Большое спасибо тем, кто умнее меня :)Выполнить быстрый код в порядке

func loginUser() { 
     PFUser.logInWithUsernameInBackground(txtEmailAddress.text, password:txtPassword.text) { 
      (user: PFUser?, error: NSError?) -> Void in 
      if user != nil { 

       // Successful login. 
       self.txtPassword.resignFirstResponder() 
       self.txtEmailAddress.resignFirstResponder() 

       getUserInfo() 

       // Push to Main.storyboard. 
       let storyboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle()) 
       let viewController: AnyObject = storyboard.instantiateInitialViewController() 
       self.presentViewController(viewController as! UIViewController, animated: true, completion: nil) 

      } else { 
       // The login failed. Display alert. 
       self.displayAlert("Error", message: "Login incorrect") 
      } 
     } 
} 

func getUserInfo() { 

    let currentUser = PFUser.currentUser() 
    let userQuery = PFQuery(className: "_User") 

    userQuery.whereKey("username", equalTo: PFUser.currentUser()!.username!) 

    userQuery.findObjectsInBackgroundWithBlock({ (results:[AnyObject]?, error:NSError?) -> Void in 
     if error == nil { 
      for result in results! { 
       userType = result["userType"] as! String 

       if userType == "admin" { 
        user = "AdminSetting" 
       } else { 
        user = "StandardSetting" 
       } 
      } 
     } 
    }) 

} 
+0

Не выполнять в фоновом режиме. –

+0

"поэтому размещение кода в обработчике завершения loginUser не является хорошим решением". Что это связано с тем, чтобы держать их в отдельных функциях. Храните их в отдельных функциях и вызывайте другую функцию в обработчике завершения. –

ответ

0

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

+0

Я не могу найти лучший способ сделать это. Когда пользователь входит в систему, мне нужно знать тип пользователя, которым они являются. Исходя из этого, я решаю, какие варианты их показывать. Я не знаю пользователя, пока они не войдут в систему, поэтому я не могу этого сделать раньше. Я новичок в этом, поэтому очень открыт для предложений. Конечно, цените свои мысли! – Robert

0

Вы также можете выполнить свой код раскадровки в getUserInfo() как блок/закрытие, переданное как параметр. Таким образом, вы можете убедиться, что он выполнен, когда асинхронный вызов в getUserInfo завершен

0

Что предлагает Shadowman, является правильным/самым изящным решением.

Вот пример:

func getUserInfo(completion: (results:[AnyObject]?, error:NSError?) -> Void) { 

    let currentUser = PFUser.currentUser() 
    let userQuery = PFQuery(className: "_User") 

    userQuery.whereKey("username", equalTo: PFUser.currentUser()!.username!) 

    userQuery.findObjectsInBackgroundWithBlock(completion) 

} 

Таким образом, вы получите обратно фактические результаты от вызова после того, как он закончил, удобно, а?

А вот как вы это называете:

self.getUserInfo { (results, error) -> Void in 

    // Here the results are already fetched, so proceed with your 
    // logic (show next controller or whatever...) 

    if error == nil { 
     for result in results! { 
      userType = result["userType"] as! String 

      if userType == "admin" { 
       user = "AdminSetting" 
      } else { 
       user = "StandardSetting" 
      } 
     } 
    } 

    // depending on whether this will still run in a background thread, you might have to dispatch this code to the main thread. 
    // you can check whether this code block is called on the main thread 
    // by checking if NSThread.isMainThread() returns true 
    // if not, you will need to use this dispatch block! 
    dispatch_async(dispatch_get_main_queue(), {() -> Void in 
     // only call UI code in main thread! 
     // MOVE TO NEXT controller in here! 
    }) 
} 
Смежные вопросы