2017-02-23 21 views
1

私のアプリのある時点で、ユーザーはムービー名を提供します。コントローラーは映画の詳細情報をOMDBから取得して保存します。 JSONをURLから辞書に変換する際に問題が発生します。ここに私のコードです:私はStackOverflowの上で見つかったURLSession部の多くのバリエーションを試してみましたスウィフト3の辞書にJSONを取得する構文解析

@IBAction func addMovieButtonPressed(_ sender: Any) { 
    // get title from the text field and prepare it for insertion into the url 
    let movieTitle = movieTitleField.text!.replacingOccurrences(of: " ", with: "+") 
    // get data for the movie the user named 
    let movieData = getMovieData(movieTitle: movieTitle) 
    // debug print statement 
    print(movieData) 
    // reset text field for possible new entry 
    movieTitleField.text = "" 
} 

// function that retrieves the info about the movie and converts it to a dictionary 
private func getMovieData(movieTitle: String) -> [String: Any] { 

    // declare a dictionary for the parsed JSON to go in 
    var movieData = [String: Any]() 

    // prepare the url in proper type 
    let url = URL(string: "http://www.omdbapi.com/?t=\(movieTitle)") 

    // get the JSON from OMDB, parse it and store it into movieData 
    URLSession.shared.dataTask(with: url!, completionHandler: {(data, response, error) in 
     guard let data = data, error == nil else { return } 
     do { 
      movieData = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [String: Any] 
     } catch let error as NSError { 
      print(error) 
     } 
    }).resume() 

    // return the data 
    return movieData 
} 

と私は、データが正常に取得されていることを知っている:
screenshot

私はどのように知りませんが適切にそれを取得し、私はその後、私のアプリの残りの部分で使用することができます辞書に変換します。 IBAction関数のprintステートメントは、常に空の辞書を返します。

私は間違っていますか?

+0

http://stackoverflow.com/q/40810108/2976878の可能な重複を - のhttp:// http://tackoverflow.com/q/27081062/2976878 - http://stackoverflow.com/q/31264172/2976878 - http://stackoverflow.com/q/25203556/ 2976878 – Hamish

答えて

2

完了ブロックと非同期関数を調べます。 getMovieDataは、データ・タスクの完了ハンドラが呼び出される前に戻っています。

あなたの機能は、代わりに返すのでは、渡された完成ブロックを呼び出しますし、に変更する必要があります。

private func getMovieData(movieTitle: String, completion: @escaping ([String:Any]) -> Void) { 

    // declare a dictionary for the parsed JSON to go in 
    var movieData = [String: Any]() 

    // prepare the url in proper type 
    let url = URL(string: "http://www.omdbapi.com/?t=\(movieTitle)") 

    // get the JSON from OMDB, parse it and store it into movieData 
    URLSession.shared.dataTask(with: url!, completionHandler: {(data, response, error) in 
     guard let data = data, error == nil else { return } 
     do { 
      movieData = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [String: Any] 
      completion(movieData) 
     } catch let error as NSError { 
      print(error) 
     } 
    }).resume() 
} 
+1

ああ!今、私は分かる。これは私が自分自身を考えなかった方向です。私は、非同期関数がどのように動作するかを調べ、完了時に呼び出される関数を書き出す方法と、この非同期関数をどのように呼び出すかを考えます。ありがとうございました! – stfwn