我有一个加载视图的textView。然后用户可以编辑和修改该值,当用户按下导航按钮时,将启动viewWillDisappear()并将textView出口的值传递给交互器,该交互器应从dataManager触发方法以保存该值对核心数据的价值。
我的问题是在不违反毒蛇规则的情况下传递此参数的最佳方法是什么?
我这样做了,但我几乎可以肯定我做错了。这是我第一次体验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)
}
}
}
DataManager的:
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”等数据,而是通过演示者使用方法传递这些数据。
您应该在演示者中查看弱视图以避免保留周期。并且由于当演示者处于活动状态时,交互器和路由器都不会为nil,因此可以将它们声明为非可选,并在init中初始化它们。对于交互器中的dataManager引用也是如此。