QA@IT

Realm ループして値を追加できない

8733 PV

前提・実現したいこと

Realmにあらかじめデータが入っている前提でループ処理をしてRealmにあるデータを取り出した後に再度Realmにデータを一部だけ戻したい。


発生している問題・エラーメッセージ

再度Realmにデータを格納する際に、2個目以降のデータを格納するとエラーが発生する。

↓エラーコード

Terminating app due to uncaught exception 'RLMException', reason: 'Primary key can't be changed after an object is inserted.'


該当のソースコード

import UIKit
import RealmSwift

class ViewController: UIViewController {

    // Realm名前データ格納配列
    var realmname:[String] = []
    var id:Int = 1

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // ボタン押下後の処理
    @IBAction func tapButton(_ sender: Any) {
        let config = Realm.Configuration(deleteRealmIfMigrationNeeded: true)
        Realm.Configuration.defaultConfiguration = config

        let realm = try! Realm()

        // Realmにある名前をrealmnameに寄せておく    
        while true {
            if let playerbefore = realm.object(ofType: PlayerTable.self, forPrimaryKey: id as AnyObject)
            {
                realmname.append(playerbefore.name)
                id += 1
            }else{
                break
            }
        }

        // Realmデータ全削除
        try! realm.write {
            realm.deleteAll()
        }

        let playerafter:PlayerTable = PlayerTable()
        id = 0

        // realmnameに寄せた名前を再度Realmに格納  
        try! realm.write {
            while true {
                if realmname[id + 1] == "" {
                    break
                }
                playerafter.id = id + 1   // 2回目のループでここに来たときにエラーになる
                playerafter.name = realmname[id]
                realm.add(playerafter, update: true)
                id += 1
            }        
        }
    }
}
import Foundation
import RealmSwift

class PlayerTable: Object {

    dynamic var id = Int()
    dynamic var name = String()
    dynamic var point = Int()

    // nameをプライマリキーに設定
    override static func primaryKey() -> String? {
        return "id"
    }
}

補足情報(言語/FW/ツール等のバージョンなど)

Swift 3.1
Realm 1.2.1

ウォッチ

この質問への回答やコメントをメールでお知らせします。