CRUD는 일반적인 개발론에서 자주 사용되는 용어로, 다음과 같은 의미를 가진다:
예를 들어, 전화번호 앱에서의 CRUD는 다음과 같이 적용된다:
데이터 CRUD는 네이티브(앱) 내부에서도, 서버에서도 일어날 수 있다.
CoreData는 앱에서 기기의 디스크에 데이터를 읽고 쓸 수 있게 돕는 프레임워크이다. Swift로 기기 내 디스크에 데이터를 저장할 수 있는 대표적인 방법으로는 CoreData와 UserDefaults가 있다.
Storage → CoreData
를 선택한다.Editor → Create NSManagedObject Subclass를 클릭해서 코드를 생성한다.
PhoneBook+CoreDataClass.swift
import Foundation
import CoreData
@objc(PhoneBook)
public class PhoneBook: NSManagedObject {
}
PhoneBook+CoreDataProperties.swift
import Foundation
import CoreData
extension PhoneBook {
@nonobjc public class func fetchRequest() -> NSFetchRequest<PhoneBook> {
return NSFetchRequest<PhoneBook>(entityName: "PhoneBook")
}
@NSManaged public var name: String?
@NSManaged public var phoneNumber: String?
}
extension PhoneBook : Identifiable {
}
NSPersistentContainer는 CoreData에서 데이터를 저장하고 관리하는 데 필요한 핵심 객체이다.
Create & Read 예제
import UIKit
import CoreData
class ViewController: UIViewController {
var container: NSPersistentContainer!
override func viewDidLoad() {
super.viewDidLoad()
let appDelegate = UIApplication.shared.delegate as! AppDelegate
self.container = appDelegate.persistentContainer
createData(name: "Adam", phoneNumber: "010-1111-2222")
readAllData()
}
// Create
func createData(name: String, phoneNumber: String) {
guard let entity = NSEntityDescription.entity(forEntityName: PhoneBook.className,
in: self.container.viewContext) else { return }
let newPhoneBook = NSManagedObject(entity: entity, insertInto: self.container.viewContext)
newPhoneBook.setValue(name, forKey: PhoneBook.Key.name)
newPhoneBook.setValue(phoneNumber, forKey: PhoneBook.Key.phoneNumber)
do {
try self.container.viewContext.save()
print("문맥 저장 성공")
} catch {
print("문맥 저장 실패")
}
}
// Read
func readAllData() {
do {
let phoneBooks = try self.container.viewContext.fetch(PhoneBook.fetchRequest())
for phoneBook in phoneBooks as [NSManagedObject] {
if let name = phoneBook.value(forKey: PhoneBook.Key.name) as? String,
let phoneNumber = phoneBook.value(forKey: PhoneBook.Key.phoneNumber) as? String {
print("name: \(name), phoneNumber: \(phoneNumber)")
}
}
} catch {
print("데이터 읽기 실패")
}
}
}
Update 예제
func updateData(currentName: String, updateName: String) {
let fetchRequest = PhoneBook.fetchRequest()
fetchRequest.predicate = NSPredicate(format: "name == %@", currentName)
do {
let result = try self.container.viewContext.fetch(fetchRequest)
for data in result as [NSManagedObject] {
data.setValue(updateName, forKey: PhoneBook.Key.name)
try self.container.viewContext.save()
print("데이터 수정 완료")
}
} catch {
print("데이터 수정 실패")
}
}
Delete 예제
func deleteData(name: String) {
let fetchRequest = PhoneBook.fetchRequest()
fetchRequest.predicate = NSPredicate(format: "name == %@", name)
do {
let result = try self.container.viewContext.fetch(fetchRequest)
for data in result as [NSManagedObject] {
self.container.viewContext.delete(data)
print("삭제된 데이터: \(data)")
}
try self.container.viewContext.save()
print("데이터 삭제 완료")
} catch {
print("데이터 삭제 실패: \(error)")
}
}
UserDefaults 또한 디스크에 데이터를 저장할 수 있게 돕는 도구이다. CoreData보다 사용성이 간단하며, key와 value를 이용해서 값을 저장한다.
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Create
UserDefaults.standard.set("010-1111-2222", forKey: "phoneNumber")
// Read
let phoneNumber = UserDefaults.standard.string(forKey: "phoneNumber")
print("저장된 전화번호: \(phoneNumber)")
// Update
UserDefaults.standard.set("010-6666-7777", forKey: "phoneNumber")
let newPhoneNumber = UserDefaults.standard.string(forKey: "phoneNumber")
print("바뀐 전화번호: \(newPhoneNumber)")
// Delete
UserDefaults.standard.removeObject(forKey: "phoneNumber")
print("전화번호가 남아있는가: \(UserDefaults.standard.string(forKey: "phoneNumber"))")
}
}
import UIKit
import SnapKit
class ViewController: UIViewController {
private let label: UILabel = {
let label = UILabel()
label.text = "포스트잇"
label.font = .boldSystemFont(ofSize: 30)
label.textColor = .black
return label
}()
private let textView: UITextView = {
let textView = UITextView()
textView.text = UserDefaults.standard.string(forKey: "memo")
textView.layer.cornerRadius = 10
textView.backgroundColor = UIColor(red: 75/255, green: 253/255, blue: 30/355, alpha: 1.0)
textView.textColor = .black
textView.font = .boldSystemFont(ofSize: 30)
return textView
}()
private lazy var button: UIButton = {
let button = UIButton()
button.setTitle("적용", for: .normal)
button.backgroundColor = .red
button.setTitleColor(.white, for: .normal)
button.titleLabel?.font = .boldSystemFont(ofSize: 20)
button.layer.cornerRadius = 10
button.addTarget(self, action: #selector(buttonTapped), for: .touchDown)
return button
}()
override func viewDidLoad() {
super.viewDidLoad()
configureUI()
}
private func configureUI() {
[label, textView, button].forEach { view.addSubview($0) }
view.backgroundColor = .white
label.snp.makeConstraints {
$0.top.equalToSuperview().offset(100)
$0.centerX.equalToSuperview()
}
textView.snp.makeConstraints {
$0.top.equalTo(label.snp.bottom).offset(100)
$0.centerX.equalToSuperview()
$0.height.width.equalTo(200)
}
button.snp.makeConstraints {
$0.top.equalTo(textView.snp.bottom).offset(50)
$0.width.equalTo(60)
$0.height.equalTo(40)
$0.centerX.equalToSuperview()
}
}
@objc
private func buttonTapped() {
UserDefaults.standard.set(textView.text, forKey: "memo")
print("저장 완료")
}
}