티스토리 뷰
안녕하세요 :) Zedd입니다.
https://zeddios.tistory.com/987
Core Data (1)
안녕하세요 :) Zedd입니다. Core Data를 사용할 일이 생겼는데...제가 옜날에 해봤단 말이죠..!?!?!? 근데 다시 하려니까 생각이 하나도 안나는거에요 그때는 문서 볼 생각도 안했었는데..ㅎㅎㅎㅎ 이러면 할때마..
zeddios.tistory.com
저번 글에서 Core Data의 개념과 fetch, save방법을 알아보았습니다..!!!!
오늘은 NSManagedObjectContext의 여러 transaction 메소드들을 살펴볼거에요.
(transaction메소드라고 표현하는게 맞는지는 모르겠지만...)
구구절절 설명안하고 딱 코드만 추가할 예정.
class PersistenceManager { | |
static var shared: PersistenceManager = PersistenceManager() | |
lazy var persistentContainer: NSPersistentContainer = { | |
let container = NSPersistentContainer(name: "The name of the .xcdatamodeld file") | |
container.loadPersistentStores(completionHandler: { (storeDescription, error) in | |
if let error = error as NSError? { | |
fatalError("Unresolved error \(error), \(error.userInfo)") | |
} | |
}) | |
return container | |
}() | |
var context: NSManagedObjectContext { | |
return self.persistentContainer.viewContext | |
} | |
} |
PersistenceManager class하나를 만들었습니다.
저번 글에서는 AppDelegate.swift에서 persistentContainer를 가져왔지만,
이번엔 이 "Persistence"기능을 관장(?)하는 매니저 클래스를 하나 만들어봤어요.
그래서 이 친구가 persistentContainer도 가지고 있습니다.
이 상태에서 메소드를 하나씩 추가해줄거에요. 최종 코드도 업로드 할게요~
- 저장된 데이터 fetch하는 법
class PersistenceManager { | |
static var shared: PersistenceManager = PersistenceManager() | |
.. | |
func fetch<T: NSManagedObject>(request: NSFetchRequest<T>) -> [T] { | |
do { | |
let fetchResult = try self.context.fetch(request) | |
return fetchResult | |
} catch { | |
print(error.localizedDescription) | |
return [] | |
} | |
} | |
} | |
let request: NSFetchRequest<Contact> = Contact.fetchRequest() | |
let fetchResult = PersistenceManager.shared.fetch(request: request) // [Contact] |
처음에는 fetchContact이런식으로 했다가..다들 각자의 NSManagedObject class타입이 있을거잖아요. (저같은 경우 Contact)
좀 general하게 쓰였으면 해서 generic을 사용해봤읍니다..
이렇게 할거면 persistentContainer의 파일 이름도 주입 받아야 하는데 걍 하겠음ㅎ
- 저장하는 법
아 근데 이건 setValue때문에...Contact..만을 위한 메소드가 필요하겠군요??!
class PersistenceManager { | |
static var shared: PersistenceManager = PersistenceManager() | |
.. | |
@discardableResult | |
func insertPerson(person: Person) -> Bool { | |
let entity = NSEntityDescription.entity(forEntityName: "Contact", in: self.context) | |
if let entity = entity { | |
let managedObject = NSManagedObject(entity: entity, insertInto: self.context) | |
managedObject.setValue(person.name, forKey: "name") | |
managedObject.setValue(person.phoneNumber, forKey: "phoneNumber") | |
managedObject.setValue(person.shortcutNumber, forKey: "shortcutNumber") | |
do { | |
try self.context.save() | |
return true | |
} catch { | |
print(error.localizedDescription) | |
return false | |
} | |
} else { | |
return false | |
} | |
} | |
} | |
let walker = Person(name: "Walker", phoneNumber: "010-1234-5678", shortcutNumber: 2) | |
PersistenceManager.shared.insertPerson(person: walker) |
ㅎㅎ...
- 특정 object삭제
class PersistenceManager { | |
static var shared: PersistenceManager = PersistenceManager() | |
... | |
@discardableResult | |
func delete(object: NSManagedObject) -> Bool { | |
self.context.delete(object) | |
do { | |
try context.save() | |
return true | |
} catch { | |
return false | |
} | |
} | |
} | |
let request: NSFetchRequest<Contact> = Contact.fetchRequest() | |
let fetchResult = PersistenceManager.shared.fetch(request: request) | |
PersistenceManager.shared.delete(object: fetchResult.last!) |
- 전체 삭제
class PersistenceManager { | |
static var shared: PersistenceManager = PersistenceManager() | |
.. | |
@discardableResult | |
func deleteAll<T: NSManagedObject>(request: NSFetchRequest<T>) -> Bool { | |
let request: NSFetchRequest<NSFetchRequestResult> = T.fetchRequest() | |
let delete = NSBatchDeleteRequest(fetchRequest: request) | |
do { | |
try self.context.execute(delete) | |
return true | |
} catch { | |
return false | |
} | |
} | |
} | |
let request: NSFetchRequest<Contact> = Contact.fetchRequest() | |
PersistenceManager.shared.deleteAll(request: request) | |
let arr = PersistenceManager.shared.fetch(request: request) | |
if arr.isEmpty { | |
print("clean") // Print "clean" | |
} |
- 갯수
fetch해서 받아온 결과 arr의 count를 사용해도 되지만,
cotext에 count가 있길래 한번 써보려구요~~
class PersistenceManager { | |
static var shared: PersistenceManager = PersistenceManager() | |
.. | |
func count<T: NSManagedObject>(request: NSFetchRequest<T>) -> Int? { | |
do { | |
let count = try self.context.count(for: request) | |
return count | |
} catch { | |
return nil | |
} | |
} | |
} | |
let request: NSFetchRequest<Contact> = Contact.fetchRequest() | |
print(PersistenceManager.shared.count(request: request)) |
- 배열 저장하기
이 부분은 댓글로 어떤분이 물어봐주셨는데 저도 궁금해서 해봅니다.
Entity에 배열로 만들고 싶은 Attribute를 만든뒤,

이렇게요. 그 다음 오른쪽 inspector에서

Type을 Transformable로, custom Class에 내가 배열로 넣을 타입?을 지정해줍니다.
CoreDataProperties에

이것도 추가해줘야겠죠?
그런 다음 똑같이

setValue에 habbit도 추가해줍니다.
그러면 저장이 잘 되는 걸 볼 수 있습니당!!!
나중에 추가되는 메소드 있으면 여기 추가해야지
아래는 전체 코드입니다.
class PersistenceManager { | |
static var shared: PersistenceManager = PersistenceManager() | |
var persistentContainer: NSPersistentContainer = { | |
let container = NSPersistentContainer(name: "Model") | |
container.loadPersistentStores(completionHandler: { (storeDescription, error) in | |
if let error = error as NSError? { | |
fatalError("Unresolved error \(error), \(error.userInfo)") | |
} | |
}) | |
return container | |
}() | |
var context: NSManagedObjectContext { | |
return self.persistentContainer.viewContext | |
} | |
func fetch<T: NSManagedObject>(request: NSFetchRequest<T>) -> [T] { | |
do { | |
let fetchResult = try self.context.fetch(request) | |
return fetchResult | |
} catch { | |
print(error.localizedDescription) | |
return [] | |
} | |
} | |
@discardableResult | |
func insertPerson(person: Person) -> Bool { | |
let entity = NSEntityDescription.entity(forEntityName: "Contact", in: self.context) | |
if let entity = entity { | |
let managedObject = NSManagedObject(entity: entity, insertInto: self.context) | |
managedObject.setValue(person.name, forKey: "name") | |
managedObject.setValue(person.phoneNumber, forKey: "phoneNumber") | |
managedObject.setValue(person.shortcutNumber, forKey: "shortcutNumber") | |
do { | |
try self.context.save() | |
return true | |
} catch { | |
print(error.localizedDescription) | |
return false | |
} | |
} else { | |
return false | |
} | |
} | |
@discardableResult | |
func delete(object: NSManagedObject) -> Bool { | |
self.context.delete(object) | |
do{ | |
try self.context.save() | |
return true | |
} catch { | |
return false | |
} | |
} | |
func count<T: NSManagedObject>(request: NSFetchRequest<T>) -> Int? { | |
do { | |
let count = try self.context.count(for: request) | |
return count | |
} catch { | |
return nil | |
} | |
} | |
@discardableResult | |
func deleteAll<T: NSManagedObject>(request: NSFetchRequest<T>) -> Bool { | |
let request: NSFetchRequest<NSFetchRequestResult> = T.fetchRequest() | |
let delete = NSBatchDeleteRequest(fetchRequest: request) | |
do { | |
try self.context.execute(delete) | |
return true | |
} catch { | |
print(error.localizedDescription) | |
return false | |
} | |
} | |
} |
저 iOS 진짜 아예 처음 할 때 Persistence기능을 썼어야 했거든요zzzz
근데 그때 막 하나도 모르는데 Core Data가 있대...
근데 그땐 Swift도 아예 모를 때라 (for문도 모름ㅋ) 진짜 멘붕
Realm이 쉽다던데.. -> 뭐 쓰기 쉽다고..? 그래 Realm 쓰자 -> 딱 이 의식의 흐름
예전에 Core Data 썼을 때는 그냥 공부 안하고 막 가져다가 썼어서...ㅎㅎㅎㅎㅎ
근데 Core Data도 차근차근 공부하니까 쉽네요 ~.~
도움이 되었길 바랍니다!
'iOS' 카테고리의 다른 글
iOS ) UICollectionReusableView (2) | 2020.04.11 |
---|---|
RxTest (2) | 2020.04.09 |
Core Data (1) (6) | 2020.03.31 |
iOS ) CATextLayer (0) | 2020.02.24 |
iOS ) CAGradientLayer (0) | 2020.02.02 |
- WWDC
- np-complete
- Xcode
- np-hard
- swift 공부
- WidgetKit
- Combine
- actor
- swift array
- 스위프트 문법
- IOS
- Accessibility
- iOS delegate
- swift tutorial
- github
- fastlane
- swift3
- 회고
- swift sort
- FLUTTER
- WKWebView
- UIBezierPath
- ios 13
- Git
- 스위프트
- Swift
- 피아노
- 제이슨 파싱
- swift delegate
- SwiftUI
- Total
- Today
- Yesterday