[Résolu] Remplacer un message d'erreur de Core Data ?

berfisberfis Membre
janvier 2016 modifié dans API AppKit #1

Bonsoir,


 


Amené à  faire évoluer mon modèle lors du développement et ayant distribué des versions de test, je souhaiterais que mes utilisateurs ne se retrouvent pas en face du message:


 


"La version de modèle d'objet géré utilisée pour ouvrir le magasin persistant est incompatible avec celle utilisée lors de sa création."


 


qui, s'il me parle en tant que développeur, risque de déconcerter mes utilisateurs. Je souhaiterais remplacer ce message par:


 


"Ce document a été créé avec une version plus récente de l'application et ne peut être ouvert."


 


Mais je ne trouve pas la façon de le faire. Une recherche par Google me montre que ce cas est rare (heureusement) mais personne n'indique la manière de "personnaliser" le message.


 


Une idée? Merci d'avance.


Réponses

  • Bonjour,


    tu peux "intercepter" l'erreur lors de l'ouverture du PersistantStore et afficher ton propre message, non?


     


    Ou alors effectuer une migration automatiquement...


  • Merci Lexxis,


     


    Je vais regarder du côté de l'interception d'erreur. Mais comme l'application est document-based, le code fourni par défaut fait tout en arrière-plan. J'aimerais éviter de dériver NSPersistentDocument juste pour cette interception.


     


    Quant à  la migration automatique, je l'effectue, et c'est ça le problème. Si un utilisateur ouvre un document 1.0 avec l'application 2.0, pas de problème. Mais s'il décide de revenir à  la version 1.0 de l'application, il ne pourra plus ouvrir le document (ou alors il se trouvera face au message obscur).




  • le code fourni par défaut fait tout en arrière-plan. J'aimerais éviter de dériver NSPersistentDocument juste pour cette interception.




     


    Xcode ne te présente pas de code auto-généré c'est ça que tu veux dire par là  ? 

  • LexxisLexxis Membre
    décembre 2015 modifié #5


    J'aimerais éviter de dériver NSPersistentDocument juste pour cette interception.




     


    Si tu as une application Document-Based utilisant CoreData, ta classe "Document" n'est-elle pas une sous-classe de NSPersistentDocument ?


     


    Cela étant dit, tu peux peut être faire quelques vérifications à  partir de la méthode  configurePersistentStoreCoordinatorForURL...


  • Je pulsion @Lexxis : ta classe de base, "Document", sous-classe déjà  NSPersistentDocument. 


  • Bon, je google depuis des heures et personne n'en parle, donc je suis en train de perdre mon temps. L'utilisateur gardera son "objet géré" et son "magasin persistant" en attendant que les gens d'Apple trouvent une meilleure traduction.


     


    Merci tout de même, je m'aperçois que j'avais déjà  posé la question il y a quelque temps sans obtenir de réponse. Il faut croire que je suis le seul que ça dérange.


  • CéroceCéroce Membre, Modérateur

    Moi aussi, ça me dérange, mais je m'en arrange.


    NSPersistentDocument, plus on creuse son fonctionnement, et plus on voit que c'est de la bidouille. Sur mon projet actuel, nous avions tellement d'ennuis, que j'avais commencé à  programmer ma propre sous-classe de NSDocument et lui accrocher une base Core Data.


     


    (En pratique, c'est quasi impossible, parce que NSDocument déplace sans cesse le fichier sans avertir, alors on ne connait jamais de façon certaine l'URL de la base SQLite. Sur NSPersistentDocument, ils utilisent de grosses bidouilles, qui marchent parce qu'ils ont accès au code, mais seulement à  peu près. Maintenant, je peux expliquer pourquoi la sauvegarde auto (versions) marche aussi mal, et pourquoi le document se referme quand on choisit "Enregistrer sous...").


  • @Céroce


     


    J'utilise cette sous-classe de NSDocument à  la place de NSPersistentDocument : https://github.com/karelia/BSManagedDocument


  • CéroceCéroce Membre, Modérateur

    Je l'avais vu, mais il y avait une limitation importante qui m'empêchait de l'utiliser... je ne sais plus laquelle.


  • Sinon je penses que tu peux utiliser la méthode ci dessous du delegate de l'application. Il te "suffit" de renvoyer l'erreur adéquat si en entrée tu as l'erreur concernant CoreData (D'ailleurs je suppose que cette méthode est appelé quelque soit l'erreur affiché par l'application)



    - (NSError *)application:(NSApplication *)application willPresentError:(NSError *)error
  • Non, Lexxis, j'avais fini par trouver cette méthode, j'ai juste mis un NSLog dedans pour voir, mais elle n'a jamais été appelée (ce qui pourtant semblerait logique). NSPersistantDocument doit utiliser une autre méthode.


  • C'est vraiment étrange. Lors de mes tests cette méthode été bien appelé (El Capitan 10.11.1). Tu ne confond pas avec la méthode willPresentError:(NSError *)error de NSDocument ?

  • berfisberfis Membre
    janvier 2016 modifié #14

    Je me débrouillerai avec la méthode Lexxis (merci à  lui). En effet, j'avais confondu avec la méthode de NSDocument, mais comme le document n'était pas créé, elle n'était jamais appelée.



    @implementation AppDelegate

    - (NSError *)application:(NSApplication *)application willPresentError:(NSError *)error
    {
    // Vérification du type de l'erreur. S'il s'agit d'un problème de modèle inexistant:
    NSMutableDictionary *newUserInfo = [NSMutableDictionary dictionaryWithCapacity:[[[error userInfo] allKeys] count]];
    [newUserInfo setDictionary:[error userInfo]];
    NSString *errorDesc = [NSString stringWithFormat: NSLocalizedString(@UPPER_VERSION, nil)];
    [newUserInfo setObject:errorDesc forKey:NSLocalizedDescriptionKey];

    NSString *solution = [NSString stringWithFormat: NSLocalizedString(@PLEASE_INSTALL, nil)];
    [newUserInfo setObject:solution forKey:NSLocalizedRecoverySuggestionErrorKey];

    NSError *newError = [NSError errorWithDomain:[error domain] code:[error code] userInfo:newUserInfo];
    return newError;
    }
    ...

Connectez-vous ou Inscrivez-vous pour répondre.