2016-06-17 12 views
-1

私はRESTEngine.sharedEngine.registerUser関数を使ってサーバーからデータを取得するために以下の関数を使用しています。 "userCreationCall"はAPI呼び出しを行い、戻ってくるJSONを解析し、ユーザーを作成してそのユーザーを完了ブロックに渡します。完成ブロック内から変数を返すときのトラブル:

"makeUser"は、ユーザーのオブジェクトを返す別の関数にその中のユーザーを渡して、その完了ブロックを処理します。この関数は、自分のアプリケーション内の他の場所で使用するユーザーオブジェクトを返します。テスト目的のため

func userCreationCall(first: String, last: String, email: String, completionHandler: (User?, ErrorType?) ->()) { 
RESTEngine.sharedEngine.registerUser(email, firstName: first, lastName: last, age: 12, success: { response in 
    if let response = response, result = response["resource"], id = result[0]["_id"] {    
     let params: JSON = 
     ["name": "\(first) \(last)", 
      "id": id as! String, 
      "email": email, 
      "rating": 0.0, 
      "nuMatches": 0, 
      "nuItemsSold": 0, 
      "nuItemsBought": 0] 
     let user = User(json: params) 
     completionHandler(user, nil) 
    } 
    }, failure: { error in 
     completionHandler(nil, error) 
    }) 
} 

func makeUser(first: String, last: String, email: String) { 

    userCreationCall(first, last: last, email: email) { user, error in 
     guard error == nil else { 
      print("Error creating a user! : \(error)") 
      return 
     } 

     returnUser(user!) 
    } 
} 

func returnUser(user: User) -> User { 
    return user 
} 

I「がmakeUser」の終了ブロック内に渡されたユーザオブジェクト割り当てられる「TESTUSER」の意図、のviewDidLoadに次の呼び出しを行う:ただし

override func viewDidLoad() { 
    super.viewDidLoad() 
    let testUser = makeUser("John", last: "Doe", email: "[email protected]") 
    print("\(testUser)") 
} 

を、場合I testUserを印刷すると、それはまだ空白になります(つまり、 "makeUser"の補完ブロック内でユーザーオブジェクトが割り当てられることはありません)。私のロジック/実装がどこに間違っているのか誰かが手掛かりを持っていますか?前もって感謝します!

+0

を必要とされていませんあなたが望む出力を返すのではなく、 – iphonic

+0

あなたは[その他の回答](http://stackoverflow.com/a/37887015/1271826)から 'makeUser'を受け取りましたが、非同期メソッドから値を返すことはできないという基本的な点を理解していないようです(そして 'getUser'は非同期メソッドになりました)。非同期メソッドを呼び出すときは、結果を返そうとせず、常に完了ハンドラパターンなどの非同期プログラミングパターンに従います。 – Rob

+0

あなたは "makeUser"の完了ブロック内にユーザーオブジェクトが割り当てられることはありません。いいえ、値を取得しますが、後で 'viewDidLoad'が既に完了した後です。 'viewDidLoad'ではなく、補完ブロックの中でのみ値を使うことができます。 – Rob

答えて

0

あなたはあまりにも何で `makeUser`に完了ハンドラを使用する必要がありますまた、例えばmakeUserで完了ブロック

func makeUser(first: String, last: String, email: String, completion:((User?) -> Void)) { 

    userCreationCall(first, last: last, email: email) { user, error in 
    guard error == nil else { 
     print("Error creating a user! : \(error)") 
     completion(nil) 
     return 
    } 

    completion(user) 
    } 
} 

override func viewDidLoad() { 
    super.viewDidLoad() 
    makeUser("John", last: "Doe", email: "[email protected]") { user in 
     if user != nil { 
      print("\(user!)") 
     } 
    } 
} 

を必要とする。しかし、余分な機能は、実際に

override func viewDidLoad() { 
    super.viewDidLoad() 

    userCreationCall("John", last: "Doe", email: "[email protected]") { user, error in 
     if error != nil { 
     print("Error creating a user! : \(error!)") 
     } else { 
     print("\(user!)") 
     // do something with the new created user 
     } 
    } 
} 
+0

私は、自分のアプリでローカルユーザー変数を作成する際にuserCreationCall(つまりユーザー)から取得した情報をどのように使用すればよいのでしょうか? 「userCreationCall」を呼び出す直前に「空の」初期化されていないユーザーを作成し、その完了ブロックでコールのデータを使用して「空の」ユーザーにプロパティを割り当てる必要がありますか? –

+0

正確には、データが非同期に取り出されるため、完了ブロックに値を割り当てる必要があります。 – vadian

+0

十分です。私はこれらのブロックに「ユーザーリターン」を組み込む方法を見つけようとしているので、これではまだ苦労しています。本質的には、私が起こそうとしていることは、フロントエンドの人が "makeUser"を呼び出して基本情報を渡し、完了を心配することなくサーバーからデータで取得したUserオブジェクトを取得できるようにすることですブロックまたはバックエンドの実装。これを実装する方法に関する提案はありますか? –

関連する問題