Swift dynamicCast error while inserting new object to database - ios

I have a dictionary which I have all data that I want to insert into database as new object. The problem is when I try to cast the newly created object it gives me exception in:
libswift_stdlib_core.dylib`swift_dynamicCast:
part of assembly code.
The code that i am using is like this:
var group:Group
if (array.count == 0) {
group = NSEntityDescription.insertNewObjectForEntityForName("Group", inManagedObjectContext:appDelegate.managedObjectContext) as Group
}
and the structure of Group class is like this:
#objc(Group)
class Group:NSManagedObject{
#NSManaged var createDate:NSString
#NSManaged var groupPictureUrl:NSString
#NSManaged var groupTypeId:NSString
#NSManaged var isDepartment:NSString
#NSManaged var lastMessageRead:NSString
#NSManaged var name:NSString
#NSManaged var unreadMessageCount:NSString
#NSManaged var groupId:NSString
#NSManaged var lastSync:NSString
}
I have also a subclass of NSManagedObject named AppData which has the same structure with Group class. And at inserting part of my code if I replace Group with AppData it works and I can insert into AppData table. As I said before they have the same structure except parameters. But when I try to insert Group object it gives me dynamic cast exception. How can I solve this problem?

I solved the problem by initializing the entity object differently, if you implement the initiation method from super class(NSManagedObject) like: (in Group.swift)
init(entity: NSEntityDescription!, insertIntoManagedObjectContext context: NSManagedObjectContext!) {
super.init(entity: entity, insertIntoManagedObjectContext: context)
}
you can create the object like this:
var desc:NSEntityDescription = NSEntityDescription.entityForName("Group",inManagedObjectContext:appDelegate.managedObjectContext)
var group:Group = Group(entity:desc, insertIntoManagedObjectContext: appDelegate.managedObjectContext)
most of solutions i have read was making the initiation like this:
var group:Group = NSEntityDescription.insertNewObjectForEntityForName("Group", inManagedObjectContext:appDelegate.managedObjectContext) as Group
so this was the problem and object could not be casted to custom managed object class with this way. Thanks to everyone.

Related

How to delete Managed Objects associated with another Managed Object

I may have not asked correctly but basically I have two Managed Object Subclass one called Folder another for Items to create different shopping lists. Each Folder has many Items and each Item has one Folder.
The problem I am having is when I delete a Folder the Items associated with it are not also deleted there still hang around in the persistent store.
Does anybody know how I can I also delete the Items that have a relationship with the Folder upon deleting the Folder ?
Folder:
class Folder: NSManagedObject {
#NSManaged var arrayOfItems: [Items]
#NSManaged var date: NSDate
#NSManaged var title: String
#NSManaged var Items: NSSet
}
Items
class Items: NSManagedObject {
#NSManaged var date: NSDate
#NSManaged var index: NSNumber
#NSManaged var item: String
#NSManaged var folder: Folder
}
Deleting a folder:
context.deleteObject(self.selectedNotebook)
// Save the context.
do {
try context.save()
} catch {
print("error saving")
}
Go to your data model file, select the relationship, and on the right side panel select the Delete Rule Cascade
Also, this page can help you understand core data better

Using constructors to init instance vars subclass PFObject

I am working on implementing a subclass of PFObject called Event, in Swift. I followed the subclassing guide in Parse's docs, but I don't understand how and where to write the code that adds data to the ivars. Below is my what I have in my class so far, including the ivars.
#NSManaged var name:String
#NSManaged var time:NSDate
#NSManaged var favorite:Bool
#NSManaged var moderator: String
#NSManaged var speakers: [String]
#NSManaged var slides: PFFile?
#NSManaged var files: [PFFile]?
override class func initialize() {
var onceToken : dispatch_once_t = 0;
dispatch_once(&onceToken) {
self.registerSubclass()
}
}
class func parseClassName() -> String! {
return "Event"
}
Normally, I would implement an init() constructor or something similar. However, I realized that the data would already be contained in the PFObject's dictionary when it is fetched from the server. Where would I put the code to copy across and put this data in the instance vars from the PFObject's dictionary? This is presuming that I would instantiate the object via a query and fetch from the server and not locally using the object() method.
Based on the comment by deadbeef above, I realized that I can just use Swift's getters and setters for computed properties to read and write values from the PFObject's data dictionary.
For example a property that I intend to have as read-only:
var name:String
{
return self["name"] as String
}
And a property I intend to have as read-write
var favorite:Bool
{
get {
return self["favorite"] as Bool
}
set(value) {
self["favorite"] = value
}
}
You don't have to copy manually.
That's the Parse framework job. The objects will be populated with data after a fetch.

How to implement Cora Data Persistent Management

I have the following structure so far:
- Singleton NetworkingManager (login, logout API calls)
- Subclass NSManagedObject (with son extension)
I don't know how to structure this part of the app?
Do I need a PersistentManager/global ObjectManagedContext?
Here are my classes:
NetworkingManager (API-call)
func getContacts() {
GET(APIURL.URL_CONTACTS ,parameters: nil,
{ (operation : NSURLSessionDataTask!, response : AnyObject!) -> Void in
var contacts = [Contacts]()
contacts <<<<* response
//_sharedPersistentManager.save(contacts!)
}, { (operation : NSURLSessionDataTask!, error : NSError!) -> Void in
println("Error contacts")
})
}
Model
import Foundation
import CoreData
class Contacts: NSManagedObject, Deserializable {
#NSManaged var firstname: String
#NSManaged var lastname: String
#NSManaged var id: String
required init(data: [String: AnyObject]) {
let managedContext = (UIApplication.sharedApplication().delegate
as AppDelegate).managedObjectContext!
let entity = NSEntityDescription.entityForName("Contacts", inManagedObjectContext: managedContext)!
super.init(entity: entity, insertIntoManagedObjectContext: managedContext)
self.id <<< data["id"]
self.firstname <<< data["1"]
self.lastname <<< data["2"]
}
}
This code fails... (Bad_ACCESS)
I struggle with the basic class design.
Would be so kind of you to post some pseudo-code and I can understand the basic concept.
All Tutorials explain how to save or fetch some data, but not a real concept for a whole app...
I'm looking for a basic concept like:
- You should implement one Persistent Manager Singleton class
//PersistentManager
- global ObjectManagedContext
- Singleton
- func save (model1: Model1)
- func save (model2: Model2)
- ....
//NetworkingManager
- Singleton
- ...
EDIT:
- added some code
- added further explanation
Typically your App would have one database (but it may have more than one, depending on your requirements). If we assume you only need one then you need to create a Core Data database (persistent store) and at a minimum one NSPersistentStoreCoordinator and one ManagedObjectContext in order to create and update database records via the ManagedObjects. Just use the template app to get sample code for doing this.
I would not try using the ManagedObjects init() method for creating the object, instead use a helper function in another class to do this. This init() method will get called automatically when you create the object so you might use it to set some default values for properties.
Below is an example ManagedObject (Swift class) and an Objective-C helper function. Apologies in advance, you will need to convert this to the equivalent Swift code.
//
// DocumentCategory.swift
// Sample
//
import Foundation
import CoreData
#objc(DocumentCategoryX)
class DocumentCategoryX: NSManagedObject {
#NSManaged var image: NSData
#NSManaged var name: String
#NSManaged var sortIndex: NSNumber
#NSManaged var viewName: String
#NSManaged var documents: NSSet
}
Sample helper function to create a managed object (a Core Data database record)
- (NSManagedObject*)createNewCategory:(NSString*)entityName sortIndex:(int)sortIndex withName:(NSString *)name viewName:(NSString *)viewName icon:(UIImage*)icon;
{
NSManagedObject *newCat = [NSEntityDescription
insertNewObjectForEntityForName:entityName
inManagedObjectContext:[self managedObjectContext]];
[newCat setValue:[NSNumber numberWithInt:sortIndex] forKey:#"sortIndex"];
[newCat setValue:name forKey:#"name"];
[newCat setValue:viewName forKey:#"viewName"];
[newCat setValue:UIImagePNGRepresentation(icon) forKey:#"image"]; // iOS
return newCat;
}
Swift function to save the MOC. Call this whenever you need to make sure things are written to disk.
// MARK: - Core Data Saving support
func saveContext () {
if let moc = self.managedObjectContext {
var error: NSError? = nil
if moc.hasChanges && !moc.save(&error) {
//FLOG("Unresolved error \(error), \(error!.userInfo)")
// Probably need a message to the user warning that a save failed!
}
}
}

Issue setting up one to many relationship in Swift Core Data

I am in the process of learning Swift and have come across an issue that I can't seem to piece together a solution for.
Currently I have two Entities in my data model: Card and Set
A Set can have many cards, but a Card can only belong to one Set.
My cards relationship is set as To Many:
While my set relationship is set to To One:
For these two Entities, I have the following subclass code:
import Foundation
import CoreData
#objc(Set) class Set: NSManagedObject {
#NSManaged var code: String
#NSManaged var name: String
#NSManaged var cards: NSSet
}
extension Set {
func addCard(value: Card) {
self.mutableSetValueForKey("cards").addObject(value)
}
func getCards() -> [Card] {
var cards: [Card]
cards = self.cards.allObjects as [Card]
return cards
}
}
import Foundation
import CoreData
#objc(Card) class Card: NSManagedObject {
#NSManaged var name: String
#NSManaged var set: Set
}
I have successfully created and verified a Set with code such as this:
var set = NSEntityDescription.insertNewObjectForEntityForName("Set", inManagedObjectContext: context) as Set
set.name = setName;
set.code = setCode;
context.save(nil)
However, later when I attempt to create Card objects and add them to this set I run into an error. Here is the code I am using for that:
// The json data here is already verified as working fine elsewhere in my code, it just serves as the basis for creating the Card objects
var cards: [AnyObject] = json.valueForKey("cards") as NSArray
for var i = 0; i < cards.count; i++ {
var cardData = cards[i] as NSDictionary
var card = NSEntityDescription.insertNewObjectForEntityForName("Card", inManagedObjectContext: context) as Card
card.name = cardData.valueForKey("name") as String
set.addCard(card)
context.save(nil)
}
The error being fired currently reads as follows:
2015-01-19 00:25:42.803 <app name>[4667:113927] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSSet intersectsSet:]: set argument is not an NSSet'
I tried tracking the error as close to the point of failure as possible. It seems to happen in the addCard function in the Set extension. I am guessing I have some very minor error in my code, but since I am pretty new to debugging Swift code I am currently at a loss for where to go next. I actually had the assignment of Cards to a Set working previously, but something I changed must have caused this issue to occur.
You should rename getCards() function in the Set extension, I believe core data use this function name and the issue happened because you override it.

CoreData: Unable to load class for entity

I'm having an issue using relationships in Core Data. I created my data model including the following entities: User, Conversation, Message, Participant - each containing a one-to-many relationship with the entity following it. I generated the classes for each entity using Editor -> Create NSManagedObject Subclass, and it correctly created the .Swift files for each class. The project builds, but when attempting to create and save a new user I get the following error:
2014-12-01 12:31:28.450 Messenger[2627:151403] CoreData: warning: Unable to load class named 'Messenger.User' for entity 'User'. Class not found, using default NSManagedObject instead.
I made sure that my entity classes were prefixed with the project/module name (Messenger.User).
I also added "#ObjC(User)" directly above the User class, and added "-ObjC" to "Other Linker Flags" for the project, as suggested by people in various other posts. These are all the fixes that I could find, but I still get the same error. Here's what my User class looks like, for reference:
import Foundation
import CoreData
#objc(User)
class User: NSManagedObject {
#NSManaged var api : API
#NSManaged var username: String
#NSManaged var userID: String
#NSManaged var passcode: String
#NSManaged var conversations: NSSet
func findConversations(sourceView: MessengerViewController) {
api.findConversations(sourceView)
}
func addConversation(newConversation: Conversation) {
self.addConversationObject(newConversation)
}
}
extension User {
func addConversationObject(value: Conversation) {
var items = self.mutableSetValueForKey("conversations");
items.addObject(value)
}
func removeConversationObject(value: Conversation) {
var items = self.mutableSetValueForKey("conversations");
items.removeObject(value)
}
}
Does anybody have an idea what else I did wrong? I've tried every fix I could come across, but nothing has seemed to work so far.
EDIT: The warning occurs when trying to create a new User object, at the third line below:
let userContext : NSManagedObjectContext = self.appDel.managedObjectContext!
let userEntity : NSEntityDescription = NSEntityDescription.entityForName("User", inManagedObjectContext: userContext)!
var newUser = User(entity: userEntity, insertIntoManagedObjectContext: userContext)
Referring to my own answer, maybe you should also make sure you cast any fetch result to the appropriate class. E.g.
let result = context.executeFetchRequest(request, error:nil) as [User]
In response to your code update, you should perhaps try to insert new instances as follows.
var user = NSEntityDescription.insertNewObjectForEntityForName( "User",
inManagedObjectContext: context) as User

Resources