Realm
Objective-C, Swift 에서 사용하기
직접 테스트 해보시려면 아래 두 링크를 참고하세요.
한 프로젝트에서 Objective-C, Swift 둘 다 사용하기
[IOS (Swift, Objective-c)] - [IOS] Objective-c, Swift 혼합 프로젝트
CocoaPod 설치, Realm 설치
[IOS (Swift, Objective-c)] - [IOS] CocoaPod 설치. 프로젝트 설정하기
Objective-C 에서 Realm 사용하기
Objective-C ViewController.m 에서
(전체 소스는 하단에 접은글에 있습니다.)
import
#import <Realm/Realm.h>
Model 객체 정의
// Define your models
@interface User : RLMObject
@property NSString *name;
@property NSInteger age;
@end
@implementation User
@end
User 라는 모델을 만들었습니다.
만약에 primaryKey 가 필요하다면,
// Define your models
@interface User : RLMObject
@property NSString *id;
@property NSString *name;
@property NSInteger age;
@end
@implementation User
+ (NSString *)primaryKey {
return @"id";
}
@end
참고1
처음에 primaryKey 없이 사용하다가 데이터가 들어가 있는 상태에서 primaryKey 를 추가하면 오류가 발생합니다.
기존에 있던 데이터들에 primaryKey 를 넣을 수 없기 때문이죠. (하단에 Migration 링크 참조)
참고2
auto-incrementing property 는 없다고 합니다. UUID 를 사용하면 될거같아요.
Auto-incrementing properties: Realm has no mechanism for thread-safe/process-safe auto-incrementing properties commonly used in other databases when generating primary keys. However, in most situations where a unique auto-generated value is desired, it isn’t necessary to have sequential, contiguous, integer IDs. A unique string primary key is typically sufficient. A common pattern is to set the default property value to NSUUID().UUIDString to generate unique string IDs.
Another common motivation for auto-incrementing properties is to preserve order of insertion. In some situations, this can be accomplished by appending objects to a List or by using a createdAt property with a default value of Date().
Default property values
@implementation User
+ (NSDictionary *)defaultPropertyValues {
return @{@"age" : @10, @"name": @""};
}
@end
Required ( = Not Null ) 설정
@implementation User
+ (NSArray *)requiredProperties {
return @[@"id", @"name"];
}
@end
Index 설정
@implementation User
+ (NSArray *)indexedProperties {
return @[@"name"];
}
@end
커스텀 함수
@implementation User
- (NSString *)name {
return [NSString stringWithFormat:@"%@ %li", self.name, self.age];
}
@end
Realm file 초기화 ( 전체 초기화 )
NSError *error = nil;
[RLMRealm deleteFilesForConfiguration:[RLMRealmConfiguration defaultConfiguration] error:&error];
if (error) {
NSLog(@"%@", error);
}
입력할 데이터 준비
User *user = [[User alloc] init];
user.id = [[NSUUID UUID] UUIDString];
user.name = @"hello";
user.age = 10;
다른 방법
// init with value
User *user = [[User alloc] initWithValue:@{@"id": [[NSUUID UUID] UUIDString], @"name": @"bryan", @"age": @20}];
입력 (addObject)
// 입력
[realm beginWriteTransaction];
[realm addObject:user];
[realm commitWriteTransaction];
다른 방법
[realm transactionWithBlock:^{
[realm addObject:user];
}];
조회
// 전체 데이터 조회
RLMResults<User *> *allUsers = [User allObjects];
NSLog(@"Number of all users: %li", (unsigned long)allUsers.count);
// 조건 조회
RLMResults *results = [User objectsInRealm:realm where:@"age > 5"];
NSLog(@"Number of users: %li", (unsigned long)results.count);
// 객체 탐색
for(User *user in results){
NSLog(@"name = %@, age = %li", user.name, user.age);
}
Operators
- ==, <=, <, >=, >, !=, BETWEEN 은 int, long, long long, float, double, NSDate 타입에서 사용할 수 있음
- ==, != 은 정확한 값 비교. 예) [Employee objectsWhere:@"company == %@", company]
- NSString, NSData 는 ==, !=, BEGINSWITH, CONTAINS, ENDSWITH 를 사용할 수 있음.
- LIKE 도 사용할 수 있는데, 와일드 카드로 * 과 ? 가 있습니다. * 은 mysql의 % 와 같고, ? 는 _ 와 같습니다.
예) value LIKE '?bc*' 는 앞의 어떤 한글자가 있고 두번째,세번째 값은 bc 이고 뒤에 무엇이 있든지 조회함. - compound operators : AND, OR, NOT
- IN : name IN {'Lisa', 'Spike', 'Hachi'}
- nil 도 사용 가능 : 예) [Company objectsWhere:@"ceo == nil"]
- ANY 가능 : 예) ANY student.age < 21 나이가 21세 미만인 데이터가 하나라도 존재하면 true
- 집합 표현 : @count, @min, @max, @sum, @avg : 예) [Company objectsWhere:@"employees.@count > 5"]
subquery 사용 예) SUBQUERY(…).@count
objectsWhere 의 더많은 참고 링크
정렬
RLMResults *results = [[User objectsInRealm:realm where:@"age > 5"] sortedResultsUsingKeyPath:@"age" ascending:YES];
LIMIT
limit 는 없습니다. Realm 은 lazy Query 기 때문에, for문을 사용하면 됩니다. 성능상 전혀 문제가 없습니다.
예를들어, 5개만 가져오려면, for 문을 5번만 돌면 됩니다.
RLMResults<User *> *users = [User allObjects];
for (NSInteger i = 0; i < 5; i++) {
User *user = users[i];
// ...
}
업데이트 (다른 쓰레드에서)
// 다른 쓰레드에서 업데이트
dispatch_async(dispatch_queue_create("background", 0), ^{
@autoreleasepool {
User *user = [[User objectsWhere:@"name contains 'bryan'"] firstObject];
NSLog(@"bryan's id is %@", user.id);
RLMRealm *realm = [RLMRealm defaultRealm];
[realm beginWriteTransaction];
user.age = 30;
[realm commitWriteTransaction];
}
});
이름이 bryan 을 포함하는 것들 중 첫번째 항목에서 age 를 30 으로 변경합니다.
조회된 데이터가 없다면, NSLog 는 다음과 같이 출력 됩니다.
bryan's id is (null)
삭제
단건 삭제
// Delete an object with a transaction
[realm beginWriteTransaction];
[realm deleteObject:[[allUsersByAge objectsWhere:@"name == 'hello'"] firstObject]];
[realm commitWriteTransaction];
여러건 삭제
[realm transactionWithBlock:^{
[realm deleteObjects:[allUsersByAge objectsWhere:@"age < 20"]];
}];
전체 삭제
[realm beginWriteTransaction];
[realm deleteAllObjects];
[realm commitWriteTransaction];
여기까지, 기본적인 사용법이었습니다.
테스트 했던, 전체 소스
#import "ObjcTestController.h"
#import <Realm/Realm.h>
// Define your models
@interface User : RLMObject
@property NSString *id;
@property NSString *name;
@property NSInteger age;
@end
@implementation User
+ (NSString *)primaryKey {
return @"id";
}
@end
@interface ObjcTestController ()
@end
@implementation ObjcTestController
- (void)viewDidLoad {
[super viewDidLoad];
// NSError *error = nil;
// [RLMRealm deleteFilesForConfiguration:[RLMRealmConfiguration defaultConfiguration] error:&error];
// if (error) {
// NSLog(@"%@", error);
// }
User *user = [[User alloc] init];
user.id = [[NSUUID UUID] UUIDString];
user.name = @"hello";
user.age = 10;
NSLog(@"User Name: %@", user.name);
RLMRealm *realm = [RLMRealm defaultRealm];
// 입력
[realm beginWriteTransaction];
[realm addObject:user];
[realm commitWriteTransaction];
User *userInit = [[User alloc] initWithValue:@{@"id": [[NSUUID UUID] UUIDString], @"name": @"bryan", @"age": @20}];
// 다른 방법의 transaction
[realm transactionWithBlock:^{
[realm addObject:userInit];
}];
// 조회
RLMResults *results = [User objectsInRealm:realm where:@"age > 5"];
NSLog(@"Number of users: %li", (unsigned long)results.count);
// 전체
RLMResults<User *> *allUsers = [User allObjects];
NSLog(@"Number of all users: %li", (unsigned long)allUsers.count);
RLMResults<User *> *allUsersByAge = [allUsers sortedResultsUsingKeyPath:@"age" ascending:YES];
for(User *user in allUsersByAge){
NSLog(@"name = %@, age = %li", user.name, user.age);
}
NSLog(@"Number of all users: %li", (unsigned long)allUsersByAge.count);
// Delete an object with a transaction
[realm beginWriteTransaction];
[realm deleteObject:[[allUsersByAge objectsWhere:@"name == 'hello'"] firstObject]];
[realm commitWriteTransaction];
NSLog(@"Number of all users after delete : %li", (unsigned long)allUsersByAge.count);
[realm transactionWithBlock:^{
[realm deleteObjects:[allUsersByAge objectsWhere:@"age < 20"]];
}];
// // Delete all objects from the realm
// [realm beginWriteTransaction];
// [realm deleteAllObjects];
// [realm commitWriteTransaction];
// 다른 쓰레드에서 업데이트
dispatch_async(dispatch_queue_create("background", 0), ^{
@autoreleasepool {
User *user = [[User objectsWhere:@"name contains 'bryan'"] firstObject];
NSLog(@"bryan's id is %@", user.id);
RLMRealm *realm = [RLMRealm defaultRealm];
[realm beginWriteTransaction];
user.age = 30;
[realm commitWriteTransaction];
}
});
}
@end
참고 1
예제 소스에 있는 User 는 여러군데에서 사용될 수 있으니 따로 빼도록 합니다.
1. New Group 생성 (예제에서는 명칭은 Models 로 합니다.)
2. 생성된 group 에서 New File 클릭 > Header File 생성
3. Models/User.h 파일 내용
//
// User.h
// RealmTest
//
// Created by USER on 2022/02/05.
//
#ifndef User_h
#define User_h
// Define your models
@interface User : RLMObject
@property NSString *id;
@property NSString *name;
@property NSInteger age;
@end
@implementation User
+ (NSString *)primaryKey {
return @"id";
}
@end
#endif /* User_h */
4. ObjcTestController.m 에서
참고 2
'IOS (Swift, Objective-c)' 카테고리의 다른 글
[IOS] Objective-C Realm 사용 RLMArray 써보기 (0) | 2022.02.06 |
---|---|
[Objective-C] 기초부터 앱개발까지 (별도 클래스, 함수 파일만들기) (0) | 2022.02.05 |
[IOS] CocoaPod 설치. 프로젝트 설정하기 (0) | 2022.02.05 |
[IOS] Objective-c, Swift 혼합 프로젝트 (0) | 2022.02.05 |
[IOS] Showing All MessagesUndefined symbol: _OBJC_CLASS_$_AVPlayerViewController (0) | 2021.09.28 |
댓글