2017-01-18 4 views
-1

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

В моем коде я проверяю, был ли человек уже создан внутри моей базы данных Firebase. Таким образом, внутри функции usersRef вы увидите, что если значение return from firebase равно «nil», пользователь не был создан и наоборот.

Когда я говорю: return userBool это дает мне эту ошибку:

Unexpected non-void return value in void function 

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

func checkIfUserExists(userID : String) -> Bool { 
    var userBool = Bool() 
    var usersRef = FIRDatabase.database().reference() 
    usersRef.child("users").child(userID).observeSingleEvent(of: .value, with: { 
    snapshot in 
     if snapshot.value != nil { 
      userBool = true 
      return userBool 
     } 
     else { 
      userBool = false 
      return userBool 
     } 
    }) 
} 

UPDATE:

Благодаря вашим предложениям, я добавил к завершению, и она работала отлично. :)

func checkIfUserExists(userID : String, completion: @escaping (_ success: Bool) ->()){ 
    var userBool = Bool() 
    var usersRef = FIRDatabase.database().reference() 
    usersRef.child("users").child(userID).observeSingleEvent(of: .value, with:{ 
     snapshot in 
      if snapshot.value != nil { 
       print("userBool!", userBool) 
       userBool = true 
      } 
      else { 
       print("userBool2!", userBool) 
       userBool = false 
      } 
     completion(userBool) 
    }) 
} 

ответ

2

Там нет никакого способа вернуться из внешней функции внутри внутреннего. Единственный способ, которым я могу думать о том, с помощью обработчика завершения, который затем можно вызывать из вложенной функции, как так:

func checkIfUserExists(userID : String, completion: @escaping (_ userExists: Bool) -> Void) 
+0

Спасибо за предложение, я рассмотрю его. :) –

+0

Работал отлично! Благодаря! –

+0

Отлично! Я рад, что это помогло. :) –

1

Проблема в том, что вы находитесь в закрытии, что не ожидает возврата типа .. Как вы называете эту функцию?

Некоторые идеи: * Пропустите закрытие этой функции, которое затем вызывается, а не пытается вернуться.

  • Сохраните отображение результатов где-нибудь, обновите это из замыкания и всегда проверяйте на это сопоставление.

Кроме того, похоже, вместо

if snapshot.value != nil { 
     userBool = true 
     return userBool 
    } 
    else { 
     userBool = false 
     return userBool 
    } 

Вы можете просто сделать это:

guard snapshot = snapshot else { return } 
return snapshot.value 
+0

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

1

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

Если это правда, то вы можете попробовать следующее:

func checkIfUserExists(userID : String) -> Bool { 
    var userBool = false 
    var usersRef = FIRDatabase.database().reference() 
    usersRef.child("users").child(userID).observeSingleEvent(of: .value, with: { 
     userBool = $0.value != nil 
    }) 
    return userBool 
} 

Если замыкание observeSingleEvent(...) вызываются через некоторое время, возвращают результат вашего метода в затворе, как предложили Moritz, не в качестве возвращаемого значения ,

+0

К сожалению, это не так, 'observSingleEvent' работает асинхронно, поэтому функция всегда будет возвращать false. – vadian

+0

Тогда нет другого выбора. Вместо того, чтобы возвращать «Bool», должно быть завершение закрытия, как предполагали другие ребята. –

+1

Спасибо за ваше предложение и yep, так как указано, что он асинхронный, но я получил его, добавив закрытие. Спасибо за вход! :) –

0

Другой способ - создать делегатский протокол и называть его закрытием.

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