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 []
}
}
}
// 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)는 사용자 목록을 표시하고 새 사용자를 추가하는 기능을 담당한다.
fetchUsers() 메서드를 통해 데이터를 가져와 tableView를 업데이트한다
addUser() 메서드에서 사용자 입력을 받아 UserManager를 통해 저장한다
직접 메서드 호출(fetchUsers())을 통해 데이터를 갱신한다