如何创建面向协议的通用服务?

问题描述:

我正在尝试创建一个协议,为视图控制器提供数据。我试图采用协议方法并使事情变得灵活,所以视图控制器可以使用任何类型的数据来符合。如何创建面向协议的通用服务?

不过,我发现了错误:Protocol 'Serviceable' can only be used as a generic contraint because it has Self or associated type requirements

这就是我想要做的事:

protocol Serviceable { 
    associatedtype DataType 
    func get(handler: ([DataType] -> Void)?) 
} 

struct PostService: Serviceable { 
    func get(handler: ([Postable] -> Void)? = nil) { 
     print("Do something...") 
    } 
} 

struct AuthorService: Serviceable { 
    func get(handler: ([Authorable] -> Void)? = nil) { 
     print("Do something...") 
    } 
} 

protocol Postable { 
    var title: String { get set } 
    var content: String { get set } 
} 

protocol ServiceControllable: class { 
    var service: Serviceable { get } // Error: Protocol 'Serviceable' can only be used as a generic contraint because it has Self or associated type requirements 
} 

extension ServiceControllable { 
    func setupDataSource() { 
     service.get { items in 
      // Do something 
     } 
    } 
} 

class MyViewController: ServiceControllable { 
    let service: Serviceable = PostService() // Error: Same as above 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     setupDataSource() 
    } 
} 

如何设置这使我的视图控制器可以实现ServiceControllable和有权访问填充表,集合等的通用setupDataSource?

你想要这样的东西。

import UIKit 

protocol Serviceable { 
    associatedtype DataType 
    func get(handler: ([DataType] -> Void)?) 
} 

struct PostService: Serviceable { 
    func get(handler: ([Postable] -> Void)? = nil) { 
     print("Do something...") 
    } 
} 

protocol Authorable {} 

struct AuthorService: Serviceable { 
    func get(handler: ([Authorable] -> Void)? = nil) { 
     print("Do something...") 
    } 
} 

protocol Postable { 
    var title: String { get set } 
    var content: String { get set } 
} 

protocol ServiceControllable: class { 

    // THIS is the way to use generic-constraint-protocols in protocols. 
    associatedtype _Serviceable: Serviceable 

    var service: _Serviceable { get } 

} 

extension ServiceControllable { 
    func setupDataSource() { 
     service.get { items in 
      // Do something 
     } 
    } 
} 

class MyViewController: UIViewController, ServiceControllable { 

    let service = PostService() 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     setupDataSource() 
    } 
} 

相关文件部分:Protocol Associated Type Declaratio