2017-09-01 9 views
1

APIから最新のアイテムを取得するためのビルド機能があります。異なる機能を持ついくつかのものがありますが、それらはすべて同じように動作します。これは次のようになります。メソッドAでは、メソッドBのコールバックからデータを取得しますか?

func getLatest(pageNumber: Int) -> Array<Any>{ 
    let urlRequest = URL(string: baseUrl + latestUrl + String(pageNumber)) 

    let requestedData = doRequest(url: urlRequest!, completion: { data -> Void in 
     // We have the data from doRequest stored in data, but now what?! 

    }) 

    return allData 
} 

また、リクエストを処理する非同期メソッドもあります。これは次のようになります。

func doRequest(url: URL, completion: @escaping ([[ApiItem]]) ->()){ 
    var allItems = [[ApiItem]]() 

    URLSession.shared.dataTask(with: url) { (data, response, error) in 
     guard let data = data else { return } 

     do{ 
      let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as! [String: AnyObject] 

      let results = json["items"] as? [AnyObject] 

      for r in results!{ 
       let item = ApiItem(json: r as! [String: Any]) 

       allItems.append([item]) 
      } 

      completion(allItems) 
     } catch let jsonError{ 
      print("JSON error: \(jsonError)") 
     } 
    }.resume() 

doRequest機能はまったく問題なく動作します。データを取得し、JSONを解析してgetLatest - >requestedDataに送信します。今の問題は、getLatest()data変数requestedDataに格納されているデータを返すにはにはが必要な関数であるということです。

getLatest()関数は、dataに格納されているデータをrequestedData()に戻すようにするにはどうすればよいですか?

func getLatest(pageNumber: Int){ 
    let urlRequest = URL(string: baseUrl + latestUrl + String(pageNumber)) 

    let requestedData = doRequest(url: urlRequest!, completion: { data -> items in 
     // We have the data from doRequest stored in data, but now what?! 


     DataManager.instance.items = items 
    }) 

} 

これは私が通常約行く方法です:私はどうなるのか

+0

あなたの[前の質問](https://stackoverflow.com/q/46002165/2227743)に記載されているコメントに従って、お試しいただきたいのと同じ扱いを取得してください。 *コールバックのコールバック*。 doRequestへの呼び出し(あなたの "今何"のコメントがあるか)の中で、getLatestのシグネチャに追加した補完ハンドラを呼び出します。 //素晴らしい作品で、しばしばそれを使用します。あまりにも多くのコールバックを入れ子にしないように注意してください。あなたはまっすぐInception地獄に行くでしょう。 2人は大丈夫です。 – Moritz

+0

ありがとう!私は今働いている! – kaanmijo

+0

あなたのコードを回答に投稿してください。将来のユーザが完全な解決策を見るのがいいかもしれません。 – Moritz

答えて

0

より良いオプションがあるかもしれませんので、私はこれを行うことによってそれを修正しました:

を第一の方法、実際にAPIからのデータを必要とする1で、私はこれを追加しました:

let trendingData = restApiManager.getLatest(pageNumber: 0, completion: { data -> Void in 
    let item = data[indexPath.row] 

    let url = NSURL(string: item.still) 

    let data = NSData(contentsOf: url as! URL) 
    if data != nil { 
     cell.image.image = UIImage(data:data! as Data) 
    }    
}) 

getLatest()方法は次のようになります。

func getLatest(pageNumber: Int, completion: @escaping ([ApiItem]) ->()) { 
    let urlRequest = URL(string: baseUrl + trendingUrl + String(pageNumber)) 

    let requestedData = doRequest(url: urlRequest!, completion: { data -> Void in 
     // We have the data from doRequest stored in data 
     var requestedData = data 
     completion(requestedData) 
    }) 
} 

そして最後に、doRequest()方法は次のようになります。

func doRequest(url: URL, completion: @escaping ([ApiItem]) ->()){ 
    var allItems = [ApiItem]() 

    URLSession.shared.dataTask(with: url) { (data, response, error) in 
     guard let data = data else { return } 

     do{ 
      let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as! [String: AnyObject] 

      let results = json["items"] as? [AnyObject] 

      for r in results!{ 
       let item = ApiItem(json: r as! [String: Any]) 

       allItems.append(item) 
      } 

      completion(allItems) 
     } catch let jsonError{ 
      print("JSON error: \(jsonError)") 
     } 
    }.resume() 
} 
-1

は、その後、あなたの最初の方法では、私はこれを行うだろう、私はデータ

class DataManager:NSObject 
{ 
    static let instance = DataManager() 
    override private init(){} 


    var items:[ApiItem] = [] 
} 

を保存することが可能なシングルトンを使用していますこの種の状況。 ...しかし

関連する問題