Closed stel closed 8 years ago
The trace shows that somehow the user is calling set_bool on a column which is actually of type col_type_LinkList (13) in the middle of a migration. Assuming the object store is updating column indices correctly during a migration then this is either a bug or corruption somewhere from core. Really difficult to progress without more info about how to reproduce this so I am going to mark as waiting for user.
If the user is willing to provide any more information, it would be interesting to see the user's model before and after the migration and the migration code. Maybe there is some combination of structural changes in the migration that could cause this.
User replied:
Before migration
class Follower: Object {
dynamic var id = ""
dynamic var mainUserID = ""
dynamic var username = ""
dynamic var strProfileURL = ""
dynamic var isFollowingMe = false
override class func primaryKey() -> String {
return "id"
}
}
class Following: Object {
dynamic var id = ""
dynamic var mainUserID = ""
dynamic var username = ""
dynamic var strProfileURL = ""
override class func primaryKey() -> String {
return "id"
}
}
class User: Object {
dynamic var id = ""
dynamic var username = ""
dynamic var email = ""
dynamic var fullName = ""
dynamic var token = ""
dynamic var strURLImageProfile = ""
dynamic var phoneNumber = ""
dynamic var bio = ""
dynamic var lastMomentCaptionImageURL = ""
dynamic var totalListners = 0
dynamic var totalMoments = 0
dynamic var totalFollowers = 0
dynamic var totalFollowings = 0
dynamic var totalWhispers = 0
dynamic var totalLovedWhispers = 0
dynamic var totalPartiedWhispers = 0
dynamic var totalChilledWhispers = 0
dynamic var isFacebookConnected = false
dynamic var isTwitterConnected = false
// dynamic var type = UserType.Normal.hashValue // added to check user is me, of featured user or some other user
dynamic var isFollowing = false // added to check featured user is being followed by me of not
dynamic var index = 0
internal let toAccount = List<Account>()
internal var toUser: User {
return linkingObjects(User.self, forProperty: "featureUser").first!
}
internal let featureUser = List<User>()
override class func primaryKey() -> String {
return "id"
}
}
class Moment: Object {
dynamic var id = ""
dynamic var visibility = ""
dynamic var isActive = false
dynamic var captionImageUrl = ""
dynamic var playlistID = ""
dynamic var userID = ""
dynamic var userImageUrl = ""
dynamic var userFullName = ""
dynamic var userUsername = ""
dynamic var captionMessage = ""
dynamic var createdTime = NSDate()
dynamic var noOfWhispers = 0
dynamic var noOfListeners = 0
dynamic var noOfMaxListeners = 0
dynamic var noOfWebListeners = 0
dynamic var hasReported = false
dynamic var hasReportedBy3 = false
override class func primaryKey() -> String {
return "id"
}
}
class Playlist: Object {
dynamic var name = ""
//dynamic var songs = RLMArray(objectClassName: Song.className())
}
class Song: Object {
dynamic var id = ""
dynamic var name = ""
dynamic var albumImageURL = ""
dynamic var albumName = ""
dynamic var artistImageURL = ""
dynamic var artistName = ""
dynamic var order = 0
dynamic var mnetID = 0
dynamic var locationURL = ""
dynamic var locationURL_mp4 = ""
dynamic var iTunesURL = ""
override class func primaryKey() -> String {
return "id"
}
}
class Account: Object {
dynamic var id = ""
dynamic var type = AccountType.Mumo.rawValue
dynamic var accessToken = ""
dynamic var accessSecret = ""
dynamic var userID = ""
dynamic var isMainAccount = false
internal var toUser: User {
return linkingObjects(User.self, forProperty: "toAccount").first!
}
override class func primaryKey() -> String {
return "id"
}
// Specify properties to ignore (Realm won't persist these)
// override static func ignoredProperties() -> [String] {
// return []
// }
}
AFTER MIGRATION
class User: Object {
dynamic var id = ""
dynamic var username = ""
dynamic var email = ""
dynamic var fullName = ""
dynamic var token = ""
dynamic var profileImageURL = ""
dynamic var phoneNumber = ""
dynamic var bio = ""
dynamic var lastMomentCaptionImageURL = ""
dynamic var totalListners = 0
dynamic var totalMoments = 0
dynamic var totalFollowers = 0
dynamic var totalFollowings = 0
dynamic var totalWhispers = 0
dynamic var totalLovedWhispers = 0
dynamic var totalPartiedWhispers = 0
dynamic var totalChilledWhispers = 0
dynamic var isFollowingUser = false
dynamic var blocked = false
dynamic var isFacebookConnected = false
dynamic var isTwitterConnected = false
//TODO: remove this
internal let toAccount = List<Account>()
var followers = List<User>()
var following = List<User>()
var suggestedUsers = List<User>()
var whispers = List<Song>()
override class func primaryKey() -> String {
return "id"
}
}
class Session: Object {
dynamic var id = ""
dynamic var token = ""
dynamic var isFacebookConnected = false
dynamic var isTwitterConnected = false
dynamic var twitterLogin = false
dynamic var currentUser: User?
override static func primaryKey() -> String? {
return "id"
}
}
class Moment: Object {
dynamic var id = ""
dynamic var visibility = ""
dynamic var isActive = false
dynamic var captionImageUrl = ""
dynamic var playlistID = ""
dynamic var captionMessage = ""
dynamic var createdTime = NSDate()
dynamic var noOfWhispers = 0
dynamic var noOfListeners = 0
dynamic var noOfMaxListeners = 0
dynamic var noOfWebListeners = 0
dynamic var hasReported = false
dynamic var hasReportedBy3 = false
dynamic var commentsCount = 0
dynamic var user: User?
var songs = List<Song>()
var whispers = List<Whisper>()
var comments = List<Comment>()
var listeners = List<User>()
override class func primaryKey() -> String {
return "id"
}
}
class Song: Object {
dynamic var id = ""
dynamic var name = ""
dynamic var albumImageURL = ""
dynamic var albumName = ""
dynamic var artistImageURL = ""
dynamic var artistName = ""
dynamic var order = 0
dynamic var mnetID = 0
dynamic var locationURL = ""
dynamic var locationURL_mp4 = ""
dynamic var iTunesURL = ""
dynamic var songURL = ""
dynamic var durationInMS = 0
dynamic var startAt: Double = 0
dynamic var duration = 0
override class func primaryKey() -> String {
return "id"
}
}
class Whisper: Object {
dynamic var id = ""
dynamic var type: String = ""
dynamic var label: String = ""
dynamic var createdTime = NSDate()
dynamic var user: User?
dynamic var song: Song?
override class func primaryKey() -> String {
return "id"
}
}
class Comment: Object {
dynamic var id = ""
dynamic var caption: String = ""
dynamic var user: User?
dynamic var createdTime = NSDate()
override class func primaryKey() -> String {
return "id"
}
}
MIGRATION BLOCK WRITTEN
Realm.Configuration.defaultConfiguration = Realm.Configuration(
schemaVersion: 7,
migrationBlock: { migration, oldSchemaVersion in
migration.enumerate(User.className()) { oldObject, newObject in
if oldSchemaVersion == 4 {
// migration.deleteData(User.className())
if let object1 = newObject {
migration.renamePropertyForClass(User.className(), oldName: "isFollowing", newName: "isFollowingUser")
migration.renamePropertyForClass(User.className(), oldName: "strURLImageProfile", newName: "profileImageURL")
// object1["isFollowingUser"] = object["isFollowing"]
// object1["profileImageURL"] = object["strURLImageProfile"]
object1["blocked"] = false
object1["followers"] = []
object1["following"] = []
object1["suggestedUsers"] = []
object1["whispers"] = []
}
}
if oldSchemaVersion == 4 {
if let object = oldObject {
if let oldToken = object["token"] as? String {
if oldToken != "" {
if let oldUserID = object["id"] {
//TODO: call api passing token and userid
Session.addOldOne(["_id":oldUserID, "token":oldToken])
//TODO: check following api. gettting "Please login in order to use this resource."
//i think access token is not valid in this new environment
store.dispatch(actionGetUser(oldUserID as! String, disposeBag: self.disposeBag))
}
}
}
}
}
}
// The enumerateObjects:block: method iterates
// over every 'Moment' object stored in the Realm file
migration.enumerate(Moment.className()) { oldObject, newObject in
if oldSchemaVersion == 4{
// migration.deleteData(Moment.className())
if let object = oldObject, let object1 = newObject {
if let momentOwnerId = object["userID"] as? String {
let user = User.findOne(momentOwnerId)
object1["user"] = user
}
object1["commentsCount"] = 0
object1["songs"] = []
object1["comments"] = []
object1["whispers"] = []
object1["listeners"] = 0
}
}
}
migration.enumerate(Session.className()) { oldObject, newObject in
if oldSchemaVersion < 6 {
newObject!["twitterLogin"] = false;
}
}
migration.enumerate(Song.className()) { oldObject, newObject in
// Add the `durationInMS` 'startAt' property to Realms with a schema version of 2 or 2
if oldSchemaVersion < 2 {
newObject!["durationInMS"] = 0
newObject!["startAt"] = 0
}
if oldSchemaVersion < 3 {
newObject!["startAt"] = oldObject!["startAt"]
}
if oldSchemaVersion == 4 {
if let object = oldObject, let object1 = newObject {
object1["songURL"] = ""
object1["durationInMS"] = 0
object1["startAt"] = 0
object1["duration"] = 0
}
}
}
migration.enumerate(Whisper.className()) { oldObject, newObject in
if oldSchemaVersion < 6 {
newObject!["song"] = Song();
}
}
})
object1["listeners"] = 0
may cause this error, as Moment.listeners
is List<User>()
.
@stel The error you pointed out is the user's mistake, and could explain the stack trace. Can we close this issue?
User didn't respond to my previous message, I'll ask him again. Anyway it's definitely the user's error, so yeah, will close this issue.
Cocoa user reported this on Help Scout: https://secure.helpscout.net/conversation/210617274/4683