mvc패턴, coredata이용시 model이 뷰에전달되는 방식

임혜정·2024년 9월 28일
0

Model (Core Data)에서 View로의 데이터 전달

Core Data를 사용할 때, NSFetchedResultsController를 이용해 데이터 변경을 감지하고 View를 업데이트한다.

모델

import UIKit
import CoreData
import SnapKit

class UserManager {
    static let shared = UserManager()
    
    lazy var persistentContainer: NSPersistentContainer = {
        let container = NSPersistentContainer(name: "UserDataModel")
        container.loadPersistentStores { (storeDescription, error) in
            if let error = error as NSError? {
                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        }
        return container
    }()
    
    func saveUser(name: String, phoneNumber: String) {
        let context = persistentContainer.viewContext
        let user = User(context: context)
        user.name = name
        user.phoneNumber = phoneNumber
        
        do {
            try context.save()
        } catch {
            print("Failed to save user: \(error)")
        }
    }
    
    func fetchUsers() -> [User] {
        let context = persistentContainer.viewContext
        let fetchRequest: NSFetchRequest<User> = User.fetchRequest()
        
        do {
            return try context.fetch(fetchRequest)
        } catch {
            print("Failed to fetch users: \(error)")
            return []
        }
    }
}

VC

// MARK: - Controller
class UserListViewController: UIViewController {
    private var tableView: UITableView!
    private var users: [User] = []
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupUI()
        fetchUsers()
    }
    
    private func setupUI() {
        tableView = UITableView()
        view.addSubview(tableView)
        
        tableView.snp.makeConstraints {
            $0.edges.equalToSuperview()
        }
        
        tableView.register(UserCell.self, forCellReuseIdentifier: "UserCell")
        tableView.dataSource = self
        
        navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(addUser))
    }
    
    private func fetchUsers() {
        users = UserManager.shared.fetchUsers()
        tableView.reloadData()
    }
    
    @objc private func addUser() {
        let alert = UIAlertController(title: "Add User", message: nil, preferredStyle: .alert)
        alert.addTextField { textField in
            textField.placeholder = "Name"
        }
        alert.addTextField { textField in
            textField.placeholder = "Phone Number"
        }
        
        let addAction = UIAlertAction(title: "Add", style: .default) { [weak self] _ in
            guard let name = alert.textFields?[0].text,
                  let phoneNumber = alert.textFields?[1].text,
                  !name.isEmpty, !phoneNumber.isEmpty else { return }
            
            UserManager.shared.saveUser(name: name, phoneNumber: phoneNumber)
            self?.fetchUsers()
        }
        
        alert.addAction(addAction)
        alert.addAction(UIAlertAction(title: "Cancel", style: .cancel))
        
        present(alert, animated: true)
    }
}

extension UserListViewController: UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return users.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "UserCell", for: indexPath) as! UserCell
        let user = users[indexPath.row]
        cell.configure(with: user)
        return cell
    }
}


class UserCell: UITableViewCell {
    let nameLabel = UILabel()
    let phoneLabel = UILabel()
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        
        contentView.addSubview(nameLabel)
        contentView.addSubview(phoneLabel)
        
        nameLabel.snp.makeConstraints {
            $0.left.top.equalToSuperview().offset(10)
        }
        
        phoneLabel.snp.makeConstraints { make in
            $0.left.equalTo(nameLabel)
            $0.top.equalTo(nameLabel.snp.bottom).offset(5)
        }
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func configure(with user: User) {
        nameLabel.text = user.name
        phoneLabel.text = user.phoneNumber
    }
}

UserListViewController(Controller)는 사용자 목록을 표시하고 새 사용자를 추가하는 기능을 담당한다.

Model -> View

fetchUsers() 메서드를 통해 데이터를 가져와 tableView를 업데이트한다

View -> Model

addUser() 메서드에서 사용자 입력을 받아 UserManager를 통해 저장한다

직접 메서드 호출(fetchUsers())을 통해 데이터를 갱신한다

profile
오늘 배운걸 까먹었을 미래의 나에게..⭐️

0개의 댓글