如何将 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