Ma méthode pour écrire une image sur disque ne marche plus : très étrange!!

HerveHerve Membre
juin 2022 modifié dans Objective-C, Swift, C, C++ #1

Bonjour

Je reprends en ce moment une appli crée en 2015 (non publiée). C'est un logiciel d'animation. A un moment, j'écris des images sur le disque, celles-ci sont crées dans une NSView :

- (void) creeLesImages:(int)startPlan etFin:(int)endPlan etNomFichier:(NSString *)strNom{

   int nbImExtrait = endPlan - startPlan;

   for (int i = 0; i < nbImExtrait; i++){

        [self setPlanEnCours:(i + startPlan)];//un int pour le plan de l'animation
        fileImage = [nomFichier stringByAppendingString:[NSString stringWithFormat:@"_%d.tiff", (i + startPlan]];//l'adresse de fichier plus haut

       NSSize  imgSize = self.bounds.size;//nous sommes dans une NSView

        NSBitmapImageRep *bir = [self bitmapImageRepForCachingDisplayInRect:[self bounds]];
        [bir setSize:imgSize];

        [self cacheDisplayInRect:[self bounds] toBitmapImageRep:bir];  //c'est ici que drawRect est appelé

       NSImage * laVue = [[NSImage alloc] initWithSize:imgSize];
        [laVue addRepresentation:bir];
        NSLog(@"laVue %d = %@", (i + planInit), laVue.description);//l'image est crée

        BOOL imprimatur = YES;//pour vérification à cause du bugg
        NSData *pdfData = [laVue TIFFRepresentation];//en console, le data apparait bien
        imprimatur = [pdfData writeToFile:fileImage atomically:NO];//Il est toujours faux alors que le data est créé
        NSLog(@"pdfData %d = %@\adresse = %@\nimprimé = %d", (i + planInit),pdfData.description, fileImage, imprimatur);
    }
} 

En console, j'ai :

laVue 49 = <NSImage 0x6000013d48c0 Size={1163, 872} RepProvider=<NSImageArrayRepProvider: 0x6000020c1a40, reps:(
    "NSBitmapImageRep 0x6000009f4070 Size={1163, 872} ColorSpace=iMac colorspace BPS=8 BPP=32 Pixels=1163x872 Alpha=YES Planar=NO Format=0 CurrentBacking=<NSMutableData: 0x60000225f960>"
)
pdfData 49 = {length = 4060422, bytes = 0x4d4d002a 003de5e8 ffffffff ffffffff ... 00000002 33333400 }dresse = /Users/(...)/erty_49.tiff
imprimé = 0

J'ai vérifié l'adresse, tout fonctionne.

Cette méthode a toujours bien fonctionné et l'appli de 2015 marche normalement. J'ai "sandboxé" l'appli et ai bien autorisé l'accès aux documents, cela ne fonctionne pas mieux.
Etonnant non?

Auriez-vous une idée? Merci par avance...

Réponses

  • PyrohPyroh Membre

    Au delà du fait qu'il existe la méthode équivalente suivante: - (BOOL)writeToFile:(NSString *)path options:(NSDataWritingOptions)writeOptionsMask error:(NSError * _Nullable *)errorPtr; qui te permet de récupérer une erreur, tu peux aussi (normalement) récupérer l'erreur dans Console.app.

    Sinon d'après la documentation ils conseillent d'utiliser un NSFileHandle. C'est pas obligatoire mais ça permet aux applications qui ouvrent correctement les fichiers et dossiers d'être notifiés des changements/créations/suppressions. Donc c'est un bon conseil que tu devrais suivre mais je ne pense pas que ce soit ce qui provoque le bug.

  • LarmeLarme Membre

    [pdfData writeToFile:fileImage atomically:NO] Cela n'écrira pas s'il existe déjà un fichier à cet endroit là (atomically à NO). Est-ce le cas ? Tu ne souhaites pas écraser le fichier existant ?

  • HerveHerve Membre

    Merci pour ta réponse, Larme.
    Non, le fichier est tout neuf, il n'y a rien d'écrit encore.
    Je crains que ce soit une "sécurité" quelque part, c'est pour cela que j'ai sandboxé (je me suis souvent fait avoir avec cela). Mais là, pas de progrès.

    Merci aussi Pyroh. Je ne connais pas NSFileHandle, je vais voir cela.

    Ce qui m'étonne, c'est que l'ancienne compilation en App fonctionne TB (dernière en date : 2020)

  • PyrohPyroh Membre
    juin 2022 modifié #5

    Et au niveau des erreurs, t'as regardé ? Parce que ta réponse est sûrement là. Aussi c'est en sandboxant une app que tu vas sacrifier ses capacités sur l'autel de la sécurité, pas le contraire.

    Sinon pour atomically ça n'empêche pas d'écraser un fichier. À ma connaissance il n'existe pas de méthode d'écriture de fichier qui s'encombre de ce genre de détail, toutes écrasent à tout va. atomically fait que le contenu est écrit dans un fichier temporaire et si ça se passe bien le fichier cible est supprimé et le fichier temporaire est renommé avec le nom du fichier cible. Ça évite de corrompre les fichiers.

  • HerveHerve Membre
    juin 2022 modifié #6

    Gagné. Voici l'erreur :
    "erreur = Error Domain=NSCocoaErrorDomain Code=513 "You don’t have permission to save the file “erty_49.tiff” in the folder “TestAVF”." UserInfo={NSFilePath=/Users/.../Documents/Tests Anima/TestAVF/erty_49.tiff, NSUnderlyingError=0x6000009b1b90 {Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"}}"

    Bon, j'ai sandboxé. Ensuite??

    Passionnant, le document en lien avec NSFileHandle, je ne connaissais pas :
    https://developer.apple.com/library/archive/documentation/Security/Conceptual/SecureCodingGuide/Introduction.html#//apple_ref/doc/uid/TP40002477-SW1

    Vous travaillez en fonction de ces problématiques pour votre part?

  • PyrohPyroh Membre

    Soit tu enlève la sandbox de ton app et ça devrait normalement aller. Soit tu lis la documentation (qui est plutôt claire).

    @Herve a dit :
    Vous travaillez en fonction de ces problématiques pour votre part?

    Pas toujours de gaité de coeur mais oui.

  • HerveHerve Membre

    Merci Pyroh

    Je lis :
    "Loading kernel extensions
    Loading of kernel extensions is prohibited with App Sandbox."

    Mon application utilise un kernel perso pour un filtre image. Apparemment, c'est cela qui bloque. Ce serait dommage de s'en passer. J'essaie de ne pas sandboxer et je vous tiens au courant.

  • PyrohPyroh Membre
    C’est pas pareil. Là on parle d’extension pour le kernel macOS. Rien à voir avec les kernels Core Image 😉
  • Effectivement si j'enlève SandBox, les images sont bien écrites. Plus de problème.

    Qu'est-ce qu'un "kernel extension" comparé à CIImage? (il y a un fichier .cikernel dans l'appli, j'avais compris que c'était cela qui coinçait)

    Merci en tous les cas pour cette discussion. Je relirai demain la doc.

    Je reprends ce logiciel pour y mettre AVAsset (en 2015, j'utilisais QTMovie,, mais il n'est plus pris en charge) et créer le film à partir des images. Les premiers essais coinçaient également parce que le fichier du film ne pouvait être créé. J'espère que demain, cela marchera...

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