2016-04-16 41 views
0

我點擊一個Web API來訪問一些JSON並初始化一個GRDMovie對象。在發生這種情況時,我需要使用其他某些屬性的不同網址來訪問API。這在GRDMovie init方法中引起了一些問題,因爲關閉被越過了。代碼如下:Swift - 使用閉包在init方法中設置屬性

var posterImage : UIImage? 
let title : String 
let score : Double 
var rating : String? 
let releaseDate : String 
let overview : String 
let movieID : Int 
let smallURL : String 
let year : String 

init(title:String, overview:String, score:Double, movieID:Int, releaseDate:String, smallURL: String, year:String) { 

    self.title = title 
    self.overview = overview 
    self.score = score 
    self.movieID = movieID 
    self.releaseDate = releaseDate 
    self.smallURL = smallURL 
    self.year = year 
    self.rating = nil 
    self.posterImage = nil 


    self.getMovieRatingWith(movieID) { (rating) in 
     self.rating = rating 
    } 

    self.getPosterImageDataFromURL(smallURL) { (posterImage) in 
     self.posterImage = posterImage 
    } 
} 

func getMovieRatingWith(movieID: Int, completion: (rating: String) ->()) { 

    var apiDict = NSDictionary() 
    var rating: String = "" 

    let urlString:String = "http://api.themoviedb.org/3/movie/\(movieID)?api_key=ebea8cfca72fdff8d2624ad7bbf78e4c&append_to_response=releases" 
    let escapedUrlString = urlString.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet()) 
    let apiURL = NSURL(string:escapedUrlString!) 
    let session = NSURLSession.sharedSession() 

    session.dataTaskWithURL(apiURL!, completionHandler: { (data:NSData?, response:NSURLResponse?, error:NSError?) in 
     do { 
      if let data2 = data { 
       let jsonDict = try NSJSONSerialization.JSONObjectWithData(data2, options: NSJSONReadingOptions.MutableContainers) as! NSDictionary 
       //send json outward 
       apiDict = jsonDict 

       if let releases = apiDict["releases"] as? NSDictionary { 
        if let countries = releases["countries"] as? [NSDictionary] { 
         for countryData in countries { 
          if let place: String = countryData["iso_3166_1"] as? String { 
           if place == "US" { 
            rating = countryData["certification"] as! String 
           } else { 

           } 
          } 
         } 
        } 
       } 

       if rating == "" { 
        rating = "Not Available" 
       } 

       completion(rating: rating) 
       //print(rating) 
      } 
     } catch { 
      //handle NSError 
      print("error") 
     } 
    }).resume() 
} 

func getPosterImageDataFromURL(smallURL:String, completion: (posterImage: UIImage) ->()) { 

    let escapedURLString:String = smallURL.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())! 
    let callURL = NSURL(string: escapedURLString) 
    let session = NSURLSession.sharedSession() 

    session.dataTaskWithURL(callURL!) { (data:NSData?, response:NSURLResponse?, error:NSError?) in 
     do { 
      if let data2 = data { 
       let poster = UIImage(data: data2) 
       completion(posterImage: poster!) 
      } 
     } 
    } 

} 

自然,我得到零爲posterImage和評級。我如何構造這個以便正確捕獲這些值?

+1

好像你剛剛讀取的值太快? – nielsbot

+1

你可以等待設置值,阻止當前線程,這可能不是你想要做的。或重構您的應用程序,以便在最終設置_rating_和_posterImage_的值時發送通知(或使用類似KVO的內容)以採取操作。 – nielsbot

+1

你真的不應該在init方法中進行網絡調用。爲該對象進行所有需要的調用,然後使用找到的數據創建對象。 – PeejWeej

回答

0

我認爲它更好地在控制器中進行api調用。您可以先創建一個obj,或者在api回調取決於您想要的之後創建它。

如果要先創建obj,請在下面執行此操作。

在GRDMovieController.swift(我只是將其命名爲隨機):

let obj : GRDMovie? 

在某處初始化與obj和調用API來獲取數據:

obj = GRDMovie(title, overview: overview, score: score, movieID: id, releaseDate: date, smallURL: url, year: year) 
getMovieRatingWith(obj) 
getPosterImageDataFromURL(obj) 

而且功能都可以像這個:

func getMovieRatingWith(movieObj: GDVMovie) { 
    var apiDict = NSDictionary() 
    var rating: String = "" 

    let urlString:String = "http://api.themoviedb.org/3/movie/\(movieObj.movieID)?api_key=ebea8cfca72fdff8d2624ad7bbf78e4c&append_to_response=releases" 
    let escapedUrlString = urlString.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet()) 
    let apiURL = NSURL(string:escapedUrlString!) 
    let session = NSURLSession.sharedSession() 

    session.dataTaskWithURL(apiURL!, completionHandler: { (data:NSData?, response:NSURLResponse?, error:NSError?) in 
     do { 
      if let data2 = data { 
       let jsonDict = try NSJSONSerialization.JSONObjectWithData(data2, options: NSJSONReadingOptions.MutableContainers) as! NSDictionary 
       //send json outward 
       apiDict = jsonDict 

       if let releases = apiDict["releases"] as? NSDictionary { 
        if let countries = releases["countries"] as? [NSDictionary] { 
         for countryData in countries { 
          if let place: String = countryData["iso_3166_1"] as? String { 
           if place == "US" { 
            rating = countryData["certification"] as! String 
           } else { 

           } 
          } 
         } 
        } 
       } 

       if rating == "" { 
        rating = "Not Available" 
       } 

       movieObj.rating = rating 

       //print(rating) 
      } 
     } catch { 
      //handle NSError 
      print("error") 
     } 
    }).resume() 
} 

func getPosterImageDataFromURL(movieObj: GRDMovie) { 

    let escapedURLString:String = movieObj.smallURL.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())! 
    let callURL = NSURL(string: escapedURLString) 
    let session = NSURLSession.sharedSession() 

    session.dataTaskWithURL(callURL!) { (data:NSData?, response:NSURLResponse?, error:NSError?) in 
     do { 
      if let data2 = data { 
       let poster = UIImage(data: data2) 
       movieObj.posterImage = poster 
      } 
     } 
    } 

} 

請糾正我,如果我錯了,並希望這會有所幫助。

相關問題