简体   繁体   中英

Saving NSManagedObject in NSUserDefaults

Hello everyone (sorry for my bad english, I'm French),

I'm trying to put my NSManagedObject into NSUserDefaults to retrieve it with its relationships. Basically I used NSCoding and I had implemented the required method, but because it's NSManaged objects, the signature of the init method it's : init(entity: NSEntityDescription, insertIntoManagedObjectContext context: NSManagedObjectContext?).

The message is "'NSInvalidArgumentException', reason: 'Illegal attempt to establish a relationship 'shop' between objects in different contexts"

If I comment the line in Address : self.shop = shop , it's creating me my entity again and again..

This is my code :

To put the shop in NSUserDefaults :

let selectedShop = shopFetchedResultsController!.fetchedObjects![indexPath.row] as! Shop
let encodedShop = NSKeyedArchiver.archivedDataWithRootObject(selectedShop)
NSUserDefaults.standardUserDefaults().setObject(encodedShop, forKey: "currentShop")

And to retrieve it :

let encodedShop = NSUserDefaults.standardUserDefaults().objectForKey("currentShop") as! NSData
let currentShop = NSKeyedUnarchiver.unarchiveObjectWithData(encodedShop) as! Shop

Shop Entity :

import Foundation
import CoreData

@objc(Shop)
class Shop: NSManagedObject, NSCoding {

@NSManaged var name: String
@NSManaged var phoneNumber: String
@NSManaged var address: Address
@NSManaged var products: NSSet

// MARK: - Managed Object Context Insertable
class var entityName: String {
    return "Shop"
}

struct Attributes {
    static let Name = "name"
    static let PhoneNumber = "phoneNumber"
    static let Address = "address"
    static let Products = "products"
}

override init(entity: NSEntityDescription, insertIntoManagedObjectContext context: NSManagedObjectContext?) {
    super.init(entity: entity, insertIntoManagedObjectContext: context)
}

convenience init(name:String, phoneNumber:String, address:Address,  products:NSSet) {
    self.init(entity: NSEntityDescription.entityForName("Shop", inManagedObjectContext: ManagedObjectContext.defaultContext)!, insertIntoManagedObjectContext: ManagedObjectContext.defaultContext)
    self.name = name
    self.phoneNumber = phoneNumber
    self.address = address
    self.products = products

}

required convenience init(coder aDecoder: NSCoder) {
    let name = aDecoder.decodeObjectForKey("name") as! String
    let phoneNumber = aDecoder.decodeObjectForKey("phoneNumber") as! String
    let address = aDecoder.decodeObjectForKey("address") as! Address
    let products = aDecoder.decodeObjectForKey("products") as! NSSet
    self.init(name: name, phoneNumber: phoneNumber, address: address,  products: products)
}

func encodeWithCoder(aCoder: NSCoder) {
    aCoder.encodeObject(name, forKey: "name")
    aCoder.encodeObject(phoneNumber, forKey: "phoneNumber")
    aCoder.encodeObject(address, forKey: "address")
    aCoder.encodeObject(products, forKey: "products")
}

Address Entity :

class Address: NSManagedObject, NSCoding {

@NSManaged var city: String
@NSManaged var country: String
@NSManaged var ext: String?
@NSManaged var number: NSNumber?
@NSManaged var postalCode: String
@NSManaged var street: String
@NSManaged var customers: NSSet
@NSManaged var shop: Shop

// MARK: - Managed Object Context Insertable
class var entityName: String {
    return "Address"
}

struct Attributes {
    static let City = "city"
    static let Country = "country"
    static let Ext = "ext"
    static let Number = "number"
    static let PostalCode = "postalCode"
    static let Street = "street"
    static let Customers = "customers"
    static let Shop = "shop"
}

override init(entity: NSEntityDescription, insertIntoManagedObjectContext context: NSManagedObjectContext?) {
    super.init(entity: entity, insertIntoManagedObjectContext: context)
}

convenience init(city:String, country:String, ext:String?, number:NSNumber?, postalCode:String, street:String, customers: NSSet, shop: Shop) {
    self.init(entity: NSEntityDescription.entityForName(Address.entityName, inManagedObjectContext: ManagedObjectContext.defaultContext)!, insertIntoManagedObjectContext: ManagedObjectContext.defaultContext)
    self.city = city
    self.country = country
    self.ext = ext
    self.number = number
    self.postalCode = postalCode
    self.street = street
    self.customers = customers
   // self.shop = shop
}

required convenience init(coder aDecoder: NSCoder) {
    let city = aDecoder.decodeObjectForKey("city") as! String
    let country = aDecoder.decodeObjectForKey("country") as! String
    let ext : String? = aDecoder.decodeObjectForKey("ext") as? String
    let number : NSNumber? = aDecoder.decodeObjectForKey("number") as? NSNumber
    let postalCode = aDecoder.decodeObjectForKey("postalCode") as! String
    let street = aDecoder.decodeObjectForKey("street") as! String
    let customers = aDecoder.decodeObjectForKey("customers") as! NSSet
    let shop = aDecoder.decodeObjectForKey("shop") as! Shop
    self.init(city: city, country: country, ext: ext, number: number, postalCode: postalCode, street: street, customers: customers, shop: shop)
}

func encodeWithCoder(aCoder: NSCoder) {
    aCoder.encodeObject(city, forKey: "city")
    aCoder.encodeObject(country, forKey: "country")
    aCoder.encodeObject(ext, forKey: "ext")
    aCoder.encodeObject(number, forKey: "number")
    aCoder.encodeObject(postalCode, forKey: "postalCode")
    aCoder.encodeObject(street, forKey: "street")
    aCoder.encodeObject(customers, forKey: "customers")
    aCoder.encodeObject(shop, forKey: "shop")
}

I don't even know if it's the correct way to implement my entities..

For information, I use Swift2 and Xcode7. If you need more details, just tell me, I can provide you other things !

Thank you a lot for your help ! Trust me, I spend 3 days on that without solutions...

You never do this. Core data objects are meant to be saved in DB only. However, you can use NSUserDefaults to save any key which you can later retrieve and use to fetch data from core data.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM