ios realm 文件_Realm在iOS上的使用

本文详细介绍了 Realm 在 iOS 上的应用,包括数据库的创建、增删改查操作,以及如何处理数据库的迁移。 Realm 不仅提供了方便的建表和查询方式,还支持数据库的加密和线性迁移策略,是移动平台上的强大数据库解决方案。
部署运行你感兴趣的模型镜像

[Realm]是由美国YCombinator孵化的创业团队历时几年打造,第一个专门针对移动平台设计的数据库*

[Realm]是一个跨平台的移动数据库引擎,目前支持iOS、Android平台,同时支持Objective-C、Swift、Java、React Native、Xamarin等多种编程语言* Realm并不是对SQLite或者CoreData的简单封装, 是由核心数据引擎C++打造,是拥有独立的数据库存储引擎,可以方便、高效的完成数据库的各种操作

Realm 数据库是 Realm 移动端数据库容器的一个实例。Realm 数据库可以是本地化的,也可以是可同步的。目前我研究的只是本地化的数据库。

看到这个realm的时候,我就想到了go/python语言中使用的第三方框架数据库xorm,它的表的创建方法跟realm简直是一模一样,同样是利用model来生成对应的表结构,唯一不同的是在移动端(iOS)上创建表的时候必须要生成一个主键,而xorm主键不是必须的。

realm在iOS上基本用法:数据库的创建、增删改查等操作

数据库创建:设置数据库所在的文件目录以及数据库的名称

(void)setDefaultRealmForUser:(NSString *)userName{

RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];

//使用默认的目录,使用用户名来替换默认的文件名

config.fileURL = [[[config.fileURL URLByDeletingLastPathComponent]URLByAppendingPathComponent:userName]URLByAppendingPathExtension:@"realm"];

NSString *version = [[NSUserDefaults standardUserDefaults] objectForKey:[NSString stringWithFormat:@"%@:%@",userName,@"ormVersion"]];

if (version.integerValue) {

config.schemaVersion = version.integerValue;

}

if (self.isSecu) {

config.encryptionKey = [self randomSec:userName];

}

//将这个配置应用到默认的realm数据库中

[RLMRealmConfiguration setDefaultConfiguration:config];

if (realm == nil) {

realm = [RLMRealm realmWithConfiguration:config error:nil];

}

}

数据库的添加或者更新(用事务来处理):

(void)realmAdd_UpdateObject:(id)object

{

[realm beginWriteTransaction];

[realm addOrUpdateObject:object];

[realm commitWriteTransaction];

}

数据库的删除(单个删除,全部删除):

(void)realmDeleteObject:(id)object

{

[realm beginWriteTransaction];

Class objectClass = [object class];

object = [objectClass createOrUpdateInRealm:realm withValue:object];

[realm deleteObject:object];

[realm commitWriteTransaction];

}

这里需要注意一点的是删除的对象必须要是realm数据库所管理的,否则会发生错误,导致程序不能继续运行;所以在删除之前我们可以再次创建这个删除更新下这个对象的实例:

object = [objectClass createOrUpdateInRealm:realm withValue:object];

看方法故名思义是不存在就创建,存在就更新,生成一个新的对象;这样这个要删除的对象就是被realm所管理。

数据的查询:分为精确查询和模糊查询

其实我看重这个框架的除了建表以及查询方便,最主要的是数据库的迁移也很方便,目前数据库的迁移分为以下几种:

1、值的更新

example: [migration enumerateObjects:Person.className

block:^(RLMObject *oldObject, RLMObject *newObject) {

// 将两个 name 合并到 fullName 当中

newObject[@"fullName"] = [NSString stringWithFormat:@"%@ %@",

oldObject[@"firstName"],

oldObject[@"lastName"]];

}];

2、属性的重命名

example: if (oldSchemaVersion < 1) {

// 重命名操作必须要在 enumerateObjects: 调用之外进行

[migration renamePropertyForClass:Person.className oldName:@"yearsSinceBirth" newName:@"age"];

}

3、线性迁移

example: 假如说,我们的应用有两个用户: JP 和 Tim。JP 经常更新应用,但 Tim 却经常跳过某些版本。所以 JP 可能下载过这个应用的每一个版本,并且一步一步地跟着更新构架:第一次下载更新后,数据库架构从 v0 更新到 v1;第二次架构从 v1 更新到 v2…以此类推,井然有序。相反,Tim 很有可能直接从 v0 版本直接跳到了 v2 版本。 因此,您应该使用非嵌套的 if (oldSchemaVersion < X) 结构来构造您的数据库迁移模块,以确保无论用户在使用哪个版本的架构,都能完成必需的更新。

*/

RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];

if (self.isSecu) {

config.encryptionKey = [self randomSec:userName];

}

//使用默认的目录,使用用户名来替换默认的文件名

config.fileURL = [[[config.fileURL URLByDeletingLastPathComponent]URLByAppendingPathComponent:userName]URLByAppendingPathExtension:@"realm"];

// 1. 设置新的架构版本。这个版本号必须高于之前所用的版本号(如果您之前从未设置过架构版本,那么这个版本号设置为 0)

NSInteger newVersion = version.integerValue;

config.schemaVersion = newVersion;

[[NSUserDefaults standardUserDefaults] setObject:version forKey:[NSString stringWithFormat:@"%@:%@",userName,@"ormVersion"]];

[[NSUserDefaults standardUserDefaults] synchronize];

// 2. 设置闭包,这个闭包将会在打开低于上面所设置版本号的 Realm 数据库的时候被自动调用

[config setMigrationBlock:^(RLMMigration *migration, uint64_t oldSchemaVersion){

if (oldSchemaVersion < newVersion) {

if (block) {

block(migration,oldSchemaVersion);

}

}

}];

[RLMRealmConfiguration setDefaultConfiguration:config];

[RLMRealm defaultRealm];

如果要求数据安全的话,可以对数据库进行加密,Realm 支持在创建 Realm 数据库时采用64位的密钥对数据库文件进行 AES-256+SHA2 加密。这样硬盘上的数据都能都采用AES-256来进行加密和解密,并用 SHA-2 HMAC 来进行验证。 每次您要获取一个 Realm 实例时,您都需要提供一次相同的密钥。下面给出一段demo给出的生成随机密钥的方法:

(NSData *)randomSec:(NSString *)indentify

{

NSString *str = [indentify stringByAppendingFormat:@"%@",[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"]];

const char *kKeychainIdentifier = [str UTF8String];

NSData *tag = [[NSData alloc] initWithBytesNoCopy:(void *)kKeychainIdentifier

length:sizeof(kKeychainIdentifier)

freeWhenDone:NO];

// First check in the keychain for an existing key

NSDictionary *query = @{(__bridge id)kSecClass: (__bridge id)kSecClassKey,

(__bridge id)kSecAttrApplicationTag: tag,

(__bridge id)kSecAttrKeySizeInBits: @512,

(__bridge id)kSecReturnData: @YES};

CFTypeRef dataRef = NULL;

OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &dataRef);

if (status == errSecSuccess) {

return (__bridge NSData *)dataRef;

}

uint8_t buffer[64];

status = SecRandomCopyBytes(kSecRandomDefault, 64, buffer);

NSAssert(status == 0, @"Failed to generate random bytes for key");

NSData *keyData = [[NSData alloc] initWithBytes:buffer length:sizeof(buffer)];

// Store the key in the keychain

query = @{(__bridge id)kSecClass: (__bridge id)kSecClassKey,

(__bridge id)kSecAttrApplicationTag: tag,

(__bridge id)kSecAttrKeySizeInBits: @512,

(__bridge id)kSecValueData: keyData};

status = SecItemAdd((__bridge CFDictionaryRef)query, NULL);

NSAssert(status == errSecSuccess, @"Failed to insert new key in the keychain");

return keyData;

}

后续会对远程数据库连接处理以及model模型之间套用了解。

您可能感兴趣的与本文相关的镜像

Stable-Diffusion-3.5

Stable-Diffusion-3.5

图片生成
Stable-Diffusion

Stable Diffusion 3.5 (SD 3.5) 是由 Stability AI 推出的新一代文本到图像生成模型,相比 3.0 版本,它提升了图像质量、运行速度和硬件效率

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值