我是第一次按照VIPER实施我的项目,我对它的实现有一些疑问。这是我到目前为止所做的: 1)实施登录页面 脚步 i)用户点击登录按钮(在视图控制器上)。 ii)我有一个请求模型,我存储'用户名'和'密码'。这是模型的结构:
struct Login{
struct Request{
var txt_email:String!
var txt_password:String!
}
struct Response {
var homeData:Dictionary<String,Any>
}
}
所以我将此Request对象传递给Interactor。 iii)在Interactor中,我有不同的Workers(工作者类对象方法)被分配来执行不同的任务,如电子邮件验证,空textFields验证等。如果一切顺利,worker api方法命中登录API并将响应传递回Interactor代表团。 iv)更新上述结构中的“响应”模型。 v)现在我在Interactor中有响应,我将此响应传递给Presenter,根据控制器需要向用户显示的内容进行一些操作。 vi)将数据传递给Controller并将其呈现给用户。
问题1:我做得对吗。如果没有,请告诉我正确的方法。如果是,请告诉我是否有改进的余地。 问题2:我需要在主页上实现UITableView和UICollectionView,我认为扩展是他们的方法。我也将遵循相同的主页策略。但是,假设在'didSelectRowAtIndexPath'中,我需要显示弹出一个用户,我认为ViewController最好直接向Presenter询问数据。但这是正确的方法吗?如果不是正确的方法是什么? 问题3:我应该将数据从cellForRowAtIndexPath:传递给实际的单元格(MyCell:UITableViewCell)类方法,然后将值分配给UIElements吗?是或否?
关于问题2和3,这里是我使用UITableView
:https://stackoverflow.com/a/45709546/3990005的Viper应用程序的简单示例的答案。
ViewController不与Interactor交谈,但是对于演示者,所以在cellForRowAtIndexPath:
上你应该给Presenter调用信息,选择了IndexPath
。
关于单元格创建,我喜欢做的是在UITableViewCell
类中有一个setup方法,在ViewController中向Presenter询问数据并将其传递给单元格。其中一些在上面的示例中可见,这里是单元格的setupCell
方法:
func setupCell(withSong: song) {
titleLabel.text = song.title
descriptionLabel.text = song.description
}
参考:https://medium.com/@javedmultani16/viper-architecture-viper-64f6cd91e6ec
我们开发人员基本上根据要求使用MVC,MVP或MVVM架构进行开发。您选择开发应用程序的架构很重要。影响软件架构选择的许多因素,如系统设计,要求,时间线等。
在Viper架构中,每个块对应于具有特定任务,输入和输出的对象。它与装配线中的工人非常相似:一旦工人完成对某个对象的工作,该对象就会传递给下一个工人,直到产品完成。
V(视图):View负责UI更新并显示演示者告诉它的内容。
I(Interactor):Interactor负责从模型层获取数据,其实现完全独立于用户界面。所有业务逻辑都写在Interactor中。例如。获取在Interactor中编写的User Data API调用。
P(Presenter):演示者扮演中间人角色,从交互中获取数据并传递给View。 (可能是数据或任何用户操作)
E(实体):基本上它包含Interactor使用的对象模型。例如。学生,朋友,大学等
R(路由器):它包含应用程序的导航逻辑。例如。下一步按钮操作显示第二屏幕。
更重要的是,我使用了PROTOCOL,它包含应用程序特定模块的所有规则和工作流程。在iOS中,所有协议都使用单独的协议swift文件为每个模块编写。
更重要的是,我使用了PROTOCOL,它包含应用程序特定模块的所有规则和工作流程。在iOS中,所有协议都使用单独的协议swift文件为每个模块编写。
让我们看看它的文件结构:enter image description here
优点:
- 所有模块都是独立的,所以VIPER非常适合大型团队。
- 使源代码更清晰,更紧凑,可重复使用
- 更容易采用TDD(测试驱动开发)
- 您可以轻松地向现有应用程序添加新功能,而无需更改其他模块。
- 它可以应用SOLID原则。
- 减少合并冲突的数量。
- 由于您的UI逻辑与业务逻辑分离,因此可以轻松编写自动化测试
struct Person { // Entity (usually more complex e.g. NSManagedObject)
let firstName: String
let lastName: String
}
struct GreetingData { // Transport data structure (not Entity)
let greeting: String
let subject: String
}
protocol GreetingProvider {
func provideGreetingData()
}
protocol GreetingOutput: class {
func receiveGreetingData(greetingData: GreetingData)
}
class GreetingInteractor : GreetingProvider {
weak var output: GreetingOutput!
func provideGreetingData() {
let person = Person(firstName: "David", lastName: "Blaine") // usually comes from data access layer
let subject = person.firstName + " " + person.lastName
let greeting = GreetingData(greeting: "Hello", subject: subject)
self.output.receiveGreetingData(greeting)
}
}
protocol GreetingViewEventHandler {
func didTapShowGreetingButton()
}
protocol GreetingView: class {
func setGreeting(greeting: String)
}
class GreetingPresenter : GreetingOutput, GreetingViewEventHandler {
weak var view: GreetingView!
var greetingProvider: GreetingProvider!
func didTapShowGreetingButton() {
self.greetingProvider.provideGreetingData()
}
func receiveGreetingData(greetingData: GreetingData) {
let greeting = greetingData.greeting + " " + greetingData.subject
self.view.setGreeting(greeting)
}
}
class GreetingViewController : UIViewController, GreetingView {
var eventHandler: GreetingViewEventHandler!
let showGreetingButton = UIButton()
let greetingLabel = UILabel()
override func viewDidLoad() {
super.viewDidLoad()
self.showGreetingButton.addTarget(self, action: "didTapButton:", forControlEvents:.TouchUpInside)
}
func didTapButton(button: UIButton) {
self.eventHandler.didTapShowGreetingButton()
}
func setGreeting(greeting: String) {
self.greetingLabel.text = greeting
}
// layout code goes here
}
// Assembling of VIPER module, without Router
let view = GreetingViewController()
let presenter = GreetingPresenter()
let interactor = GreetingInteractor()
view.eventHandler = presenter
presenter.view = view
presenter.greetingProvider = interactor
interactor.output = presenter