2017-01-18 19 views
-1

ネストされた関数の内部から関数の値を返そうとしています。私はなぜそれが動作しないのか理解していますが、私はちょうど私の問題のタイプの回避策を知る必要があります。ネストした関数の関数の戻り値(Swift 3 | Xcode)

私のコードでは、Firebaseデータベース内に人が既に作成されているかどうかを確認しています。したがって、usersRef関数の内部で、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(...)機能その呼び出しに同期してクロージャを実行します。 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 
} 

:それは本当だ場合

は、次のことを試すことができます。

+0

残念ながら、それは真実ではありません、 'observeSingleEvent'は非同期に働くので、関数は常にfalseを返します。 – vadian

+0

他の選択肢はありません。 'Bool'を返すのではなく、他の人が提案したように完了の終了が必要です。 –

+1

あなたの提案をありがとう、うん、それは非同期だと述べたように、私はクロージャを追加することによってそれを働かせた。入力いただきありがとうございます! :) –

0

もう一つの方法は、デリゲートのプロトコルを作成し、クロージャ内でご提案のための