[Swift]Conversion NSAttributedString <=> NSData

DrakenDraken Membre
janvier 2016 modifié dans API UIKit #1

Il est simple de fabriquer un NSData à  partir d'un String.



let str = "Sushi"
let dataSushi = str.dataUsingEncoding(NSUTF8StringEncoding)

Et dans le sens inverse (NSData => String)



let strData = String(data: dataSushi!, encoding: NSUTF8StringEncoding)

Je n'arrive pas à  faire la même chose avec un NSAttributedString. D'après la documentation, il faut utiliser la méthode dataFromRange, avec un paramètre documentAttributes.



let miam = NSAttributedString(string: "Miam miam")
let dataMian = miam.dataFromRange(range: NSRange, documentAttributes: [String : AnyObject])

Si j'essaye de passer [:], je me fait jeter par Xcode.



let miam = NSAttributedString(string: "Miam miam")
let dataMiam = miam.dataFromRange(range: NSRange, documentAttributes: [:])

Il m'explique que "Call can throw, but it not marked with 'try' and the error is not handled." J'ai survolé le chapitre sur le Error handling pour trouver la bonne syntaxe, mais il est 2 heures du matin et mon esprit patine dans la gadoue)


 


Une suggestion pour la conversion NSAttributedString => NSData et vice-versa ?


 


J'arrive à  le faire en utilisant le protocole NSCoding, mais le résultat est trop gourmand en mémoire, 540 octets pour un simple "Sushi". Le seul point positif est qu'il n'y a pas besoin des paramètres abscons de NSAttributedString.dataFromRange(). 



class UnTexte : NSObject, NSCoding {
var texte = NSAttributedString()

init(texte: NSAttributedString) {
self.texte = texte
}

required init?(coder aDecoder: NSCoder) {
self.texte = aDecoder.decodeObjectForKey("texte") as! NSAttributedString
}

func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeObject(self.texte, forKey: "texte")
}

}


let attStr = NSAttributedString(string: "Sushi")
let texte = UnTexte(texte: attStr)
let dataTexte = NSKeyedArchiver.archivedDataWithRootObject(texte)
print(dataTexte.length)

Je présume que le mécanisme du NSCoding prend de la place pour ces besoins internes, mais 540 octets pour un simple NSAttributedString de 5 caractères, c'est beaucoup ..


 


Par curiosité, j'ai fait le même test avec NSCoding et un String de base, pour arriver à  302 octets avec un simple "Sushi". C'est encore trop, alors que cela ne prend que 5 octets avec String.dataUsingEncoding.


«1

Réponses

  • Il te faut les attributs aussi de ton NSAttributedString ou juste le String ?


    Parce que dans ce cas là  tu as la propriété string de toute instance de NSAttributedString et qui renvoie le texte brut.


  • Oui il faut lire la gestion des erreurs :). et il faut que tu passes aussi au moins un attributs


     



     


        // Generates an NSData object for the receiver contents in range.  It requires a document attributes dict specifying at least the NSDocumentTypeDocumentAttribute to determine the format to be written.


        @available(iOS 7.0, *)


        public func dataFromRange(range: NSRange, documentAttributes dict: [String : AnyObject]) throws -> NSData


     





    let dataMian = try? miam.dataFromRange(range, documentAttributes: [NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType])



  • Il te faut les attributs aussi de ton NSAttributedString ou juste le String ?


    Parce que dans ce cas là  tu as la propriété string de toute instance de NSAttributedString et qui renvoie le texte brut.




    Un joli texte prend beaucoup de son intérêt sans le gras et l'italique.



  • Oui il faut lire la gestion des erreurs :). et il faut que tu passes aussi au moins un attributs




    let dataMian = try? miam.dataFromRange(range, documentAttributes: [NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType])




     


     


    Merci, ça marche. Mais c'est gourmand ..



    let miam = NSAttributedString(string: "Miam miam")
    let range = NSRange(location: 0, length: miam.length)
    let dataMiam = try? miam.dataFromRange(range, documentAttributes: [NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType])
    print (dataMiam?.length)


    550 octets pour stocker "miam miam".


     


    En utilisant NSRTFTextDocument pour documentAttributes ça tombe à  250 octets.


     


    Et 9 octets avec NSPlainTextDocument ! Prochaine étape, tester avec des enrichissements dans le texte. 

  • Pas sûr que NSPlainTextDocument garde les attributs...


     


    Je me demande à  quel point est optimisée la conversion inverse, que donne let strData = String(data: dataMiam!, encoding: NSUTF8StringEncoding), en fonction des différentes transformations possibles ?


  • DrakenDraken Membre
    janvier 2016 modifié #7


    Pas sûr que NSPlainTextDocument garde les attributs...




    C'est ce que je me disais aussi. Je verrais en testant. Mais il reste toujours le format RTF.


     


    C'est fou de faire toutes ces manipulations juste pour conserver le gras et les italiques dans la chaine stockée sur disque.


     


    Ce que je cherche à  faire, c'est stocker une String dans un NSData dans le format le plus compact possible, avec des indicateurs de gras et d'italique. Je n'ai pas besoin de toute la puissance des NSAttributedString, juste de conserver gras et italique.

  • LarmeLarme Membre
    janvier 2016 modifié #8


    C'est ce que je me disais aussi. Je verrais en testant. Mais il reste toujours le format RTF.


     


    C'est fou de faire toutes ces manipulations juste pour conserver le gras et les italiques dans la chaine stockée sur disque.




    Si tu reçois les strings avec les balises toi-même, il est peut-être plus intéressant de les garder avec les balises... Potentiellement, la version sans balise aussi (pour faire une recherche sur le string).



    NSString  *htmlString = @<b>Bo</b><i>Bi</i><u>Bu</u>;
    NSAttributedString *attributedString = [[NSAttributedString alloc] initWithData:[htmlString dataUsingEncoding:NSUTF8StringEncoding]
          options:options
          documentAttributes:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType}
          error:nil];
    NSString *textToSave= [attributedString string];
    NSString *textWithHTMLToSave = htmlString;

  • DrakenDraken Membre
    janvier 2016 modifié #9

    A l'origine le texte est un NSAttributedString extrait d'un fichier RTF.


     


    Je n'ai plus le temps de continuer maintenant, mais j'ai vu que la taille du NSData au format de document RTF n'augmente pas très vite. Il semble y avoir un entête de 240 octets, ensuite chaque caractère ne prend qu'un octet (du moins les caractères classique de l'alphabet). Ce n'est pas une perte très importante, avec des textes longs.



  • Pas sûr que NSPlainTextDocument garde les attributs...




    Après vérification, il ne les garde pas.  >:(

  • AliGatorAliGator Membre, Modérateur
    Bah en même temps heureusement qu'il ne les garde pas, vu que c'est le but même de ce format, de ne stocker que du plain text (qui signifie en anglais "texte brut" à  savoir sans attributs, par opposition à  "texte stylé"). S'il gardait les attributs avec NSPlainTextDocument ça serait un bug.


  • Un joli texte prend beaucoup de son intérêt sans le gras et l'italique.




     


    J'ai fait ce test :

    ​



    NSString *string = @<u>Bo</u><i>Bi<b>Bu</b></i>;
    NSLog(@String: %@", string);
    NSError *errorStrToAttrStr = nil;
    NSAttributedString *attrString = [[NSAttributedString alloc] initWithData:[string dataUsingEncoding:NSUTF8StringEncoding]
                       options:@{NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType}
                     documentAttributes:nil
                      error:&errorStrToAttrStr];

    if (errorStrToAttrStr)
    {
      NSLog(@errorStrToAttrStr: %@", errorStrToAttrStr);
      return;
    }

    NSLog(@AttrStr: %@", attrString);

    NSError *errorAttrStrToStr = nil;
    NSData *data1 = [attrString dataFromRange:NSMakeRange(0, [attrString length])
             documentAttributes:@{NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType}
              error:&errorAttrStrToStr];

    if (errorAttrStrToStr)
    {
      NSLog(@errorAttrStrToStr: %@", errorAttrStrToStr);
      return;
    }
    NSLog(@Data1: %@", data1);

    NSString *stringRetrieved = [[NSString alloc] initWithData:data1 encoding:NSUTF8StringEncoding];
    NSLog(@StringRetrived: %@", stringRetrieved);

    NSError *errorDataToAttrStr = nil;
    NSAttributedString *attrStringRetrieved = [[NSAttributedString alloc] initWithData:data1
                          options:@{NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType}
                     documentAttributes:nil
                         error:&errorDataToAttrStr];

    if (errorDataToAttrStr)
    {
      NSLog(@errorDataToAttrStr %@", errorDataToAttrStr);
    }

    NSLog(@AttrStringRetrieved: %@", attrStringRetrieved);


    Quand on logs les attributedstrings, on voit que beaucoup d'informations sont sauvegardées.


    ça doit être pareil avec le RTF, j'ai pas testé.

  • DrakenDraken Membre
    janvier 2016 modifié #13

    D'après mes essais, le format RTF est environ deux fois moins gourmand que le HTML, fort heureusement. Mais cela reste encore par rapport au texte "pur".


     


    J'ai essayé avec ce texte :


    "Il ne faut pas confondre les sushis avec les sashimis, un plat japonais constitué de tranches de poisson cru."


     


    Encapsulé dans un NSData, il prend 110 octets.


     


    Stocké dans un NSAttributed, puis encapsulé dans un NSData au format RTF : 353 octets



    let textSushi = "Il ne faut pas confondre les sushis avec les sashimis, un plat japonais constitué de tranches de poisson cru."

    let dataStringSushi = textSushi.dataUsingEncoding(NSUTF8StringEncoding)

    let sushi = NSAttributedString(string: textSushi)

    let dataSushi = try? sushi.dataFromRange(NSRange(location: 0, length: sushi.length), documentAttributes: [NSDocumentTypeDocumentAttribute:NSRTFTextDocumentType])

    if let dataSushi = dataSushi {
    print (dataStringSushi?.length)
    print(dataSushi.length)
    }

    La même chose au format NSData HTLM : 651 octets



    let dataSushi = try? sushi.dataFromRange(NSRange(location: 0, length: sushi.length), documentAttributes: [NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType])

    La taille du NSData est identique si j'utilise un NSMutableAttributedString.


     


    C'est du texte brut, sans le moindre attribut. Ou alors juste les attributs que iOS lui assigne pendant la création du NSAttributedString.


     


    J'ai ajouté un attribut de couleur sur tous les caractères, cela fait passer le NSData (format RTF) à  374 octets, soit une différence de +21 octets. C'est intéressant parce qu'il y a justement 21 blocs de lettres dans le texte, en comptant la virgule et le point final.


     


    Avec le même attribut de couleur, le NSData (format HTLM) passe de 651 octets à  667 octets (+16 octets).


     


    Une surprise : J'ai ensuite essayé de changer la police de caractères du texte. En NSData RTF cela fait baisser la taille de la chaà®ne. De 353 octets, ça passe à  349 octets ! 4 octets, c'est toujours ça de gagné ..



    func changerFont (texte:NSMutableAttributedString, font:UIFont)
    {
    texte.addAttribute(NSFontAttributeName, value: font, range:NSRange(location:0, length:texte.length))
    }

    Le phénomène ne se reproduit pas en HTML. Le changement de police ajoute 16 octets à  la taille, exactement comme pour la couleur.


     


    Je résume :


    String : 110 octets


    NSData format RTF : 353 octets


    NSData format HTML : 651 octets


     


    Conclusion le format RTF c'est bien, le format HTLM c'est mal. Du moins pour stocker des textes enrichis dans un NSData.

  • Si la taille mémoire est vraiment importante pour toi et si tu n'as que quelques options de formattage connues à  l'avance, tu peux créer ton propre format.

    Texte|attribut1|Index debut|Index fin|attribut2|debut|fin ...


    En utilisant la fonction enumerateAttributesInRange pour parcourir les attributs.


    Il y a aussi le format BBCode et je ne serais pas étonné que tu trouves des sources qui font la conversion vers BBCode sur github.


  • Si la taille mémoire est vraiment importante pour toi et si tu n'as que quelques options de formattage connues à  l'avance, tu peux créer ton propre format.

    Texte|attribut1|Index debut|Index fin|attribut2|debut|fin ...


    En utilisant la fonction enumerateAttributesInRange pour parcourir les attributs.




    C'est exactement ce que j'étais en train de me dire !

  • Je comprend mieux l'excédent de poids d'un NSAttributedString après le stockage dans un NSData. iOS ajoute des tas d'informations de présentation au passage. 


     


    Exemple :



    let str = "Sushi Power"
    var attStr = NSAttributedString(string: str)

    Affichage de attStr dans la console :


     



     


    Sushi Power{


    }



     


     


    Conversion en NSData (format RTF) et génération d'un nouvel NSAttributedString :



    let str = "Sushi Power"
    var attStr = NSAttributedString(string: str)

    // Format de stockage du NSData
    let optionDocument = [NSDocumentTypeDocumentAttribute:NSRTFTextDocumentType]

    // Conversion NSAttributedString => NSData
    let data = try? attStr.dataFromRange(NSRange(location: 0, length: attStr.length), documentAttributes:optionDocument)

    // Conversion NSData => NSAttributedString
    let texteFinal = try? NSAttributedString(data: data!, options: optionDocument, documentAttributes: nil)

    Affichage de texteFinal dans la console :


     



     


    Optional(Sushi Power{


        NSFont = "<UICTFont: 0x7c9736d0> font-family: \"Helvetica\"; font-weight: normal; font-style: normal; font-size: 12.00pt";


        NSParagraphStyle = "Alignment 0, LineSpacing 0, ParagraphSpacing 0, ParagraphSpacingBefore 0, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 0/0, LineHeightMultiple 0, LineBreakMode 0, Tabs (\n    28L,\n    56L,\n    84L,\n    112L,\n    140L,\n    168L,\n    196L,\n    224L,\n    252L,\n    280L,\n    308L,\n    336L\n), DefaultTabInterval 36, Blocks (null), Lists (\n), BaseWritingDirection -1, HyphenationFactor 0, TighteningForTruncation NO, HeaderLevel 0";


    })



     


    C'est copieux ..


     


    Encore pire avec un NSData au format HTML :


     



     


    Optional(Sushi Power{


        NSColor = "UIDeviceRGBColorSpace 0 0 0 1";


        NSFont = "<UICTFont: 0x7a85a9e0> font-family: \"Helvetica\"; font-weight: normal; font-style: normal; font-size: 16.00pt";


        NSKern = 0;


        NSParagraphStyle = "Alignment 4, LineSpacing 0, ParagraphSpacing 0, ParagraphSpacingBefore 0, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 20/0, LineHeightMultiple 0, LineBreakMode 0, Tabs (\n), DefaultTabInterval 36, Blocks (\n), Lists (\n), BaseWritingDirection 0, HyphenationFactor 0, TighteningForTruncation NO, HeaderLevel 0";


        NSStrokeColor = "UIDeviceRGBColorSpace 0 0 0 1";


        NSStrokeWidth = 0;


    }


    {


        NSColor = "UIDeviceRGBColorSpace 0 0 0 1";


        NSFont = "<UICTFont: 0x7963fe50> font-family: \"Times New Roman\"; font-weight: normal; font-style: normal; font-size: 12.00pt";


        NSKern = 0;


        NSParagraphStyle = "Alignment 4, LineSpacing 0, ParagraphSpacing 0, ParagraphSpacingBefore 0, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 15/0, LineHeightMultiple 0, LineBreakMode 0, Tabs (\n), DefaultTabInterval 36, Blocks (\n), Lists (\n), BaseWritingDirection 0, HyphenationFactor 0, TighteningForTruncation NO, HeaderLevel 0";


        NSStrokeColor = "UIDeviceRGBColorSpace 0 0 0 1";


        NSStrokeWidth = 0;


    })


     

  • La même chose au format de document Plain :


     



     


    Optional(Sushi Power{


        NSFont = "<UICTFont: 0x7aaf8070> font-family: \".SFUIText-Regular\"; font-weight: normal; font-style: normal; font-size: 12.00pt";


    })


     


     


    Beaucoup plus raisonnable sur l'occupation mémoire, mais si triste à  l'affichage !

  • En fait, ils fixent les valeurs par défaut de formattage au moment où tu génères ton texte enrichi.

    Cela permet d'avoir un texte qui aura la même apparence partout. A opposer à  une autre méthode qui constisterait à  n'inclure aucune valeur par défaut et à  laisser chaque programme consommateur du texte appliquer ses valeurs par défaut.

    Je ne crois pas qu'il y ait de bonne solution à  ce problème.


    Cependant, il y a quand même un soucis, c'est que la valeur par défaut de la police est "Helvetica" alors qu'on est passé en "San Francsisco" sur tous les systèmes Apple. Tu pourrais soumettre un radar pour ça.

    Quant à  la taille finale, ils pourraient éviter de mettre des valeurs par défaut quand ces valeurs sont zéro et que zéro a un sens pour la valeur (HeadIdent 0, Tailleident0, etc.) Je pense que c'est une juste un raccourci du développeur qui écrit toujours le contenu de sa structure interne en serialisation, que les valeurs ait été positionnées à  des valeurs significatives ou non.


    En général, en pratique, on s'en fout car les tailles que tu cites sont faibles.
    Cela dit sur du Bluetooth low energy, par exemple, cela commence à  compter.
  • Je vais reprendre mon idée initiale :


    Modifies-tu le texte ?


    Car sinon, tu pourrais juste sauvegarder des strings qui contiennent les balises. Cela sera moins lourd à  sauver, mais il y a aura toujours un petit temps à  faire le parsing/init à  partir de HTML ou autre.


     


    Autre solution, combien "d'effets" différents gères-tu ? S'il y en a très peu, un serializer pourrait être intéressant, tu gardes le texte, et des attributs (isBold, isItalic, etc.à ) sur les ranges adéquates.




  • Cependant, il y a quand même un soucis, c'est que la valeur par défaut de la police est "Helvetica" alors qu'on est passé en "San Francsisco" sur tous les systèmes Apple. Tu pourrais soumettre un radar pour ça.




    Oui enfin d'un autre coÌ‚té Helvetica n'était pas la police par défaut pour les interfaces d'OSX mais bien Lucida Grande. 


    Helvetica a, par contre, toujours été la police par défaut pour la saisie de texte. On peut donc s'économiser un radar...



  • S'il y en a très peu, un serializer pourrait être intéressant, tu gardes le texte, et des attributs (isBold, isItalic, etc.à ) sur les ranges adéquates.




    C'est la solution vers laquelle je me tourne en ce moment, un string, et deux tableaux pour garder les ranges des isBold et isItalic. Ce qui permet de stocker la "forme structurelle" du texte et de fabriquer un NSAttributedString à  la demande avec différentes polices.

  • Oui enfin d'un autre coÌ‚té Helvetica n'était pas la police par défaut pour les interfaces d'OSX mais bien Lucida Grande. 
    Helvetica a, par contre, toujours été la police par défaut pour la saisie de texte. On peut donc s'économiser un radar...


    Merci pour la précision, j'avais oublié Lucida Grande.
    Mais en fait, pour la police système, je pensais au retour de systemFontOfSize. Cela m'aurait paru logique que la police utilisée soit la même, mais je ne savais pas qu'il y avait une police différente pour l'édition de texte. Du coup comment récupère-t-on cette dernière par API ?
    Parce que j'avoue que j'utilisais toujours systemFontOfSize que ce soit pour de l'affichage ou de l'édition.


  • En fait, ils fixent les valeurs par défaut de formattage au moment où tu génères ton texte enrichi.


    Cela permet d'avoir un texte qui aura la même apparence partout. A opposer à  une autre méthode qui constisterait à  n'inclure aucune valeur par défaut et à  laisser chaque programme consommateur du texte appliquer ses valeurs par défaut.

     




     


    Non, justement. Ils ne fixent pas les valeurs de formatage par défaut au moment de la création du texte enrichi, uniquement pendant la génération d'un NSData au format de document RTF ou HTML. Je présume que c'est plus une question d'entête de fichier RTF/HTML que du NSAttributedString lui-même. 


     


    Quand c'est un NSData au format de document Plain, le système se contente de lui associer une font par défaut, si aucune n'est déjà  présente.

  • AliGatorAliGator Membre, Modérateur

    La même chose au format de document Plain :
     
     
    Beaucoup plus raisonnable sur l'occupation mémoire, mais si triste à  l'affichage !

    Lol c'est avec un print console que tu mesures l'occupation mémoire, toi ?

    Il y a une grosse différence entre la taille sérialisée sur disque (surtout en RTF, qui est un format plutôt dense contrairement à  l'HTML) et la taille du texte affichée dans la console quand tu imprimes la debugDescription de ton objet... pas très pertinent comme comparaison.

    Et quitte à  faire des comparaisons, il faut les faire sur des textes de longueurs variables et variés (par exemple plusieurs tailles de Lorem Ipsums), car par exemple si le format a un prologue / header qui prend 1Ko, bah sur un texte de 200 caractères ça va te sembler énorme tu vas dire que ça fait du x6, alors que sur un texte de 500 mots ça va devenir ridicule.
  • DrakenDraken Membre
    février 2016 modifié #25


    Lol c'est avec un print console que tu mesures l'occupation mémoire, toi ?




    Bin non, je mesure l'occupation mémoire des NSData avec l'opérateur lenght. Le print console c'est pour voir ce qui peut bien trainer dans le NSAttributedString, avant et après l'encapsulation dans le NSData.


     



     


     


    Beaucoup plus raisonnable sur l'occupation mémoire, mais si triste à  l'affichage !

    Le format Plain est triste à  l'affichage à  cause de la perte des attributs d'enrichissement, pas suite à  un log console presque vide. 


     




    Et quitte à  faire des comparaisons, il faut les faire sur des textes de longueurs variables et variés (par exemple plusieurs tailles de Lorem Ipsums), car par exemple si le format a un prologue / header qui prend 1Ko, bah sur un texte de 200 caractères ça va te sembler énorme tu vas dire que ça fait du x6, alors que sur un texte de 500 mots ça va devenir ridicule.




     


    Oui, un petit entête est négligeable sur un texte de 500 mots, mais sur un texte de 50 ou même de 20 mots ? Imagine qu'il s'agisse d'un quiz style Trivial Pursuit avec des milliers de questions courtes.


     


    "En quelle année s'est déroulée la bataille de Marignan ?" (11 mots)


    "1286" (1 mot)


    "1515" (1 mot)


    "1674" (1 mot)


     


    "Où s'est déroulée la bataille de Marignan ?" (9 mots)


    "Du coté de Milan" (4 mots)


    "A Chartres" (2 mots)


    "Sur la frontière espagnole" (4 mots)


     


    "Qui a gagné la bataille de Marignan ?" (8 mots)


    "Les Prussiens" (2 mots)


    "Les Français" (2 mots)


    "Les Mercenaires Suisses" (3 mots)


     


    Si le petit entête négligeable se retrouve avec chaque question/réponse, il vas prendre une place colossale par rapport aux données utiles.


  • Bah alors si c'est que pour rendre du texte stocké mais qui ne sera pas saisi utilise du markdown...


     


    J'ai justement un petit framework qui traine: sur Github. La fonction commonMarkToHTML te permettra très facilement de transformer tout ça à  la volée. Ensuit tu récupère un String HTML que tu peux convertir en NSAttributedString.


     


    ça fait que "En quelle année s'est déroulée la *bataille de Marignan* ?" donnera "En quelle année s'est déroulée la bataille de Marignan ?" ou encore "**Mauvaise** réponse !" s'affichera "Mauvaise réponse !'


     


     


    (D'ailleurs en parlant de Markdown l'éditeur de CocoaCafé ne pourrait pas le supporter avec un plugin IP Board ? Oui je sais que c'est du boulot...)


  • Du coup comment récupère-t-on cette dernière par API ?


    Un mal pour un bien.
    NSFont.userFontOfSize renvoie Helvetica 12pt sous OSX 10.11, pas testé sous iOS.
  • DrakenDraken Membre
    février 2016 modifié #28

     



    Bah alors si c'est que pour rendre du texte stocké mais qui ne sera pas saisi utilise du markdown...


     




     


    J'y ai pensé, mais le markdown n'est pas à  la portée de tous. Si je demande par exemple a un historien de me rédiger 200 questions, il sais se servir d'un traitement de textes, pour taper du texte de manière classique, pas forcément du markdown. Même chose pour un prof d'anglais, de physique, de sports, un photographe, un avocat, un peintre, etc .. Les données doivent être saisies sous une forme naturelle et directement lisible par leur créateurs, pour éviter les erreurs ici et là . 


     


    Tu vas me dire "c'est affiché de manière naturelle avec un éditeur markdown". Ce qui n'est pas d'une grande utilité avec un type ne connaissant que son traitement de texte (Word généralement) et qui n'a pas l'intention d'en changer et de prendre de nouvelles habitudes juste pour taper une série de questions.


     


    J'ai eu de très mauvaises expériences à  l'époque où je bossais avec Ubi Soft en bossant avec des graphistes. Même en rédigeant un cahier de charges précis, style "Je veux 12 images de 48x48 pixels, représentant tel mouvement de ce personnage. Cela doit utiliser les  16 couleurs suivantes (il y a 25 ans, les contraintes de couleurs étaient terribles avec les cartes graphiques EGA et VGA, sans parler de l'Atari ST ou de l'Amstrad CPC). Les graphismes doivent être placés sur une image sur les positions suivantes : ....." On se retrouvais souvent avec une ou deux images de 48x52 pixels, parce que c'était plus "joli", ou des graphismes positionnés à  quelques pixels de l'endroit demandé, ou carrément très loin. Et il fallait reprendre les fichiers graphiques à  la main, avec un logiciel de dessin.

  • @Draken: De toute manière tu vas devoir traiter les données brutes que tu vas recevoir non ? Admettons que tu reçoive un document Word, meÌ‚me si tu peux initialiser une NSAttributedString depuis un document word (AppKit only il me semble) il va quand meme falloir que tu découpe le tout et que tu mette ça dans un modeÌ€le...


     


    À moins que tu ne demande à  tes fournisseurs de contenu de te filer directement des plist correctement formatées il va falloir que tu fasse une moulinette. Je suis prêt à  t'aider pour cette partie là .


  • DrakenDraken Membre
    février 2016 modifié #30

    Un fichier word avec juste du texte ça se transforme facilement en RTF.


     


    Il n'est évidemment pas question de demander à  des non-informaticiens de fournir des plist ou des fichiers XML avec balises. Un format simple comme celui-ci peut suffire :


     



     


    Question A


    Bonne Réponse


    Réponse 2


    Reponse 3


     


    Question B


    Bonne Réponse


    Réponse 2


    Réponse 3


     

    Question C

    Bonne Réponse


    Réponse 2


    Réponse 3


     


    En se basant sur les lignes vides pour séparer les questions.


     


    Vous m'avez déjà  grandement aidé, toi, Ali et FKDEV pour le découpage d'un RTF en tableau de NSAttributedString, dans ce topic :


     http://forum.cocoacafe.fr/topic/13581-probablement-resolu-swift-chargement-dun-fichier-rtf-dans-un-tableau-de-nsattributedstring/?hl=nsattributedstring


     

    Je précise que l'objectif final n'est pas de créer un quizz. C'est juste une analogie pour illustrer un aspect technique rencontré dans un autre projet. A chaque problème, je cherche des analogies simples pour les expliquer. Je comprend mieux les bidules techniques avec des petits exemples. Et c'est plus éducatif pour les débutants parcourant le forum.
  • Oui je comprends mieux maintenant.


    Mais néanmoins je pense qu'on touche quand même à  une chose importante ici c'est qu'il y aura toujours plusieurs manières de faire quelque chose (chaque personne ayant posté ici a apporté au moins une méthode). Le vrai challenge est de savoir quelle méthode est la mieux adaptée à  ce qu'on veut réellement faire. 


     


    Alors je te pose la question: qu'est-ce que tu veux réellement faire ?


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