2017-01-17 7 views
0

GETリクエストをシリアル化してからムービーオブジェクトを作成し、そのムービーオブジェクトをムービーに表示するムービー配列に追加しようとしています。JSON項目を配列に追加しようとしましたが、動作しません。

私は新しいですし、今しばらくの間、この問題に苦労している:(

あなたが仕事self.movies?.append(movie)はずのを見れば?私は私が取得する最初の項目を取得しようとするときになどの任意の理由を参照してくださいいけません私は、アレイが埋めまだ....されていないいけない私が間違っているのかを知る意味範囲外の致命的なエラーインデックス:(

import UIKit 

class ViewController: UIViewController { 

var movies:[Movie]? = [] 

@IBOutlet weak var uiMovieTitle: UILabel! 


override func viewDidLoad() { 
    super.viewDidLoad() 
    // Do any additional setup after loading the view, typically from a nib. 
    getMovieData() 
    print(self.movies?.count) 
    setUI() 


} 

@IBAction func yesBtn(_ sender: UIButton) { 
    print(movies?[5].title ?? String()) 
} 

@IBAction func seenBtn(_ sender: UIButton) { 

} 

@IBAction func noBtn(_ sender: UIButton) { 

} 


@IBOutlet weak var moviePoster: UIImageView! 


let urlString = "https://api.themoviedb.org/3/discover/movie?api_key=935f539acbfed4b9e5534ddeed3fb57e&language=en-US&sort_by=popularity.desc&include_adult=false&include_video=false&page=1&with_genres=12" 

func getMovieData(){ 
    //Set up URL 
    let todoEndPoint: String = "https://api.themoviedb.org/3/discover/movie?api_key=935f539acbfed4b9e5534ddeed3fb57e&language=en-US&sort_by=popularity.desc&include_adult=false&include_video=false&page=1&with_genres=12" 

    guard let url = URL(string: todoEndPoint) else { 

     print("Cant get URL") 
     return 
    } 

    let urlRequest = URLRequest(url: url) 

    //Setting up session 
    let config = URLSessionConfiguration.default 
    let session = URLSession.shared 

    //Task setup 
    let task = session.dataTask(with: urlRequest) { (data, URLResponse, error) in 

     //Checking for errors 
     guard error == nil else{ 
      print("Error calling GET") 
      print(error) 
      return 
     } 
     //Checking if we got data 
     guard let responseData = data else{ 
      print("Error: No data") 
      return 
     } 

     self.movies = [Movie]() 

     do{//If we got data, if not print error 

      guard let todo = try JSONSerialization.jsonObject(with: responseData, options:.mutableContainers) as? [String:AnyObject] else{ 

       print("Error trying to convert data to JSON") 
       return 


      }//if data is Serializable, do this 


      if let movieResults = todo["results"] as? [[String: AnyObject]]{ 
       //For each movieobject inside of movieresult try to make a movie object 
       for moviesFromJson in movieResults{ 

        let movie = Movie() 

        //If all this works, set variables 
        if let title = moviesFromJson["title"] as? String, let movieRelease = moviesFromJson["release_date"] as? String, let posterPath = moviesFromJson["poster_path"] as? String, let movieId = moviesFromJson["id"] as? Int{ 

         movie.title = title 
         movie.movieRelease = movieRelease 
         movie.posterPath = posterPath 
         movie.movieId = movieId 


        } 

        self.movies?.append(movie) 

       } 

      } 
     }//do end 

     catch{ 
      print(error) 
     } 


    } 
    ////Do Stuff 



    task.resume() 

} 

func setUI(){ 

    //uiMovieTitle.text = self.movies![0].title 
    //print(self.movies?[0].title) 
} 

}

私Movieクラス:

import UIKit 

class Movie: NSObject { 


var title:String? 
var movieRelease: String? 
var posterPath:String? 
var movieId:Int? 
var movieGenre:[Int] = [] 

//public init(title:String, movieRelease:String, posterPath:String,movieId:Int) { 
    // self.movieId = movieId 
    //self.title = title 
    //self.movieRelease = movieRelease 
    //self.posterPath = posterPath 
    //self.movieGenre = [movieGenre] 



//} 

}

+0

がGET呼び出しの内部で追加しようとしないでください、それはあなたがそのエラーになりますので、非同期(async)それを行います、あなたがわからない場合は、コールバックでそれをやろうどうすればいいのか聞いてみてください。例コード –

+0

などで説明しようと思います。はい、私はそれを行う方法は分かりませんし、説明することができます:)私はあなたが意味するものを参照してくださいしかし、私はそれを行う必要がある方法や場所を知っていない:) – Pr0tonion

+0

オハイオ州、私は今新しい答えを作りましょう –

答えて

0

getMovieDataは非同期ネットワークを呼び出します。 viewDidLoadがこれを呼び出してからsetUI()を呼び出しますが、setUIが呼び出されてもネットワーキングは進行中です。

代わりに、self.movies?.append(movie)行の後にネットワークが完了したときにsetUIを呼び出します。 UIコードはメインスレッドで発生する必要があります。だから... ...

for moviesFromJson... // your existing code 
    ... 
    self.movies?.append(movie) 
} 

// Refresh UI now movies have loaded. 
DispatchQueue.main.async { 
    setUI() 
} 
+0

ありがとう!!!チャームのように働いた! – Pr0tonion

0
 import UIKit 

    class ViewController: UIViewController { 

    var movies:[Movie]? = [] 

    @IBOutlet weak var uiMovieTitle: UILabel! 


    override func viewDidLoad() { 
     super.viewDidLoad() 
     // Do any additional setup after loading the view, typically from a nib. 
     getMovieDataCall(completionHandler: {data, error in self. getMovieDataCallBack(data: data, error: error)}) 

    } 

func getMovieDataCallBack(data: Data?, error: Error?) { 
     if error == nil { 
      let dictionary = try! JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! Dictionary<String, AnyObject> 
      //do your appending here and then call setUI() 
      print("dictionaryMovie \(dictionary)") 
     } else { 
      showAlertView("", error?.localizedDescription) 
     } 
} 

    func getMovieDataCall(completionHandler: @escaping (Data?, Error?) -> Void)){ 
     //Set up URL 
     let todoEndPoint: String = "https://api.themoviedb.org/3/discover/movie?api_key=935f539acbfed4b9e5534ddeed3fb57e&language=en-US&sort_by=popularity.desc&include_adult=false&include_video=false&page=1&with_genres=12" 

     guard let url = URL(string: todoEndPoint) else { 

      print("Cant get URL") 
      return 
     } 

     let urlRequest = URLRequest(url: url) 

     //Setting up session 
     let config = URLSessionConfiguration.default 
     let session = URLSession.shared 

     //Task setup 
     let task = session.dataTask(with: urlRequest) { (data, URLResponse, error) in 

       if error != nil { 
        NSLog("GET-ERROR", "=\(error)"); 
        completionHandler(nil, error) 
       } else { 
        let dataString = String(data: data!, encoding: String.Encoding(rawValue: String.Encoding.utf8.rawValue)) 
        print(dataString!) 
        completionHandler(data, nil) 
       } 

     task.resume() 

    } 

    func setUI(){ 

    } 
+0

あなたはGetリクエストを最初に作成し、完了ハンドラを持っていなければならないことがわかります。エラーがなければ、追加してUIをリフレッシュしてください。 –

関連する問題