RealmSwift
官方文档
https://www.mongodb.com/docs/realm/sdk/swift/
realmswift存储和sql存储使用上最大的区别是,realmswift可以直接将对象存储,无需写sql建表,建索引。
它将数据存储为一个文档,数据结构由键值(key=>value)对组成。也就是说能以对象的形式进行存储。
model编写
1、object model不能使用struct
2、model必须继承Object或EmbeddedObject
3、对象必须要加前缀@Persisted
4、如果是Object类型,而且需要写入、删除、添加操作的话,要加主键@Persisted(primaryKey: true)
5、数组array必须要用realmswift.List<element>
6、如果更改数组后没更新版本或者没重装app,不执行do内容
$R1 = "Migration is required due to the following errors:\n- Property ‘Person.name’ has been added
7、不能多个对象引用同一个对象
报的错误类似Thread 1: “Attempting to create an object of type ‘Person’ with an existing primary key value ‘A’.”
数据写入
1、任何读操作都得是在这里执行
do {
let realm = try Realm()
let personList = realm.objects(Person.self)
}
2、如果是需要写的操作,就必须在这里执行,保证原子性。
do {
let realm = try Realm()
try realm.write({
// 报错原因 浅拷贝,地址都是一样的,指向的内容也是一样的,因此不能add上去
realm.add(person)
// realm.add(anotherPerson)
})
let personList = realm.objects(Person.self)
}
let personList = realm.objects(Person.self)
这只是引用地址,如果后面有写的操作,会直接报错。
报错源码:Thread 1: “Attempting to modify object outside of a write transaction - call beginWriteTransaction on an RLMRealm instance first.”
3、如果你在本地里打开文件(Realm studio),运行不执行try realm.write
。如果把try去掉会直接报错
4、add
添加数据库的时候,realm.add(person,update: .modified)
如果没设置主键会直接报错
Thread 1: “‘Person’ does not have a primary key and can not be updated”
.add(person,update: .modified)
是如果主键一致的话,修改里面的内容,主键不一样的话,添加新的数据。
技术点
Realm.Configuration
对数据库的深度定制
一般使用这个
var config = Realm.Configuration(fileURL: ,
encryptionKey: ,
schemaVersion: ,
migrationBlock: )
fileURL存储的位置,一般是存储document里,
encryptionkey 密钥
schemaVersion 更新model参数时需要在这+1
migrationBlock 初始化后如果需要对数据进行操作的回调,也可以在闭包里对model更改的数据进行操作。
当需要删除表时,如果都是使用Object作为model的话,删除的只是当前对象的基础类型参数。如果引用了其他的Object类型的model作为参数,该参数的信息依旧保留,不会链式删除。
如果想删除当前Object,并且删除以对象形式的参数,该参数的model应为EmbeddedObject
。
配合网络请求
ObjectMapper
直接看demo代码吧
public class DiningPartnerList: Object, Mappable {
@Persisted(primaryKey: true) var primaryKey = 1
@Persisted public var brands = List<DiningPartnerItem>()
public override init() {}
required public init?(map: ObjectMapper.Map) {
}
public func mapping(map: ObjectMapper.Map) {
brands <- (map["brands"], ListTransformWithEmbeddedObject<DiningPartnerItem>())
}
}
DiningPartnerItem.swift
public class DiningPartnerItem: EmbeddedObject, Mappable {
@Persisted public var id: String?
@Persisted public var name: String?
@Persisted public var isNewBrand: Bool = false
@Persisted public var isOnlineStore: Bool = false
public override init() {}
required public init?(map: ObjectMapper.Map) {
}
public func mapping(map: ObjectMapper.Map) {
id <- map["id"]
name <- map["name"]
isNewBrand <- map["new_brand"]
isOnlineStore <- map["is_online_store"]
}
}
ListTransformWithEmbeddedObject
是array转换List的过程。这个是EmbeddedObject
类型,如果想要Object
类型的话
将
public struct ListTransformWithEmbeddedObject<T: RealmSwift.EmbeddedObject>: TransformType where T: BaseMappable
改成
public struct ListTransformWithObject<T: RealmSwift.Object>: TransformType where T: BaseMappable
代码是从github那里搬下来的
public struct ListTransformWithEmbeddedObject<T: RealmSwift.EmbeddedObject>: TransformType where T: BaseMappable {
public init() { }
public typealias ListObject = List<T>
public typealias ListJSON = [Any]
public func transformFromJSON(_ value: Any?) -> List<T>? {
if let objects = Mapper<T>().mapArray(JSONObject: value) {
let list = List<T>()
list.append(objectsIn: objects)
return list
}
return nil
}
static public func arrayToList<T>() -> TransformOf<List<T>, [T]> {
return TransformOf(
fromJSON: { (value: [T]?) -> List<T> in
let result = List<T>()
if let value = value {
result.append(objectsIn: value)
}
return result
},
toJSON: { (value: List<T>?) -> [T] in
var results = [T]()
if let value = value {
results.append(contentsOf: Array(value))
}
return results
})
}
public func transformToJSON(_ value: ListObject?) -> ListJSON? {
return value?.compactMap { $0.toJSON() }
}
}
codable
RealmSwift的list已经支持Codable,这是 List.swift
文件的源码,如果是数组只需要使用list<element>
就行
// MARK: - Codable
extension List: Decodable where Element: Decodable {
public convenience init(from decoder: Decoder) throws {
self.init()
var container = try decoder.unkeyedContainer()
while !container.isAtEnd {
append(try container.decode(Element.self))
}
}
}
extension List: Encodable where Element: Encodable {}
demo
class ColorList: Object, Codable {
@Persisted var color: List<MyColor>
enum CodingKeys: String, CodingKey {
case color = "xxxcolor"
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(color, forKey: .color)
}
}
class MyColor: EmbeddedObject, Codable {
@Persisted var name: String?
@Persisted var hexColor: String?
enum CodingKeys: String, CodingKey {
case name, hexColor
}
}
原文地址:https://blog.csdn.net/SCDNBB
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。