0

私は Swift で iOS 用のアプリを作成しており、API 呼び出しロジックを ViewController の外に保持しようとしています。以下で説明する 1 つの API 呼び出しについて、このチュートリアルに従いました。

ViewController が実装するプロトコル「APIControllerProtocol」を作成してから、タイプ APIControllerProtocol のインスタンスを保持する「delegate」というプロパティを含む APIController クラスを作成しています。プロトコルは単純に次のように定義されます。

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

そして、ViewController は、API 呼び出しが JSON データを返した後に呼び出される didReceiveAPIResults 関数を実装します。ViewController には、API を呼び出す関数を呼び出すための APIController のインスタンスも含まれます。

この時点で、API 呼び出しを実行する ViewController を増やしたいと考えています。ViewController ごとに 1 つの API 呼び出しのみを行う必要がある場合は、APIController に別の関数を追加するだけで、新しい ViewController に同じプロトコルを使用させることができます。ただし、2 つ以上の API 呼び出しを行う必要がある ViewController がある場合、このロジックには欠陥があります。

  1. ViewController で didReceiveAPIResults を 2 つの異なる方法で呼び出すことができません。
  2. 複数の「デリゲート」プロパティを APIController クラスに追加して、さまざまな種類のプロトコルを保持することは道だとは思いません。

  3. プロトコルで複数の関数を定義するということは、1 つの API 呼び出しのみを行う必要がある ViewControllers でこれらすべての関数を実装する必要があることを意味します。

この問題を解決するための私のアイデアは

  1. ViewControllerごとにAPIControllerクラスとAPIControllerProtocolを作る

  2. APIControllerProtocol でオプションの関数を使用して、すべての ViewController がすべての関数を実装する必要がないようにします (これが実際にどのように機能するかはわかりません)。

他の洞察をいただければ幸いです。

4

3 に答える 3

0

プロトコルで複数の関数を定義するということは、1 つの API 呼び出しのみを行う必要がある ViewControllers でこれらすべての関数を実装する必要があることを意味します。

これは正しくありません。オプションの関数を作成すると、おそらく答えが得られます。

@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) のように、呼び出されたときに要件の名前の後に疑問符を書くことで、オプションの要件の実装を確認します。オプションのプロパティ要件、および値を返すオプションのメソッド要件は、オプションの要件が実装されていない可能性があるという事実を反映するために、アクセスまたは呼び出し時に常に適切な型のオプションの値を返します。

于 2015-04-22T14:32:07.520 に答える
0

あなたがロジックの基にしているチュートリアルは、私にはうまく見えません。それが何をするか、それは最大限に調整された標準の委任パターンを実装します。DetailsViewController には APIViewController インスタンスがあり、デリゲートとして自分自身を割り当てます - かなり標準的です。ただし、DetailsViewController は、DetailsViewController に実装されているデリゲート メソッドを起動するために、その APIViewController インスタンスのメソッドを呼び出します。私の好みでは、それはあまりにも多くのことです。

はるかに賢明なパターンは、API 呼び出しを処理し、任意のビュー コントローラーがアクセスできるシングルトン (共有インスタンス) オブジェクトを作成することです。そこでは、パラメーターを受け取るメソッドを実装できます。そのうちの 1 つは、リクエストが結果をビュー コントローラーに渡すのが完了したときに呼び出すことができるクロージャーです。

したがって、View Controller では次のように呼び出します。

 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)
}
于 2017-03-23T00:06:01.653 に答える
0

「API」という用語の使用は混乱を招きます。あなたが言っているのはサーバーリクエストのように聞こえるので、それを私はそれと呼びます。

プロトコルベースの設計ではなく、完了ブロック/クロージャ設計を使用することをお勧めします。

ネットワークリクエストクラスへの呼び出しで完了クロージャーを取得し、サーバーリクエストが完了したらその完了クロージャーを呼び出します。

ネットワーク要求クラスを作成して、保留中の要求ごとに要求のリストと完了クロージャーを維持し、完了または失敗したときに各要求のクロージャーを呼び出すことができます。

于 2015-04-22T14:45:59.167 に答える