2017-03-11 9 views
-2

私はFlickrの画像を表示するView Controllerを持っています。 Flickr APIリクエストメソッドを別のクラス "FlickrAPIRequests"に入れて、データを取得したときにビューコントローラでイメージを更新する必要があります。 2つのクラスの結合を取り除くために、プロトコルを使用してそれを選択します。どのように私はそれを達成するだろうか?Swift 3でプロトコルを正しく設定する方法

答えて

0

私はsilentBobの答えに続き、それは私のためにうまくいかなかったことを除いて素晴らしかったです。私は私がやったことであるので、ここでは、シングルトンとしてFlickrAPIRequestsクラスを設定するために必要な:ビューコントローラで

protocol FlickrAPIRequestDelegate{ 

func showFlickrPhoto(photo: UIImage) } 

クラスFlickrAPIRequests {

private static let _instance = FlickrAPIRequests() 

static var Instance: FlickrAPIRequests{ 
    return _instance 
} 

var flickrDelegate: FlickrAPIRequestDelegate? = nil 

// Make the Flickr API call 
func flickrAPIRequest(_ params: [String: AnyObject], page: Int){ 

それから私は、検索ボタンを押したとき:

 // Set flickrDelegate protocol to self 
    FlickrAPIRequests.Instance.flickrDelegate = self 

    // Call the method for api requests 
    FlickrAPIRequests.Instance.flickrAPIRequest(paramsDictionary as [String : AnyObject], page: 0) 

さらに、プロトコルに準拠するView Controllerの拡張機能があります。

extension FlickrViewController: FlickrAPIRequestDelegate{ 

func showFlickrPhoto(photo: UIImage){ 

    self.imgView.image = photo 
    self.prepFiltersAndViews() 
    self.dismissAlert() 
} 

}

APIメソッドは、私はメインスレッド内のプロトコルメソッドを呼び出す写真を返すとき:

// Perform this code in the main UI 
        DispatchQueue.main.async { [unowned self] in 
         let img = UIImage(data: photoData as Data) 
         self.flickrDelegate?.showFlickrPhoto(photo: img!) 
         self.flickrDelegate?.setPhotoTitle(photoTitle: photoTitle) 
        } 
1

このようなプロトコル、または同様書く

:ビューコントローラは、別名、このようなプロトコル方式(複数可)を(任意の方法が存在することができる)を使用し、そのプロトコルに準拠している必要があり

protocol FlickrImageDelegate: class { 
    func displayDownloadedImage(flickrImage: UIImage) 
} 

weak var flickrDelegate: FlickrImageDelegate? = nil 
class ViewController:UIViewController, FlickrImageDelegate { 

    displayDownloadedImage(flickrImage: UIImage) { 
      //handle image 
    } 
} 

はその後FlickrAPIRequestsに、あなたはこのようなデリゲートプロパティを持っている必要があります

self.flickrDelegate.displayDownloadedImage(flickrImage: downloadedImage) 

あなたは(コールバックブロックを使用して検討するかもしれない:0これはFlickrAPIRequestsをインスタンス化する際に、コントローラを表示するために、そのインスタンスflickrDelegateプロパティを設定し、画像のダウンロード方法、あなたが画像をダウンロードするとき、あなたはこれを呼び出すには、ビューコントローラで使用されていますクロージャ)FlickrAPIRequestsで、あなたがそれを噛んだ後、FRP、約束などを見てください。

+0

ありがとうございました、この答えは私を助けたが、私は、余分な追加されるまで、それは動作しませんでしたFlickrAPIRequestsクラスをシングルトンとして設定する手順私は答えを掲載した。それに応じて回答を編集したい場合は、受け入れられた回答を変更することができます。 – fullMoon

+0

これは動作するシングルトンである必要はありませんが、それを処理する方法の1つです。 シングルトンインスタンスがある場合は、コールバックブロック(クロージャ)の使用を検討してください。 ルックアップ;) – silentBob

2

あなたはプロトコルを定義し、FlickrAPIRequestsクラスをデリゲートを取るように設定することができます。私は別のアプローチを提案する。

FlickrAPIRequestsに完了ハンドラを使用する方法を設定します。それは次のようになります。

func downloadFileAtURL(_ url: URL, completion: @escaping DataClosure) 

FlickrAPIRequests機能は、ファイルがダウンロードされた後に実行するためにダウンロードするだけでなく、コードのブロックするファイルへのURLを取るだろう。

あなたは(この例では、クラスがDownloadManagerと呼ばれている)このよう

DownloadManager.downloadManager.downloadFileAtURL(
    url, 

    //This is the code to execute when the data is available 
    //(or the network request fails) 
    completion: { 
    [weak self] //Create a capture group for self to avoid a retain cycle. 
    data, error in 

    //If self is not nil, unwrap it as "strongSelf". If self IS nil, bail out. 
    guard let strongSelf = self else { 
     return 
    } 

    if let error = error { 
     print("download failed. message = \(error.localizedDescription)") 
     strongSelf.downloadingInProgress = false 
     return 
    } 

    guard let data = data else { 
     print("Data is nil!") 
     strongSelf.downloadingInProgress = false 
     return 
    } 

    guard let image = UIImage(data: data) else { 
     print("Unable to load image from data") 
     strongSelf.downloadingInProgress = false 
     return 
    } 

    //Install the newly downloaded image into the image view. 
    strongSelf.imageView.image = image 
    } 
) 

をその機能を使用する場合があります私はGithubの上のサンプルプロジェクトがAsyc_demo(リンク)と呼ばれてい私は「のような簡単なダウンロードマネージャを使用したこと上記に概説した。

完了ハンドラを使用すると、完了したダウンロードを処理するコードを呼び出してすぐにダウンロードを開始することができます。コードは現在のスコープにアクセスできるため、ダウンロード後の画像データの配置場所を知ることができます。 。

委任パターンを使用すると、進行中のダウンロードを覚えていて、完了後にどのような処理を行うかを認識できるように、ビューコントローラに状態を設定する必要があります。

関連する問題