如何将 IBOutlet 值从视图传递到 VIPER iOs 中的交互器?

Posted

技术标签:

【中文标题】如何将 IBOutlet 值从视图传递到 VIPER iOs 中的交互器?【英文标题】:How to pass IBOutlet value from view to interactor in VIPER iOs? 【发布时间】:2018-09-13 08:58:23 【问题描述】:

我有一个与视图一起加载的 textView。然后用户可以编辑和修改值,当用户按下导航按钮时,viewWillDisappear() 将启动并将 textView 出口的值传递给交互器,这应该从 dataManager 触发一个方法来保存它核心数据的价值。

我的问题是在不违反 viper 规则的情况下传递此参数的最佳方法是什么?

我是这样做的,但我几乎可以肯定我做错了。这是我对 VIPER 架构的第一次体验,我们将不胜感激。

查看文件:

import Foundation
import UIKit
class NoteDetailView : UIViewController  

    var presenter: NoteDetailPresenterProtocol?
    @IBOutlet weak var detailNoteText: UITextView!

    override func viewDidLoad() 
        super.viewDidLoad()
        presenter?.viewDidLoad()
    

    override func viewWillDisappear(_ animated: Bool) 
        super.viewWillDisappear(animated)
        presenter?.updatedText = detailNoteText.text
        presenter?.viewWillDisappear()
    




extension NoteDetailView : NoteDetailViewProtocol 
    func showNote(noteDetail note: NoteModel) 
        detailNoteText.text = note.noteText
    

主持人:

import Foundation
class NoteDetailPresenter : NoteDetailPresenterProtocol 
    var view: NoteDetailViewProtocol?
    var updatedText: String?
    var note: NoteModel?

    var router: NoteDetailRouterProtocol?

    var interactor: NoteDetailInteractorProtocol?

    func viewDidLoad()
        view?.showNote(noteDetail: note!)
    

    func viewWillDisappear() 
        guard note?.noteText.isEmpty == false, let text = updatedText else return
        interactor?.retrieveNote(note: note!, updatedText : text)
    

交互者:

import Foundation
class NoteDetailInteractor : NoteDetailInteractorProtocol 
    var dataManager: NewNoteDataManagerProtocol?
    var localDataManager: NoteListLocalDataManagerInputProtocol?

    func retrieveNote(note: NoteModel, updatedText : String) 
        do 
            if let noteList = try localDataManager?.retrieveNoteList() 

                let noteModelList = noteList.map()
                    return NoteModel(noteText : $0.noteText != nil ? $0.noteText! : "", creationDate : $0.creationDate != nil ? $0.creationDate! : "")
                
                if !noteModelList.isEmpty 
                    var noteTextExist = false
                    var indexPath = 0
                    for (index,newnote) in noteModelList.enumerated()
                        if newnote == note 
                            noteTextExist = true
                            indexPath = index
                        
                    
                    if noteTextExist == true 
                        do 
                            noteList[indexPath].noteText = updatedText
                            try dataManager?.updateNote(note: noteList[indexPath])
                        
                        catch 
                            print(error)
                        
                    
                
            

        
        catch 
            print(error)
        
    


数据管理器:

import Foundation
import CoreData
import UIKit
class NewNoteDataManager : NewNoteDataManagerProtocol

    func deleteNote(note: Note) throws 
        guard let managedOC = CoreDataStore.managedObjectContext else 
            throw PersistenceError.managedObjectContextNotFound
        
        managedOC.delete(note)
        do 
            try managedOC.save()
        
        catch let error as NSError 
            print(error)
        
    

    func updateNote(note: Note) throws 
        guard let managedOC = CoreDataStore.managedObjectContext else 
            throw PersistenceError.managedObjectContextNotFound
        
        do 
            try managedOC.save()
        
        catch let error as NSError 
            print(error)
        

    

    func saveNote(noteText: String) throws 
        guard let managedOC = CoreDataStore.managedObjectContext else 
            throw PersistenceError.managedObjectContextNotFound
        

        if let entity = NSEntityDescription.entity(forEntityName: String("Note"), in: managedOC) 
            do 
                let newNote = Note(entity: entity, insertInto: managedOC)
                newNote.noteText = noteText

                let date = Date()
                let formatter = DateFormatter()
                formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
                newNote.creationDate = formatter.string(from: date)
                try managedOC.save()
            catch let error as NSError 
                print(error)
            
        else 
            throw PersistenceError.couldNotSaveObject
        
    



完整的项目可以在这里找到: https://github.com/AlfroMlg/Notes

【问题讨论】:

Github 链接没有最新提交的代码.. @PratikSodha 现在更新了。它在开发分支中。现在在主分支上 【参考方案1】:

说实话,我认为你的方法还可以。有人可能会争辩说,最好不要将“updatedText”和“note”之类的数据存储在 Presenter 中,而是使用方法通过 Presenter 传递这些数据。

您应该在演示者弱中引用视图以避免保留循环。 并且由于在演示者还活着时交互器和路由器都不会为零,因此您可以将它们声明为非可选并在 init 中初始化它们。交互器中的 dataManager 引用也是如此。

【讨论】:

我完全忘记了保留周期。谢谢你和其他人。我在视图中编写了一个 getter 方法来获取 iboutlet 文本。这是这样做的好方法吗? 看起来很合理。当要访问的视图数据量增加时,请尝试将其分组以避免视图中出现数十个 getter :)

以上是关于如何将 IBOutlet 值从视图传递到 VIPER iOs 中的交互器?的主要内容,如果未能解决你的问题,请参考以下文章

如何将模型值从视图传递到控制器?

如何将值从 tableview 传递到 collectionview

如何将值从动态列表视图传递到活动?

如何将 NsDictionary 值从 tableview 传递到下一个视图

如何将值从列表视图传递到 detalis Activity

如何将值从 def 传递到视图 openerp