ios - 如何将 IBOutlet 值从视图传递到 VIPER iOs 中的交互器?
问题描述
我有一个与视图一起加载的 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
解决方案
老实说,我认为你的方法还可以。有人可能会争辩说,最好不要将“updatedText”和“note”等数据存储在 Presenter 中,而是使用方法通过 Presenter 传递这些数据。
您应该在演示者弱中引用视图以避免保留循环。并且由于当演示者还活着时交互器和路由器都不会为零,您可以将它们声明为非可选并在 init 中初始化它们。交互器中的 dataManager 引用也是如此。
推荐阅读
- mongodb - 为什么 mongorestore 命令不运行?
- fortran - 尽管已经声明了指定的变量,但无法分类的声明?
- r - 为 R 中的单个预测变量生成多个散点图
- debian-buster - Debian Buster 挂起和唤醒局域网问题
- sql - 将源日期格式更改为所需日期格式的挑战
- html - 如何使用媒体查询更改图像地图坐标
- bayesian - coda.samples 中的迭代次数和细值
- java - Spring Boot & Mustache 格式化日期
- python - event() 缺少 1 个必需的位置参数:“coro”错误 discord.py
- c# - 尝试将 Google Cloud Vision API 打到 OCR 图像时出现“打开文件时出错”