0
votes

I am using CoreData in my application. I created an entity which has two attributes. One is Int type and second one is Transformable Type. I am able to save my record successfully. But when I try to fetch, It get crash. And one more thing, everything is working fine without using Transformable type. What could be the reason? Is that Transformable Type? And If yes then what is the solution?

func saveUserInfoInDatabase(userDetails: FleetInfoDetails) {
    self.deleteUserInfoFromDatabase()
    let entityDescription = NSEntityDescription.entityForName("UserInfo", inManagedObjectContext: self.userInfoObjectContext)
    let data = UserInfo(entity: entityDescription!, insertIntoManagedObjectContext: self.userInfoObjectContext)
    print(userDetails)
    data.info = userDetails
    data.sync = 1
    do {
        try self.userInfoObjectContext.save()
    } catch {
        fatalError("Failure to save context: \(error)")
    }
}

func deleteUserInfoFromDatabase() {
    let fetchRequest = NSFetchRequest(entityName: "UserInfo")
    if #available(iOS 9.0, *) {
        let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
        do {
            try DatabaseManager.sharedInstance.persistentStoreCoordinator.executeRequest(deleteRequest, withContext: self.userInfoObjectContext)
            do {
                try self.userInfoObjectContext.save()
            } catch {
                let saveError = error as NSError
                print(saveError)
            }
        } catch let error as NSError {
            let saveError = error as NSError
            print(saveError)
        }
    } else {
        // Fallback on earlier versions
    }
}

func fetchUserInfoFromDatabase(){
    let request = NSFetchRequest(entityName: "UserInfo")
    do {
        let results = try self.userInfoObjectContext.executeFetchRequest(request) as? [UserInfo] //Getting crash here
        if results!.count > 0 {

        }else{
            print("0 results or potential error")
        }
    } catch {
        let saveError = error as NSError
        print(saveError)
    }
}

I am assigning following object class to Transformable attirbute.

class FleetInfoDetails: NSObject {

var fleetId: Int!
var fleetImage: String!
var accessToken: String!
var email: String!
var phone: String!
var password: String!
var name: String!
var teams: Array<AssignedTeamDetails>?

func encodeWithCoder(_aCoder: NSCoder) {   }
func initWithCoder(aCode:NSCoder) {

}

init(json: NSDictionary) {

    if let fleetId = json["fleet_id"] as? Int {
        self.fleetId = fleetId
    }
    if let fleetImage = json["fleet_image"] as? String {
        if fleetImage.isEmpty{
            self.fleetImage = nil
        }
        self.fleetImage = fleetImage
    }
    if let accessToken = json["access_token"] as? String {
        if accessToken.isEmpty{
            self.accessToken = nil
        }
        self.accessToken = accessToken
    }
    if let email = json["email"] as? String {
        if email.isEmpty{
            self.email = nil
        }
        self.email = email
    }

    if let phone = json["phone"] as? String {
        if phone.isEmpty{
            self.phone = nil
        }
        self.phone = phone
    }
    if let password = json["password"] as? String {
        if password.isEmpty{
            self.password = nil
        }
        self.password = password
    }

    if let name = json["name"] as? String {
        if name.isEmpty{
            self.name = nil
        }
        self.name = name
    }

    if let items = json["teams"] as? NSArray{
        if items.count == 0{
            teams = [AssignedTeamDetails]()
        } else {
            teams = [AssignedTeamDetails]()
        }
        for item in items{
            if let team = AssignedTeamDetails(json: item as! NSDictionary) as AssignedTeamDetails! {
                teams?.append(team)
            }
        }
    }
 }
1
What error do you see in the debug console? What does the (symbolicated!) stack look like when you crash?Phillip Mills
EXC_BAD_ACCESS. There is nothing on debug console. And Where I get symbolicated stack look?Rox
What kind of value are you assigning to the transformable attribute? Does it conform to NSCoding?Tom Harrington
@TomHarrington I edited my question with object.Rox
Why do you not post the console message when you state there is a crash? At least set an exception breakpoint to find out where the crash is occurring.Fogmeister

1 Answers

0
votes

I just fight and fight and finally achieved it. Here is My solution:

class FleetInfoDetails: NSObject, NSCoding {

var fleetId: Int!
var accessToken: String!

required init(coder aDecoder: NSCoder) {
    fleetId = aDecoder.decodeObjectForKey("fleetId") as! Int
    accessToken = aDecoder.decodeObjectForKey("accessToken") as! String
}

func encodeWithCoder(aCoder: NSCoder) {
    aCoder.encodeObject(fleetId, forKey: "fleetId")
    aCoder.encodeObject(accessToken, forKey: "accessToken")
}

init(json: NSDictionary) {

if let fleetId = json["fleet_id"] as? Int {
    self.fleetId = fleetId
}
if let accessToken = json["access_token"] as? String {
    if accessToken.isEmpty{
        self.accessToken = nil
    }
    self.accessToken = accessToken
}
}
}

I just added NSCoding in my object class. And then implemented required init() and encodeWithCode() methods. After that I used NSKeyedArchiver and NSKeyedUnarchiver to save and fetch data.

func saveUserInfoInDatabase(userDetails: FleetInfoDetails) {
    self.deleteUserInfoFromDatabase()
    let entityDescription = NSEntityDescription.entityForName("UserInfo", inManagedObjectContext: self.userInfoObjectContext)
    let data = UserInfo(entity: entityDescription!, insertIntoManagedObjectContext: self.userInfoObjectContext)
    data.info = NSKeyedArchiver.archivedDataWithRootObject(userDetails)
    data.sync = 1
    do {
       try self.userInfoObjectContext.save()
    } catch {
       fatalError("Failure to save context: \(error)")
    }
}

func fetchUserInfoFromDatabase(){
    let request = NSFetchRequest(entityName: "UserInfo")
    do {
      let results = try    self.userInfoObjectContext.executeFetchRequest(request) as? [UserInfo] 

    if results!.count > 0 {
       let userData = NSData(data: results?.first?.valueForKey("info") as! NSData)             
       let userDetails = NSKeyedUnarchiver.unarchiveObjectWithData(userData) as! FleetInfoDetails

    }else{
        print("0 results or potential error")
    }
} catch {
    let saveError = error as NSError
    print(saveError)
}
}

Hope it will help anyone. If there is any other solution please let me know.