title: Protocol-oriented files fetching
body: <p>Recently I watched this talk (<a href="https://realm.io/news/appbuilders-natasha-muraschev-practical-protocol-oriented-programming/" rel="nofollow">link</a>, see section <em>Networking</em>) and I decided to do some excerise in protocol-oriented programming. So I thought about this simple example: View Controller for displaying list of files. Of course, protocol-oriented way, with following constraints:</p>
  
  <p><code>FilesViewController</code> - containts table view &amp; <code>FilesTableViewAdapter</code>. Table view delegate.
  <code>FilesTableViewAdapter</code> - initializable with table view &amp; <code>FilesProvider: Gettable</code>,
  so that in tests I can inject <code>FilesProviderMock: Gettable</code>.
  <code>FilesTableViewAdapter</code> is a data source of table view and uses <code>FilesProvider</code> for fetching files.</p>
  
  <pre><code>final class FilesTableViewController: UIViewController {
  
      var filesTableView: FilesTableView! { return view as! FilesTableView }
  
      private var tableViewAdapter: FilesTableViewAdapter&lt;FilesProvider&gt;!
  
      // MARK: Subclassing
  
      override func loadView() {
          view = FilesTableView(frame: UIScreen.main.bounds)
      }
  
      override func viewDidLoad() {
         tableViewAdapter = FilesTableViewAdapter(filesTableView.tableView, provider: FilesProvider())
  
         // Actually I would like to have this method in Adapter
         // so that VC isn't handling networking.
         tableViewAdapter.provider.get { result in
             // result type: (Result&lt;[File]&gt;)
             switch result {
             case .success(let files): print(files)
             case .failure(let error): print(error)
             }
          }
  
          filesTableView.tableView.delegate = self
          filesTableView.tableView.dataSource = tableViewAdapter
       }
  }
  
  extension FilesTableViewController: UITableViewDelegate {
    //
  }
  
  
  final class FilesTableViewAdapter&lt;T: Gettable&gt;: NSObject, UITableViewDataSource {
  
      let provider: T
      private let tableView: UITableView
  
      init(_ tableView: UITableView, provider: T) {
          self.tableView = tableView
          self.provider = provider
  
          super.init()
      }
  
      func problem() {
          provider.get { result in
              // Result type is (Result&lt;T.T&gt;) - :(
              switch result {
              case .success(let files): print(files)
              case .failure(let error): print(error)
          }
      }
  }
  
  struct FilesProvider {
     private let Files = [File]()
  }
  
  extension FilesProvider: Gettable {
  
      func get(completionHandler: (Result&lt;[File]&gt;) -&gt; Void) {
          //
      }
  }
  
  protocol Gettable {
     associatedtype T
     func get(completionHandler: (Result&lt;T&gt;) -&gt; Void)
  }
  </code></pre>
  
  <p>I know I went too far with <em>generalizing</em> this piece of code. Now I'm stuck and I have this questions I can't answer myself:</p>
  
  <ol>
  <li>How to make it in protocol-oriented way, with networking code in class different than VC (say <em>Adapter</em>)?</li>
  <li>How to make it easily testable and extendable in the future?</li>
  </ol>