Base de Données non enregistrement des objets de façon persistante
Je suis nouveau à la Base de Données et en tant que tel ne suis pas sûr si je fais une erreur. J'ai téléchargé des données à partir d'une API REST et il a enregistré avec succès le JSON
réponse à disque. Je suis en train de traiter les données et enregistrer la persistance de l'aide de Base de Données.
NSLog(@"inserted objects: %@", [managedObjectContext insertedObjects]);
[managedObjectContext performBlockAndWait:^{
NSError *error = nil;
if (![managedObjectContext save:&error]) {
NSLog(@"Unable to save context for class %@", className);
} else {
NSLog(@"saved all records!");
}
}];
J'ai réussi à traiter le JSON
et de l'ajouter à un NSManagedObjectContext
. Dans la première ligne, il montre que j'ai réussi a tenté d'insérer des 2 objets.
inserted objects: {(
<User: 0xa259af0> (entity: User; id: 0xa259b70 <x-coredata:///User/t44BB97D0-C4B4-4BA6-BD25-13CEFDAE665F3> ; data: {
email = "[email protected]";
experience = "2013-07-20";
"first_name" = Vishnu;
id = 2;
"job_title" = Developer;
"last_name" = Prem;
location = "";
"phone_number" = "+6590091516";
"profile_pic" = "";
"thumbnail_profile_pic" = "";
"user_id" = 2;
}),
<User: 0xa25e460> (entity: User; id: 0xa25e4c0 <x-coredata:///User/t44BB97D0-C4B4-4BA6-BD25-13CEFDAE665F2> ; data: {
email = "[email protected]";
experience = "2013-07-20";
"first_name" = Sanchit;
id = 1;
"job_title" = Developer;
"last_name" = Bareja;
location = "";
"phone_number" = "+15106127328";
"profile_pic" = "";
"thumbnail_profile_pic" = "";
"user_id" = 1;
})
)}
Quand j'ai essayé de [managedObjectContext save:&error]
, il le fait avec succès et imprimer "sauvegardé tous les dossiers" comme prévu. Cependant, lorsque je vais à ma demande .sqlite
fichier et vérifier les objets ajoutés, je me rends compte qu'il n'a pas ajouté de tous les objets de la bd.
Sur l'app relancer, j'ai l'impression d'une liste d'objets qui sont déjà dans la base de données et il confirme que je n'en ai point encore enregistrés.
Personne ne sait ce qui se passe et pourquoi je ne suis pas en mesure d'enregistrer les données de manière persistante, même si on dirait que j'ai créé avec succès l '"Utilisateur" des objets qui doit être enregistré dans la Base de Données du modèle.
EDIT:
c'est là que je créer les NSPersistentStoreCoordinator
//Returns the persistent store coordinator for the application.
//If the coordinator doesn't already exist, it is created and the application's store added to it.
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"RTModel.sqlite"];
NSError *error = nil;
NSLog(@"Test 1");
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
NSLog(@"Test 2");
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
/*
Replace this implementation with code to handle the error appropriately.
abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
Typical reasons for an error here include:
* The persistent store is not accessible;
* The schema for the persistent store is incompatible with current managed object model.
Check the error message to determine what the actual problem was.
If the persistent store is not accessible, there is typically something wrong with the file path. Often, a file URL is pointing into the application's resources directory instead of a writeable directory.
If you encounter schema incompatibility errors during development, you can reduce their frequency by:
* Simply deleting the existing store:
[[NSFileManager defaultManager] removeItemAtURL:storeURL error:nil]
* Performing automatic lightweight migration by passing the following dictionary as the options parameter:
[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
Lightweight migration will only work for a limited set of schema changes; consult "Core Data Model Versioning and Data Migration Programming Guide" for details.
*/
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
return _persistentStoreCoordinator;
}
J'ai 3 contextes.
masterManagedObjectContext
backgroundManagedObjectContext
newManagedObjectContext
maître est mère de à la fois de fond et de nouvelles. Quand j'ai une requête contextes comme ceci:
NSError *error = nil;
NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"User"];
[request setSortDescriptors:[NSArray arrayWithObject:
[NSSortDescriptor sortDescriptorWithKey:@"id" ascending:YES]]];
[request setReturnsObjectsAsFaults:NO];
NSArray *testArray = [[[RTCoreDataController sharedInstance] newManagedObjectContext] executeFetchRequest:request error:&error];
for (User *obj in testArray) {
NSLog(@"obj.id %@", obj.id);
}
NSLog(@"query records: %@",testArray);
maître et de l'arrière-plan à la fois le bon obj.id dans le NSLog ainsi que donne la sortie ci-dessous pour @"les enregistrements de requête"
(
"<User: 0xa3811d0> (entity: User; id: 0xa381230 <x-coredata:///User/t92BCED2D-CD17-49CC-9EBA-DF8F52F06A002> ; data: {\n email = \"[email protected]\";\n experience = \"2013-07-20\";\n \"first_name\" = Sanchit;\n id = 1;\n \"job_title\" = Developer;\n \"last_name\" = Bareja;\n location = \"\";\n \"phone_number\" = \"+15106127328\";\n \"profile_pic\" = \"\";\n \"thumbnail_profile_pic\" = \"\";\n \"user_id\" = 1;\n})",
"<User: 0xa382170> (entity: User; id: 0xa3820b0 <x-coredata:///User/t92BCED2D-CD17-49CC-9EBA-DF8F52F06A003> ; data: {\n email = \"[email protected]\";\n experience = \"2013-07-20\";\n \"first_name\" = Vishnu;\n id = 2;\n \"job_title\" = Developer;\n \"last_name\" = Prem;\n location = \"\";\n \"phone_number\" = \"+6590091516\";\n \"profile_pic\" = \"\";\n \"thumbnail_profile_pic\" = \"\";\n \"user_id\" = 2;\n})"
)
toutefois, la "nouvelle" renvoie (null)
de l'obj.id en NSLog
et renvoie les éléments suivants pour @"query records"
:
(
"<User: 0xa2b08a0> (entity: User; id: 0x95aebe0 <x-coredata:///User/tBFCC6C5F-7D2C-4AA0-BA96-B806EE360A762> ; data: <fault>)",
"<User: 0xa2b0910> (entity: User; id: 0xa4b9780 <x-coredata:///User/tBFCC6C5F-7D2C-4AA0-BA96-B806EE360A763> ; data: <fault>)"
)
NSPersistentStoreCoordinator
et NSManagedObjectContext
? Si ceux-ci sont mal configurés, il vous aidera à voir s'il en existe.faites les modifications pertinentes! J'ai suivi le tutoriel ici (raywenderlich.com/15916/...) et cela fonctionne, mais quand j'ai essayé de le personnaliser pour mon propre API REST, il échoue.
avez-vous été "sauvé tous les records!" après la connexion des objets insérés?
Oui, je me suis "sauvé tous les records"!
Êtes-vous à l'aide de plusieurs objets gérés contextes? Vous avez peut être la relation parent-enfant entre certains, et de vous enregistrer uniquement l'enfant?
OriginalL'auteur Sanchit Bareja | 2013-08-17
Vous devez vous connecter pour publier un commentaire.
À partir de votre code et les commentaires, il semble que vous n'épargnent pas le maître contexte. Assurez-vous que vous appelez
sur tous les enfants des contextes d'enregistrer les données, et après que sur le maître contexte.
Cela devrait être la bonne réponse. J'ai rencontré le même problème tout à l'heure et après lecture de ce post j'ai essayé de force d'économie de l'ensemble du contexte de la hiérarchie dans une boucle. Enfin, le programme de travail.
Mon approche est d'avoir une fonction globale (en Données de Base de la pile ou de délégué d'Application)
saveContext
qui enregistre tout et à qui je peux appeler de n'importe où en toute sécurité.Oui, c'est nécessaire et m'a causé de la douleur, aussi, comme la Base de Données docs n'en parle pas. Je recommande également à l'appel de cette sur la file d'attente principale.
Mais seulement si le contexte a été créé sur le contexte principal!
OriginalL'auteur
Je viens de me faire cogner ma tête contre essentiellement le même problème. Un UITableViewController extrait une sous-classe de NSManagedObject de la NSManagedObjectContext, vérifier si un attribut a été nulle, et si il a été téléchargé les données, définissez cet attribut, puis sauvé le NSManagedObjectContext. Quelque chose comme ceci:
La fonction d'enregistrement a été de donner un OUI de retour boolean et saveError le reste du néant, mais si je quitte l'application et l'a relancé, lors de ma Base de Données chargé mon NSManagedObject sous-classes, les attributs de données a été de néant, et quand ce UITableViewController revint, il avait pour télécharger les données à nouveau.
Je ne pouvais pas vraiment trouver une solution à ce n'importe où... la lecture à travers la Base de Données de la documentation n'a pas aidé. La solution m'est venue lorsque j'ai examiné la différence entre le code ci-dessus et mon code qui définit les attributs dans le NSManagedObject sous-classe de l'usine de méthodes, ce qui est fondamentalement:
La seule différence est que je vais appeler les méthodes de fabrique de l'intérieur [mgObContext performBlock:].
De sorte que le code est modifié:
Qui, à ce jour, fonctionne parfaitement. Donc, je pense que n'importe quand vous faites des modifications à NSManagedObjects' attributs, vous devez le faire sur leur NSManagedObjectContext du fil.
OriginalL'auteur
Pensé que je voudrais également ajouter une entrée pour les personnes qui ont des problèmes similaires.
Dans mon expérience, en essayant de sauver les objets qui n'ont pas suffisamment de champs ne semblent persister lors de l'enregistrement, et pas d'erreurs semblent être levée lorsque c'est le cas. Vérifiez toujours si les champs sont remplis correctement avant de l'enregistrer incendies.
Une autre façon de regarder ces types de problèmes sont à retourner le problème dans sa tête. Peut-être que l'objet n'a en fait enregistrer, mais la méthode dans laquelle vous êtes de vérifier qu'ils ont, en effet, été sauvés qui est faux. Souvent, vous pourriez faire ceci en interrogeant CoreData pour l'enregistrement(s) à l'aide de certains critères. Vérifiez que vos critères sont corrects et que votre requête est en fait le retour de ce que vous attendez.
S'il ne retourne pas à quoi vous vous attendez, il pourrait être en raison de vos propres erreurs, mais il se pourrait aussi que la matrice de stockage de vos résultats n'est pas de les ranger correctement. J'ai couru dans les cas avant, où j'ai dû renommer un
NSArray
parce que quelque chose sur le nom du tableau était à l'origine de référencement de questions, et donc la matrice pourrait pas les résultats que j'attendais. Des acclamations.OriginalL'auteur
Je suis un débutant avec iOS, mais j'ai fait quelques exemple avec CoreData pour stocker les utilisateurs d'info.
Tout d'abord, vous avez besoin pour créer votre modèle de votre entité (je suppose que vous l'avez déjà fait). Dans mon exemple, mon entité est appelée "l'Utilisateur".
Tout d'abord, ajoutez une propriété similaire à ce
à votre ViewController classe.
Deuxième, dans votre méthode viewDidLoad, ajoutez ces deux lignes:
Et la troisième, de stocker votre info:
(Je prends mes propriétés à partir d'un NSDictionary appelé dictionnaire)
De lire votre info:
OriginalL'auteur
Je sais que ce n'est pas une réponse à ce que l'OP a demandé, mais je voulais partager mon expérience sur le même sujet, dans le cas où il aidera quelqu'un d'autre.
J'ai eu quelques problèmes avec l'enregistrement des données de manière persistante, quelque chose semblait m'aider à la réparer. La structure est très simple, une Entité avec un champ et un lien (à plusieurs). J'ai apporté quelques modifications à la classe générée,
NSMutableOrderedSet
au lieu deNSOrderedSet
.Je n'en faisais pas multi-thread, ou quelque chose comme ça, juste en ajoutant des éléments à la relation. Après l'enregistrement, et re-lancement de l'application, les données ont tout simplement disparu (les éléments ajoutés à la relation).
J'ai fini par découvrir qu'il existe une propriété appelée mise à jour. Après l'ajout de l'élément nouveau à la relation, j'ai vérifié si cette propriété a changé de sa valeur. Il n'a pas. J'ai donc dû créer un autre champ dans l'Entité, un Booléen, juste pour être en mesure de forcer l'entité pour être sauvé après l'ajout d'éléments de cette relation.
Donc j'espère que cela aide quelqu'un avec le même problème, j'ai passé un certain temps en pensant que je n'étais pas enregistrer correctement..
cela fait 2 ans maintenant, donc je ne me souviens pas des détails, mais pour assurer que la propriété ne fait pas partie du cadre, je l'ai ajouté à l'entité (comme je l'ai dit dans la réponse). Semble que tout ajout de l'objet du rapport n'a pas de déclenchement de l'enregistrer de façon persistante, mais la mise à jour de cette autre valeur a fait le tour.
OriginalL'auteur
Ajouter cette après vous enregistrez vos données :
OriginalL'auteur
Après des heures de débogage, j'ai trouvé que la raison pour laquelle mes mises à jour n'étaient pas sauvés parce que dans mon sous-classe de
NSManagedObject
j'ai défini par les propriétés w/@synthesize
au lieu de@dynamic
.Après je l'ai changer, tout enregistré comme prévu.
Espère que aidé quelqu'un.
OriginalL'auteur