SobjectiveRecordとは
SobjectiveRecord는 Swift로 작성된 CoreData용 라이브러리.
오픈소스로 Github에서 자유롭게 이용 가능 합니다.
Xcode 6.1.1 로 구현
SobjectiveRecord의 특징
적은 코드량으로 CoreData를 자유롭게 조작 가능하고
제네릭을 이용해 구현을 하여 fecth결과를 형변환없이 사용가능 합니다.
특히 백그라운드 처리를 기본으로 하고 있어 UI쓰레드를 블럭하지 않고 사용할 수도 있습니다.
CoreData의 백그라운드 처리에 대한 상세내용은 아래 글들을 참고하세요.
SobjectiveRecord의 이용
이용 준비
- Github -> SobjectiveRecord에서 다운로드 한후
SobjectiveRecord
폴더를 사용할 프로젝트에 복사,
또는 CocoaPods을 이용pod 'SobjectiveRecord'
CocoaPods 이용시는 CocoaPods의 버젼이 0.36 이상
초기화
import SobjectiveRecord // CocoaPods 이용시 만
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// 우선 CoreData를 이용하기 전에 스토어를 초기화
NSPersistentStoreCoordinator.setupDefaultStore()
// youre code here
return true
}
Basic
- typealias를 이용하여 모델 클래스의 typealias를 정의
SobjectiveRecord는 fecth결과를 형변환없이 사용하기 위한 클래스.
한번만 정의해 두면 두고두고 편합니다.
// User, Tweet는 NSManagedObject의 서브클래스
typealias Users = SobjectiveRecord<User>
typealias Tweets = SobjectiveRecord<Tweet>
// 이후 이건 동등
var user = SobjectiveRecord<User>.create()
var user = Users.create()
기본적으로 모든 처리는 performBlock:
안에 기술
NSManagedObjectContext.defaultContext.performBlock {
// your code here
}
var moc = NSManagedObjectContext.defaultContext.createChildContext()
moc.performBlock {
// your code here
}
Create / Save / Delete
NSManagedObjectContext.defaultContext.performBlock {
var t = Tweets.create()
t.text = "I am here"
t.save()
t = Tweets.create(attributes: ["text" : "hello!!", "lang" : "en"])
t.delete()
}
NSManagedObjectContext.defaultContext.performBlock {
Tweets.deleteAll()
NSManagedObjectContext.defaultContext.save()
}
Finders
NSManagedObjectContext.defaultContext.performBlock {
var tweets = Tweets.all()
var tweetsInEnglish = Tweets.find(condition: "lang == 'en'")
var hmhv = Users.first(condition: "screenName == 'hmhv'")
var englishMen = Users.find(condition: ["lang" : "en", "timeZone" : "London"])
var predicate = NSPredicate(format: "friendsCount > 100")
var manyFriendsUsers = Users.find(condition: predicate)
}
Order and Limit
NSManagedObjectContext.defaultContext.performBlock {
var sortedUsers = Users.all(order: "name")
var allUsers = Users.all(order: "screenName ASC, name DESC")
// or
var allUsers2 = Users.all(order: "screenName A, name D")
// or
var allUsers3 = Users.all(order: "screenName, name d")
var manyFriendsUsers = Users.find(condition: "friendsCount > 100", order: "screenName DESC")
var fiveEnglishUsers = Users.find(condition: "lang == 'en'", order: "screenName ASC", fetchLimit: 5)
}
Aggregation
NSManagedObjectContext.defaultContext.performBlock {
var allUserCount = Users.count()
var englishUserCount = Users.count(condition: "lang == 'en'")
}
BatchUpdate
NSManagedObjectContext.defaultContext.performBlock {
Users.batchUpdate(condition: "friendsCount > 10", propertiesToUpdate: ["friendsCount": 0])
// update all entities
Users.batchUpdate(propertiesToUpdate: ["friendsCount": 100])
}
NSFetchedResultsController
NSManagedObjectContext.defaultContext.performBlock {
var frc = Users.createFetchedResultsController(order: "name")
frc.delegate = self
var error: NSError? = nil
if frc.performFetch(&error) {
self.reloadData()
}
}
Custom ManagedObjectContext
var childContext = NSManagedObjectContext.defaultContext.createChildContext()
childContext.performBlock {
var john = Users.create(context: childContext)
john.name = "John"
john.save()
var savedJohn = Users.first(condition: "name == 'John'", context: childContext)
var manyFriendsUsers = Users.find(condition: "friendsCount > 100", order: "screenName DESC", context: childContext)
var allUsers = Users.all(context: childContext)
}
커스텀 모델, 커스텀 sqlite파일의 이용
var modelURL = NSURL.defaultModelURL(modelName: "model_name")
NSPersistentStoreCoordinator.setupDefaultStore(modelURL: modelURL)
// or
var storeURL = NSURL.defaultStoreURL(fileName: "file_name.sqlite")
NSPersistentStoreCoordinator.setupDefaultStore(storeURL: storeURL)
맵핑
웹 서비스로 부터의 JSON은 first_name
, last_name
과 같은 스네이크 케이스인 경우가 많지만,
Objective-C에서는 firstName
, lastName
과 같은 캐멀 케이스가 주류다.
그래서 스네이크 케이스에서 캐멀 케이스로의 맵핑은 자동으로 됩니다.
그외에 특별한 이름 맵핑이 필요한 경우는 각 모델 클래스에서 mappings을 오버라이드에서 설정가능.
!! Date, Transformable 타입 및 Relationships은 맵핑 대상외 입니다. !!
// just override +mappings in your NSManagedObject subclass
extension User
{
override class var mappings: [String: String]? {
return ["description" : "userDescription"]
}
}
// first_name => firstName 은 자동으로 맵핑됨
테스트
HobjectiveRecord은 메모리내 스토어를 설정가능합니다. 테스트 이용에 편리합니다.
NSPersistentStoreCoordinator.setupDefaultStore(useInMemoryStore: true)