2015-04-22 78 views
0

我正在Swift中爲iOS創建一個應用程序,並且試圖將我的API調用邏輯保留在我的ViewControllers之外。我跟着this tutorial進行了一個API調用,我將在下面介紹。使用協議實現多個API調用(服務器請求)

我正在創建ViewController將實現的協議「APIControllerProtocol」,然後創建一個APIController類,該類將包含名爲'delegate'的屬性以保存APIControllerProtocol類型的實例。該協議被簡單地定義爲

protocol APIControllerProtocol { 
    func didReceiveAPIResults(result: SwiftyJSON.JSON) 
} 

而且視圖控制器將實行didReceiveAPIResults函數的調用API調用返回JSON數據之後。 ViewController將包含一個APIController的實例,並調用一個函數調用API。

在這一點上,我想讓更多的ViewControllers執行API調用,如果我只需要爲每個ViewController調用1個API,那麼我可以將另一個函數添加到APIController中,並且我可以讓新的ViewController使用相同的協議。但是,如果有,將需要作出2所或多個API調用的ViewController這個邏輯是有缺陷的,因爲

  1. 我不能在兩種不同的方式調用didReceiveAPIResults在ViewController中,
  2. 我不認爲添加多個'委託'屬性到APIController類來保存不同類型的協議是一條路。

  3. 在協議中定義多個函數意味着我將不得不在ViewControllers中實現所有這些函數,只需要進行1次API調用即可。

我的思路來解決這個問題是

  1. 做一個APIController類APIControllerProtocol在APIControllerProtocol每個視圖控制器

  2. 使用可選功能,因此不是每個視圖控制器就必須實現所有的功能(我不知道這會如何工作)

任何其他見解,將不勝感激。

回答

0

您對「API」一詞的使用令人困惑。這聽起來像你的意思是一個服務器請求,所以這就是我要稱之爲。

我會建議使用完成塊/封閉設計而不是基於協議的設計。

使您的網絡請求類的調用取得完成關閉,並在服務器請求完成後調用該完成關閉。

您可以編寫網絡請求類來維護每個待處理請求的請求列表和完成關閉,並在每個請求完成或失敗後調用關閉。

+0

是的,此處的API調用表示服務器請求。閉包設計對協議設計有什麼好處?我不明白維護一個請求列表的重要性是什麼?您能否提供代碼或指向教程的鏈接以向我展示如何使用服務器請求的關閉? – hoffware

+0

這聽起來像你想擁有一個管理多個服務器請求的類。代表是一對一的關係。每個服務器管理器對象只能有一個且只有一個委託。您不能以這種方式管理來自3個不同視圖控制器的未決請求。有了完成塊,你可以。 –

+0

您可能想要看看像AFNetworking這樣的圖書館,而不是重新發明輪子。特別是那個非常豐富和成熟,有很多很棒的功能,並且有成千上萬的開發者在使用它。它能做到我們談論得非常好。 –

0

在協議中定義多個功能將意味着我將不得不 實現所有這些功能在ViewControllers只需要 使1個API調用。

這是不正確的。創建可選功能,你可能有你的答案。

@objc protocol APIControllerProtocol { 
    func didReceiveAPIResults(result: SwiftyJSON.JSON) 
    optional func someAwesomeMethod() 
} 

https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Protocols.html

任擇議定書要求

您可以定義協議的可選的要求,這些要求 不必由符合協議類型來實現。 可選要求以可選修飾符作爲協議定義的一部分 的前綴。

可選的協議需求可以通過可選的鏈接調用, 用於說明需求不是由符合協議的類型實現的 。有關可選鏈接的信息 ,請參閱可選鏈接。

通過在請求名稱後面寫入 問號,例如someOptionalMethod?(someArgument),可以檢查可選需求的實現。可選屬性 要求和返回值的可選方法要求 將在訪問或調用 時始終返回適當類型的可選值,以反映可選 要求可能尚未實現的事實。

+0

我得到的錯誤 「‘可選’只能是應用於「@ objc'協議的成員」,我認爲這意味着我需要執行'@objc協議APIControllerProtocol'。但是,檢查使用可選函數的UITableViewDelegate的源代碼時,我注意到它沒有'@ objc'標記。我必須添加'@ objc'標籤嗎? – hoffware

+0

在我發佈的文檔中對此進行了討論。 @objc協議APIControllerProtocol –

+0

當我向協議中添加@ @ objc時,會出現另一個錯誤「由於無法在Objective-C中表示參數的類型,因此方法不能標記爲」@ obc「。我可以返回另一個JSON表示,或者在調用委託之前解析JSON,但是還有其他選項嗎? – hoffware

0

你基於你的邏輯的教程看起來對我來說不好。它所做的,它實現了一個標準的委託模式調整到最大值。 DetailsViewController有一個APIViewController實例,它將它自己指定爲代理 - 非常標準。但是,然後DetailsViewController會調用該APIViewController實例上的方法以獲取在DetailsViewController中實現的委託方法。這對我的口味來說太過分了。

更合理的模式是創建一個單獨的(共享實例)對象,它將處理您的API調用,並且任何視圖控制器都可以訪問它。在那裏你可以實現你的參數的方法,其中之一是一個閉包,當你的請求完成時將結果傳遞給視圖控制器。

所以在您的視圖控制器,你會打電話來是這樣的:

APIController.sharedInstance.doSomethingWith(someParameter, completion: { (result) -> Void in 
    // Do something with the result 
}) 

你APIController會實現這個像這樣

func doSomethingWith(param: String, completion: (AnyObject) -> Void) { 
    // do your data fetching here... 
    // pass the result to the closure when the data is retrieved 
    completion(result) 
} 
相關問題