[RESOLU] pdf : Error CGImageComponentType unknown

busterTheobusterTheo Membre
octobre 2017 modifié dans API UIKit #1

Bonjour tout le monde,


j'en profite au passage pour remercier les barman&womans qui m'ont bien aidé, et dont j'ai utilisé la plupart des conseils pour mon app.


 


Là  je reviens vite fait, car sur google je ne trouve rien à  ce sujet.


 


Il s'agit d'une erreur que j'ai lorsque je crée mon pdf


 


 



 


<Error>: initialize_vImage_format : CGImageComponentType unknown - using kCGImageComponent8BitInteger derived from bits per pixel



 


 


Je ne met pas de code pour l'instant pour ne pas surcharger.


 


Je n'ai strictement rien trouvé sur cette erreur, même en restreignant la recherche sur moins de mots.


 


Si quelqu'un a une piste, je suis preneur


 


Merci d'avance...


Réponses

  • CéroceCéroce Membre, Modérateur

    ça ressemble aux constantes qu'on passe quand on crée un CGBitmapContext, comme kCGBitmapFloatComponents.


    Pourrais-tu nous faire voir ton code de création du PDF ?


  • Merci Céroce pour ta réponse.


     


    Je met le code de (createPdfFromView), je pense que cela suffira, sinon dis moi...


     


    Je sais que j'ai encore du nettoyage à  faire. Par ex. j'ai encore quelques variables globales qui trainent - je suis sur Instruments et ça avance bien.


     


    Voici le code du pdf :



    func createPdfFromView(_ aView: UIScrollView, saveToDocumentsWithFileName fileName: String) {
    let pageDimensions = aView.bounds // (0.0, 0.0, 970.0, 7000.0) Maintenant (0.0, 0.0, 970.0, 700.0) OK pour avoir plusieurs pages

    print("fileName = \(fileName)")

    let lePageSize = pageDimensions.size
    let totalSize = aView.contentSize

    var largeurPageWidth = lePageSize.width
    var hauteurPageHeight = lePageSize.height

    if largeurPageWidth == 0 {
    largeurPageWidth = 400.0
    }
    if hauteurPageHeight == 0 {
    hauteurPageHeight = 400.0
    }

    let numberOfPagesThatFitHorizontally = Int(ceil(totalSize.width / largeurPageWidth)) // = 1
    let numberOfPagesThatFitVertically = Int(ceil(totalSize.height / hauteurPageHeight))

    let outputData = NSMutableData()
    UIGraphicsBeginPDFContextToData(outputData, pageDimensions, nil)

    let savedContentOffset = aView.contentOffset
    let savedContentInset = aView.contentInset

    aView.contentInset = UIEdgeInsets.zero

    if let context = UIGraphicsGetCurrentContext() {
    for indexHorizontal in 0 ..< numberOfPagesThatFitHorizontally {
    for indexVertical in 0 ..< numberOfPagesThatFitVertically {
    UIGraphicsBeginPDFPage()

    var leBonOffsetX = 0
    var leBonOffsetY = 0


    if indexHorizontal != 0 {
    leBonOffsetX = indexHorizontal
    } else {
    leBonOffsetX = 0
    }

    if indexVertical != 0 {
    leBonOffsetY = indexVertical
    } else {
    leBonOffsetY = 0
    }

    let offsetHorizontal = CGFloat(leBonOffsetX) * pageSize.width
    let offsetVertical = CGFloat(leBonOffsetY) * pageSize.height

    // context.translateBy(x: -offsetHorizontal, y: -offsetVertical)
    // aView.contentOffset = CGPoint(x: offsetHorizontal, y: offsetVertical)

    // Sinon ça marche pas : je ne sais pas pourquoi...!
    if leBonOffsetX != 0 && leBonOffsetY != 0 {
    context.translateBy(x: -offsetHorizontal, y: -offsetVertical)
    } else if leBonOffsetX == 0 && leBonOffsetY != 0 {
    context.translateBy(x: 0, y: -offsetVertical)
    } else if leBonOffsetX != 0 && leBonOffsetY == 0 {
    context.translateBy(x: -offsetHorizontal, y: 0)
    } else if leBonOffsetX == 0 && leBonOffsetY == 0 {
    context.translateBy(x: 0, y: 0)
    }

    aView.contentOffset = CGPoint(x: offsetHorizontal, y: offsetVertical)

    aView.layer.render(in: context)
    }
    }
    }

    UIGraphicsEndPDFContext()

    aView.contentInset = savedContentInset
    aView.contentOffset = savedContentOffset

    let path = NSSearchPathForDirectoriesInDomains(.documentDirectory,.userDomainMask, true)[0]

    let documentsFileName = path + "/Etude-esthetique" + "-" + fileName + ".pdf"

    // ICI save documentsFileName dans urlPdf dans BDD
    let fetchEntity: FetchEntity = FetchEntity()
    let fetchResultsPatients: NSArray = fetchEntity.getFetchResults("Patients", predicateField: listeDesVariables.nomString)

    let singlePatient: Patients = fetchResultsPatients.lastObject as! Patients

    let nomPdf = "/Etude-esthetique" + "-" + fileName + ".pdf"
    singlePatient.setValue(nomPdf, forKey: "urlPdf")

    do {
    try GeContext.save()
    } catch _ {
    }

    globalDocumentsFileName = documentsFileName

    outputData.write(toFile: documentsFileName, atomically: true)

    }
  • CéroceCéroce Membre, Modérateur
    octobre 2017 modifié #4

    Je ne parviens pas à  reproduire le bug avec ce code. J'ai testé sous iOS 10.3 et 11.0 (simu).


    Sur quelle ligne exacte as-tu le message d'erreur ?


  • En fait sur le simulateur, l'erreur n'apparaà®t pas.


    Elle apparaà®t sur mon iPad : 3e génération - wifi - 64 Go - iOS 9.3.5




  • En fait sur le simulateur, l'erreur n'apparaà®t pas.


    Elle apparaà®t sur mon iPad : 3e génération - wifi - 64 Go - iOS 9.3.5




     


    Xcode n'affiche pas  la ligne sur la console, si l'iPad est connecté au Mac en mode débug ?

  • Joanna CarterJoanna Carter Membre, Modérateur


    En fait sur le simulateur, l'erreur n'apparaà®t pas.


    Elle apparaà®t sur mon iPad : 3e génération - wifi - 64 Go - iOS 9.3.5




     


    Peut-être, mais si l'erreur apparaà®t, c'est sur quelle ligne de code ?

  • BT, tu devrais reproduire l'erreur et nous montrer une copie d'écran complète d'Xcode à  ce moment.

  • Xcode ne dit pas sur quelle ligne de code.


     


    Et l'app ne plante pas du tout.


     


    En gros, aucun pb sauf l'affichage de cette erreur.


     


    J'en vois d'autres aussi, de temps en temps (je ferais d'autres posts pour cela), et certaines disparaissent avec l'optimisation du code, mais celle-ci persiste.


     


    Pas très important, je pense.


     


    Avec toutes ces versions de iOS, Xcode, swift, macOS, etc, qui changent sans arrêt, y'a de quoi devenir chèvre.


     


     


     


    En tout cas, merci pour votre persévérance...


  • CéroceCéroce Membre, Modérateur

    Bon, si c'est juste un message dans la console...


    Mais entre nous, moi aussi quand je vois le moindre warning, j'essaye de le corriger. Même s'il y a pas mal de frameworks qui loggent beaucoup trop dans la console.


     




    Xcode ne dit pas sur quelle ligne de code.


     




    Fait du pas-à -pas avec le débogueur, tu verras après l'exécution de quelle ligne le message s'affiche.


  • Ah merci, il est vrai que je ne pratique pas cette technique, je travaille beaucoup à  l'ancienne avec des print...


     


    Mais là , je travaille beaucoup sur instruments, et un peu avec le debugger. Je vais poussez un peu là -dessus.


    Merci pour tes conseils et encouragements. Je reviens avec la ligne de code en question.


  • CéroceCéroce Membre, Modérateur

    Si je peux me permettre, essaie d'effectuer les améliorations suivantes dans ton code:


    - la production d'un PDF mériterait une classe à  elle-seule


    - extrais la détermination du nom de fichier et l'enregistrement dans le fichier


    - de même, extrais tout ce qui concerne CoreData d'ici. Ce genre de mélanges devient vite ingérable.


    - essaie de faire des méthodes qui ne dépassent pas 10 lignes (c'est très faisable, crois-moi).


  • Ce sont des conseils à  suivre impérativement, je sais, mais tellement de pression et de délais et de fichiers que je dois faire dans l'ordre des priorités. Et cela en fait partie.


     


    Mais à  ce propos, c'est un peu difficile dans le sens où le pdf est censé se construire, on va dire sur un écran, qui lui, est donc relié à  un controller, qui lui, à  des tonnes de données issues de plusieurs controllers associés à  plusieurs écrans, et donc des dizaines de données (variables issues de calculs et tests à  partir de données coredata) et blablabla - Enfin, tu vois l'délire quoi !!!


     


    C'est genre, 1 mois de taf pour modifier un truc qui fonctionne impec. Mais à  faire plus tard quand même.


    J'en rêve mais trop risqué pour l'instant...


     


    Merci quand même pour ces précieux conseils. Je garde çà  dans ma besace...


    T'as bien fait de te permettre. 


  • CéroceCéroce Membre, Modérateur
    octobre 2017 modifié #14


    C'est genre, 1 mois de taf pour modifier un truc qui fonctionne impec. Mais à  faire plus tard quand même.


    J'en rêve mais trop risqué pour l'instant...




    Je comprends fort bien, et il ne faut pas croire qu'il y aurait des êtres surdoués qui feraient du code parfait. Mais à  ne rien améliorer, tu accumules la dette technique, et modifier ton code devient de plus en plus compliqué.


     


    L'approche dite du Boy Scout " Laisser le code en meilleur état qu'on l'a trouvé " est souvent judicieuse. L'idée est que quand on revient sur un bout de code, on l'améliore juste un peu. C'est une bonne technique parce que l'amélioration est progressive (pas besoin d'un gros investissement), et le travail est concentré sur le code qui est souvent modifié.


     


    Enfin, les modifications que je te propose ne sont pas forcément compliquées ni risquées. Souvent, juste renommer des variables, des fonctions ou des classes, et extraire un bout d'une fonction dans une autre améliorent beaucoup la lisibilité sans compromettre la logique. 


  • Joanna CarterJoanna Carter Membre, Modérateur


    Mais à  ce propos, c'est un peu difficile dans le sens où le pdf est censé se construire, on va dire sur un écran, qui lui, est donc relié à  un controller, qui lui, à  des tonnes de données issues de plusieurs controllers associés à  plusieurs écrans, et donc des dizaines de données (variables issues de calculs et tests à  partir de données coredata) et blablabla - Enfin, tu vois l'délire quoi !!!




     


     


    Malheureusement, là , c'est ton problème  ::)


     


    Si tu avais commencé en bien compartimenter ton code, tu n'aurais pas ce chose de délire.


     


    Les controllers ne sont pas là  pour stocker les données, il sont là  pour les connecter aux composants visuels. Chaque interaction avec l'UI devrait être "détecté" par le controller et c'est con boulot de "traduire" le geste en données et de transmettre le résultat au modèle ; c'est seulement dans le modèle que l'on trouve les données.


     


    Pour toi, comme dit Céroce, il faut commencer à  extraire les données des controllers et les mettre dans un/plusieurs classes/structs. Il ne faut pas le faire tout en même temps ; tu pourrais le faire par fonction ou même par propriété. Après, tu auras un seul endroit dont tu trouveras les données pour le pdf.


     


    Pour l'avenir, il faut, dès aujourd'hui, mieux compartimenter ton code dehors le controllers  :-*

  • Oui, grand merci pour vos motivations. 


    Je suis justement en train de procéder ainsi depuis pas mal de temps.


    Mon code s'améliore et se simplifie. Je ne sais pas si on s'exprime ainsi, mais j'externalise de plus en plus.


     


    J'ai bien noté le rappel sur le MVC. Merci, car depuis le temps, c'est toujours dur de rentrer ça dans ma p'tite tête - Peut-être devrais-je essayer d'avoir le "melon", y'aurait plus de place, mais cela n'est pas le cas.  o:)


    MVC, plus optionnal/nil/unwrapping, c'est toujours chaud tout ça pour moi. Pfff.


    ça fait trois ans que je suis sur cette app.


    Je progresse, et j'ai parfois l'impression de régresser.


    C'est ainsi qu'on apprend, je crois.


    J'essaie d'être de plus en plus rigoureux, mais le stress perturbe parfois.


     


    Le truc est que j'évolue avec le temps, et aussi beaucoup grâce aux barmans, mais la route est longue.


    J'ai appris beaucoup de choses, mais je reste encore un débutant, pas mauvais, certes, mais vraiment mauvais quand même :o , du fait du non-respect des fondamentaux. Mais ça vient... 


     


    Bon allez, j'arrête de déconner (ça fait du bien, ça aide à  lutter contre le stress) et je repars onTheRoadAgain.


     


    Désolé pour cette séance de divan qui vous fait perdre votre temps.


     


    Je propose de mettre "Résolu".


     


    On va certainement se retrouver sur d'autres posts...


     


    :p     :p

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