์ƒ์„ธ ์ปจํ…์ธ 

๋ณธ๋ฌธ ์ œ๋ชฉ

[ Swift ] CRUD์™€ CoreData ํ”„๋ ˆ์ž„์›Œํฌ

๐ŸŽ iOS/Swift

by AHN.Jihyeon 2024. 7. 14. 12:07

๋ณธ๋ฌธ

โœ… CRUD

Creat : ๋ฐ์ดํ„ฐ ์ƒ์„ฑ                          // ์ƒˆ๋กœ์šด ์ „ํ™”๋ฒˆํ˜ธ ๋“ฑ๋ก

Read : ๋ฐ์ดํ„ฐ ์ฝ๊ธฐ                           // ์ €์žฅ๋œ ์ „ํ™”๋ฒˆํ˜ธ ๋ฐ์ดํ„ฐ ์กฐํšŒ

Update : ๋ฐ์ดํ„ฐ ์—…๋ฐ์ดํŠธ(์“ฐ๊ธฐ)     // ์ €์žฅ๋œ ์ „ํ™”๋ฒˆํ˜ธ ์ˆ˜์ •

Delete : ๋ฐ์ดํ„ฐ ์‚ญ์ œ                         // ์ „ํ™”๋ฒˆํ˜ธ ์‚ญ์ œ 

 

 

 

Swift๋กœ ๊ธฐ๊ธฐ ๋‚ด ๋””์Šคํฌ์— ๋ฐ์ดํ„ฐ ์ €์žฅํ•˜๋Š” ๋ฐฉ๋ฒ•์€ CoreData์™€ UserDefault๊ฐ€ ๋Œ€ํ‘œ์ ์ด๋‹ค.

๋Œ€๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด์„ ๋•Œ๋Š” CoreData, ๋น„๊ต์  ๋‹จ์ˆœํ•œ ๋ฐ์ดํ„ฐ๋Š” UserDefault๊ฐ€ ์ ์ ˆํ•˜๋‹ค.


โœ… CoreData

์•ฑ์—์„œ ๊ธฐ๊ธฐ์˜ ๋””์Šคํฌ์— ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ณ  ์“ธ ์ˆ˜ ์žˆ๊ฒŒ ๋•๋Š” ํ”„๋ ˆ์ž„์›Œํฌ

 

 

 

โœ… CoreData ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ 

Storage์—์„œ Core Data ์„ ํƒ

 

 

 

 

Entity ์ƒ์„ฑ

 

 

 

 

Attribute๋กœ name๊ณผ phoneNumber๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค. 

์ด๋Š” ์ „ํ™”๋ฒˆํ˜ธ๋ถ€๋ผ๋Š” ๋ฐ์ดํ„ฐ ์ง‘ํ•ฉ์— ์ด๋ฆ„๊ณผ ์ „ํ™”๋ฒˆํ˜ธ ์†์„ฑ์„ ๋ถ€์—ฌํ•œ ๊ฒƒ์ด๋‹ค. 

 

 

 

์—ฌ๊ธฐ์„œ ์™ผ์ชฝ ์ด๋ฏธ์ง€๋ฅผ ๋ณด๋ฉด, codegen์ด ๊ธฐ๋ณธ์œผ๋กœ class defininion์œผ๋กœ ๋˜์–ด ์žˆ๋‹ค. 

์ด๊ฑธ manual /none์œผ๋กœ ๋ฐ”๊ฟ”์ฃผ์–ด์•ผ ์•„๋ž˜์™€ ๊ฐ™์€ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค. 

๊ทธ๋ฆฌ๊ณ  ์˜ค๋ฅธ์ชฝ ์ด๋ฏธ์ง€์˜ ์ƒ๋‹จ์˜ ์—๋””ํ„ฐ ๋ถ€๋ถ„์—์„œ ํ•ด๋‹น ๋ถ€๋ถ„์„ ํด๋ฆญํ•ด์ฃผ๋ฉด ๋œ๋‹ค. 

 

Codegen ๊ฐœ๋…

Code Generator ์˜ ์ค„์ž„๋ง. Entity ๋ฅผ ์–ด๋–ค ํ˜•์‹์˜ ์ฝ”๋“œ๋กœ ์ƒ์„ฑํ•  ๊ฒƒ์ธ์ง€ ์„ ํƒํ•˜๋Š” ์†์„ฑ.

  • Manual/None = Entity ์˜ ์„œ๋ธŒ ํด๋ž˜์Šค๋ฅผ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•˜์ง€ ์•Š๊ณ  ๊ฐœ๋ฐœ์ž๊ฐ€ ํด๋ž˜์Šค ์ž‘์„ฑ.
  • Class Definition = Entity ์˜ ์„œ๋ธŒ ํด๋ž˜์Šค๋ฅผ ์ž๋™์œผ๋กœ ์ƒ์„ฑ.
  • Category/Extension = Entity ํด๋ž˜์Šค์™€ ํ•จ๊ป˜ extension ์„ ์œ„ํ•œ ํŒŒ์ผ๊นŒ์ง€ ์ƒ์„ฑ.

 

 

 

์œ„์™€ ๊ฐ™์€ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค๋ฉด ํ•ด๋‹น ํŒŒ์ผ์„ ์‚ญ์ œํ•ด์ฃผ๊ณ  ๋‹ค์‹œ ์ƒ์„ฑํ•ด์ฃผ๋ฉด ๋œ๋‹ค. 

 

 

 

๐ŸŒŸ CoreDataClass.swift 

 

 

 

๐ŸŒŸCoreDataProperties.swift

 

 

 

๐ŸŒŸ AppDelegate.swift - NSPersistentContainer ์ž๋™ ์ƒ์„ฑ

CoreData์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ณ  ๊ด€๋ฆฌํ•˜๋Š”๋ฐ ํ•„์š”ํ•œ ํ•ต์‹ฌ ๊ฐ์ฒด

CoreData์™€ ํ”„๋กœ์ ํŠธ ์‚ฌ์ด ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ  ๋ฐ›๋Š” ๋งค๊ฐœ์ฒด

 

 

 

๐ŸŒŸ AppDelegate.swift - saveContext() ๋ฉ”์„œ๋“œ ์ž๋™ ์ƒ์„ฑ

๋ฐ์ดํ„ฐ์˜ ์—…๋ฐ์ดํŠธ(์ถ”๊ฐ€, ์—…๋ฐ์ดํŠธ, ์‚ญ์ œ ๋“ฑ)๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด saveContext()๋ฅผ ํ˜ธ์ถœํ•ด ๋ฌธ๋งฅ์„ ์ €์žฅ 

 

 

 


โœ… CoreData๋ฅผ ํ™œ์šฉํ•œ CRUD

 

 

 

๐ŸŒŸ CoreDataTest์— ๋ฐ์ดํ„ฐ Creat

func createData(name: String, phoneNumber: String) {
					  
    guard let entity = NSEntityDescription.entity(forEntityName: "PhoneBook", in: self.container.viewContext) else { return }
    let newPhoneBook = NSManagedObject(entity: entity, insertInto: self.container.viewContext)
    newPhoneBook.setValue(name, forKey: "name")
    newPhoneBook.setValue(phoneNumber, forKey: "phoneNumber")
        
    do {
        try self.container.viewContext.save()
        print("๋ฌธ๋งฅ ์ €์žฅ ์„ฑ๊ณต")
    } catch {
        print("๋ฌธ๋งฅ ์ €์žฅ ์‹คํŒจ")
    }
}

 

 

 

 

๐ŸŒŸ CoreDataTest์—์„œ ๋ฐ์ดํ„ฐ 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: "name") as? String,
                   let phoneNumber = phoneBook.value(forKey: "phoneNumber") as? String {
                    print("name: \(name), phoneNumber: \(phoneNumber)")
                }
            }
            
        } catch {
            print("๋ฐ์ดํ„ฐ ์ฝ๊ธฐ ์‹คํŒจ")
        }
    }

 

 

 

 

๐ŸŒŸ CoreData๋ฅผ ํ†ตํ•ด Update

 func updateData(currentName: String, updateName: String) {
        print(#function)
        // ์ˆ˜์ •ํ•  ๋ฐ์ดํ„ฐ๋ฅผ ์ฐพ๊ธฐ ์œ„ํ•œ fetch request ์ƒ์„ฑ
        let fetchRequest = PhoneBook.fetchRequest() //PhoneBook์— ์žˆ๋Š” ๋ฐ์ดํ„ฐ ์กฐํšŒ
        fetchRequest.predicate = NSPredicate(format: "name == %@", currentName) // name์ด currentName์ธ ๋ฐ์ดํ„ฐ๋ฅผ ์ฐพ๋Š” ์กฐ๊ฑด๋ฌธ
    //์˜ˆ์‹œ: ์ด๋ฆ„์ด "Jihyeon"์ธ ๋ฐ์ดํ„ฐ ์ˆ˜์ •
        
        do {
            // fetch request ์‹คํ–‰
            let result = try self.container.viewContext.fetch(fetchRequest)
            
            // ๊ฒฐ๊ณผ ์ฒ˜๋ฆฌ
            for data in result as [NSManagedObject] {
                // ๋ฐ์ดํ„ฐ ์ˆ˜์ • - ๋ฐ์ดํ„ฐ ์ค‘ name์˜ ๊ฐ’์„ updateName์œผ๋กœ updateํ•œ๋‹ค.
                data.setValue(updateName, forKey: PhoneBook.Key.name) // ์ด๋ฆ„์„ "Jihyeon"์—์„œ "Swfit"๋กœ ์ˆ˜์ •
                
                // ๋ณ€๊ฒฝ ์‚ฌํ•ญ ์ €์žฅ
                try self.container.viewContext.save()
                print("๋ฐ์ดํ„ฐ ์ˆ˜์ • ์™„๋ฃŒ")
            }
            
        } catch {
            print("๋ฐ์ดํ„ฐ ์ˆ˜์ • ์‹คํŒจ")
        }
    }

 

 

 

 

๐ŸŒŸCoreData๋ฅผ ํ†ตํ•ด Delete

func deleteData(name: String) {
    // ์‚ญ์ œํ•  ๋ฐ์ดํ„ฐ๋ฅผ ์ฐพ๊ธฐ ์œ„ํ•œ fetch request ์ƒ์„ฑ
    let fetchRequest = PhoneBook.fetchRequest()
    fetchRequest.predicate = NSPredicate(format: "name == %@", name)
    
    do {
        // fetch request ์‹คํ–‰
        let result = try self.container.viewContext.fetch(fetchRequest)
        
        // ๊ฒฐ๊ณผ ์ฒ˜๋ฆฌ
        for data in result as [NSManagedObject] {
            // ์‚ญ์ œ
            // CRUD ์˜ D.
            self.container.viewContext.delete(data)
            print("์‚ญ์ œ๋œ ๋ฐ์ดํ„ฐ: \(data)")
        }
        
        // ๋ณ€๊ฒฝ ์‚ฌํ•ญ ์ €์žฅ
        try self.container.viewContext.save()
        print("๋ฐ์ดํ„ฐ ์‚ญ์ œ ์™„๋ฃŒ")
        
    } catch {
        print("๋ฐ์ดํ„ฐ ์‚ญ์ œ ์‹คํŒจ: \(error)")
    }
}

 

 

 

 

๊ด€๋ จ๊ธ€ ๋”๋ณด๊ธฐ