iOS でRealm Swift を 利用し、サンプルを作成する際のトラブル内容と対応事項をメモします。
#目次
・ Realm Swift#1 class
・ Realm Swift#2 sample
・ Realm Swift#3 issue
動作環境
Swift 5.0
Xcode 11.1
トラブル一覧
1。レルムにデータ追加失敗の時
2。複数カラムのプライマリーキーが作成したい場合
3。 レルム取得する際にアプリクラッシュされる場合
#レルムにデータ追加失敗の時
class Student: Object {
@objc dynamic var studentId = ""
@objc dynamic var name = ""
@objc dynamic var age = 0
}
func add(obj :T) throws {
let realm = try! Realm()
try realm.write {
realm.add(obj, update: .modified)
}
}
下記のようにRLMExceptionエラーが起きる。
__理由 :__ `主キーが存在しないため、更新できません。` ##対応方法 ##対応① 主キーを設定すること。※注意:https://realm.io/docs/swift/3.20.0/#models
主キーを宣言すると、オブジェクトを効率的に検索および更新でき、
各値に一意性を適用できます。
主キーを持つオブジェクトをレルムに追加すると、
主キーは変更できなくなります。
override public static func primaryKey() -> String? {
return "studentId"
}
##対応②:主キーが設定できない場合
try realm.write {
//追加の場合
//realm.add(obj, update: .modified)
realm.add(obj)
}
let student = realm.getObjects.first
try realm.write {
//更新の場合
student?.name = "test"
student?.age = 20
}
複数カラムの主キーが作成したい場合
class Student: Object {
@objc dynamic var studentId = ""
@objc dynamic var age = 0
override public static func primaryKey() -> String? {
return String(format: "%@_%d ", studentId,age)
}
##対応: 主キー(customPrimaryKey)を新しく作成すること。
但し、不要な項目が追加されてしまう。
class Student: Object {
@objc dynamic var studentId = ""
@objc dynamic var age = 0
@objc dynamic var customPrimaryKey = ""
override public static func primaryKey() -> String? {
return "customPrimaryKey"
}
convenience init(studentId: String, age: Int) {
self.init()
self.studentId = studentId
self.age = age
self.customPrimaryKey = String(format: "%@_%d ", studentId,age)
}
レルム取得する際にアプリクラッシュされる場合
func updateOnly(block:() -> Void ) throws {
try realm.write(block)
}
原因 : 想定ですが、クロージャは解放されず、 レルムのトランザクションを完了されなっかた。
##対応: @ escapingを付与すること。
・クロージャが外部から渡される場合、@ escapingが必須らしい。
・非同期処理の後にクロージャを実行する場合は、
@ escaping を引数で受け取るクロージャに付与しなければなりません。
func updateOnly(block: @escaping () -> Void ) throws {
try realm.write(block)
}
##参考
https://realm.io/docs/swift/3.20.0/
@escapingと@autoclosure