2016-09-03 30 views
0

非同期に実行されるユーザーを登録したいと考えています。ただし、ユーザーが正常に作成されたときにのみプログラムを続行する必要があるため、呼び出し関数は同期して動作します。 現在の実装は次のようになります。同期呼び出し内での非同期タスクの実行

class SignUp: NSObject { 

    // ... 

    func signUpUser() throws -> Bool { 
     guard hasEmptyFields() else { 
      throw CustomErrorCodes.EmptyField 
     } 

     guard isValidEmail() else { 
      throw CustomErrorCodes.InvalidEmail 
     } 

     createUser({ (result) in 
      guard result else { 
       throw CustomErrorCodes.UserNameTaken 
      } 
      return true // Error: cannot throw.... 
     }) 
    } 


    func createUser(succeeded: (result: Bool) ->()) -> Void { 
     let newUser = User() 
     newUser.username = username! 
     newUser.password = password! 

     // User is created asynchronously 
     createUserInBackground(newUser, onCompletion: {(succeed, error) -> Void in 
      if (error != nil) { 
       // Show error alert 
      } else { 
       succeeded(result: succeed) 
      } 
     }) 

    } 

} 

とのViewControllerで次のようにサインアップが開始されます。createUserが投げる機能ではありませんので、

do { 
    try signup.signUpUser() 
} catch let error as CustomErrorCodes { 
    // Process error 
} 

しかし、これは動作しません。どうすればsignUpUser()が新しいユーザーが正常に作成された場合にのみtrueを返すことができますか?

答えて

1

あなたは言う:

とのViewControllerにサインアップは、次のように開始されます。

do { 
    try signup.signUpUser() 
} catch let error as CustomErrorCodes { 
    // Process error 
} 

ないが。それは非同期の仕組みではありません。全体のアイデアは、あなたがを待たずにです。あなたが待っているなら、非同期ではありません。それはあなたがブロックしていることを意味し、それはあなたがしてはいけないことです。

代わりに、というように、という名前を付けて、非同期処理の最後に配置してください。それが成功したかどうか聞いてみましょう。ダウンロードタスクのデリゲートが構成されているかを見てください:

https://developer.apple.com/library/ios/documentation/Foundation/Reference/NSURLSessionDownloadTask_class/

ダウンロードタスクは、それは我々が正常に完了したかどうか知っているように、バックデリゲートを呼び出します。それはあなたの非同期タスクに持たせたい関係です。そのデリゲートのようになりたい。

+0

これは良い提案です。私はデリゲートを使うとき、それは魅力のように機能します!しかし、どのような状況では、クロージャを使用するほうが良いでしょう(例えばsignUpUserへの呼び出しで)。これはタスクを非同期にするためです。 – Taco

+0

コールバック関数を渡す利点は、コールバック関数を事前に知っていない場合です。 – matt

+0

それは理にかなっています! – Taco

0

あなたの思考を調整する必要があります。非同期イベントを待つ必要がある同期メソッドを記述するのではなく、完了クロージャをとるメソッドを記述します。このメソッドはすぐに戻りますが、非同期プロセスが完了すると、ワイルドカードは完了クロージャを呼び出します。このようなメソッドを呼び出すと、ジョブが完了すると呼び出される不完全閉包でコードが渡されます。

関連する問題