[Résolu] Problème d'affichage de caractères accentués turques...

LeChatNoirLeChatNoir Membre, Modérateur
janvier 2011 modifié dans API UIKit #1
Salut,

Je viens de me prendre le chou 2 heures sur des caractères accentués turques... !
Je comprend vraiment pas comment je peux résoudre mon affaire.
J'en appelle presque directement à  Ali car je sais que l'encodage, il maitrise sur le bout des doigts.
Bon je sais aussi qu'il est bien occupé donc si une âme charitable veut bien étudier la question..

Alors voilà , dans ma base Sql, le libellé est stocké en utf8.
Je l'extrait en utf8 et le transmet à  mon appli sous forme de NSData.
Une fois le Dl terminé, je serialise ça dans une propertyList (mon select extrait mes données sous forme de property list genre <array><dict>...</dict></array>).

Tout ça fonctionne à  merveille. Sauf pour les caractères turques...
NiÄŸde par exemple, se transforme en Ni?de...

Et là , j'avoue que je sèche... Peut être que je fatigue mais bon, j'ai retourné le truc dans tous les sens, je sais plus comment avancé...

Les caractères espagnols par exemple comme le i accentué passe très bien.
Mais là , le ÄŸ ou le ı turcs passent pas...

Il doit bien y avoir une solution ? Au secours  :'(



Réponses

  • AliGatorAliGator Membre, Modérateur
    06:27 modifié #2
    Suis fatigué aussi donc pas le temps d'y réfléchir, mais met des logs (de tes NSData et du NSString construit à  partir de ce NSData interprété en UTF8) aux différentes étapes de ton appli (lecture depuis la base : est-ce que là  tu récupères des données qui sont OK avec les accents qui s'affichent bien ? ensuite stockage dans ton plist, si tu l'ouvres avec PropertyListEditor il t'affiche les caractères correctement ?)

    A chaque itération, quand je te dis "met des logs" à  la limite ça serait même mieux de mettre les données dans un UILabel même, car si tu utilises NSLog, qui affiche dans la console, tu peux avoir des problèmes, la console n'étant qu'un simple terminal de sortie de texte en général ASCII, il n'arrive pas toujours à  afficher correctement les caractères UTF8... quoique dans ce cas normalement il t'affiche \uXXXX à  la base avec XXXX le codepoint du caractère Unicode, pas un "?" à  la place du caractère, mais bon.
  • laudemalaudema Membre
    06:27 modifié #3
    Sur le point précis des logs dans la console on peut utiliser printf ("%s\n", [turkishWord UTF8String]);
    printf sait écrire les accents dans la console quand NSLog ne sait pas.
  • LeChatNoirLeChatNoir Membre, Modérateur
    06:27 modifié #4
    Salut et merci pour vos réponses nocturnes !

    En fait, le ? s'affiche dans un label effectivement.
    Dans la log, via NSLog, j'ai Ni\U00c4\U009fde

    Ca m'a l'air correct.... Faudrait que je check les codes mais j'ai pas trouvé où le faire...
    Par contre, dans un label, ca se transforme en Nià„?de...

    Ca peut pas être une histoire de police qui n'a pas le caractère accentué en question ? (c'est la police standard des UILabel...)

    A+
  • FKDEVFKDEV Membre
    janvier 2011 modifié #5
    dans 1294383295:

    Ca m'a l'air correct.... Faudrait que je check les codes mais j'ai pas trouvé où le faire...


    http://www.fileformat.info/info/unicode/char/11f/index.htm
    http://www.unicode.org/charts/index.html

    Ton caractère est bien 0xc49f en utf8 mais le code unicode est \u+011F.

    Dans le log tu devrait avoir NI\U011Fde.
    Donc je suppose que ton caractère stocké en utf8 a été réencodé en utf8 quelque part.

  • LeChatNoirLeChatNoir Membre, Modérateur
    06:27 modifié #6
    nan. J'ai essayé de le sortir en utf8 dans mon select et c'est pire.
    Chaque caractère accentué est alors composé de 2 séquences de \uXXXX

    Merci pour le lien, je regarde...
    C'est casse tête ce truc !
  • muqaddarmuqaddar Administrateur
    06:27 modifié #7
    dans 1294395210:

    C'est casse tête ce truc !


    Je dirais même plus : c'est casse tête ce turc !
  • LeChatNoirLeChatNoir Membre, Modérateur
    06:27 modifié #8
    :D :D :D
  • AliGatorAliGator Membre, Modérateur
    janvier 2011 modifié #9
    Il s'agit certainement de la forme décomposée (NFD) et non précomposée (NFC) de ton caractère.
    C'est même très problable pour un caractère si peu fréquent que ton caractère turc.

    En gros en Unicode des caractères accentués comme "é" peuvent être codés sous la forme précomposée ("NFC") d'un caractère déjà  tout prêt qui s'appelle "e accent aigu", en gros... ou peuvent être codés sous forme décomposée (NFD) du code point "un caractère e" puis du codepoint "rajouter un accent aigu sur le caractère précédent" (bon c'est peut-être dans l'ordre inverse, accent puis caractère, je sais plus mais bref).

    Du coup si tu t'attendais à  un caractère de codepoint U+011F mais que tu te retrouves avec deux octets/codepoints unicodes U+00C4 + U+9FDE, ce n'est pas forcément une erreur. Il a peut-être été transformé en sa forme décomposée à  un moment donné (par mysql ? ou à  une autre étape de ton processus ?). Ce qu'il faut c'est vérifier dans les tables unicodes à  quoi correspondent ces deux codepoints que tu as, en particulier vérifier que l'un est une diacritique (l'accent) et l'autre la lettre brute (sans accent) qui, si tu les assemblent, donnent bien le glyphe / la lettre que tu espères.

    Si oui alors y'a pas de problème (et un bug d'affichage peut-être, mais ta chaà®ne serait alors correcte au sens Unicode).
    Si non alors l'étape qui décompose ton caractère NFC en sa forme NFD se foire peut-être, en décomposant mal ton caractère précomposé en 2 mauvais codepoints. Si c'est par exemple mysql qui fait cette décomposition en interne, peut-être faut-il regarder de plus près les bugreports (si c'est un bug connu) ou jouer avec l'interclassement utilisé dans ta base MySQL (utf8_bin au lieu de utf8_general par exemple)
  • LeChatNoirLeChatNoir Membre, Modérateur
    06:27 modifié #10
    ???????
    B)
  • muqaddarmuqaddar Administrateur
    06:27 modifié #11
    dans 1294397371:

    ???????
    B)


    Ali, tu nous as rendu notre chat noir à  la mine décomposée.
  • AliGatorAliGator Membre, Modérateur
    06:27 modifié #12
    J'ai édité mon post entre temps avec plus de détail et d'explications.
  • muqaddarmuqaddar Administrateur
    06:27 modifié #13
    Je pense un peu comme Ali depuis le début : le problème viendrait de l'export de la table plutôt que de Cocoa.

    En mysql, j'utilise utf8_unicode_ci.

    Tu peux faire des test en exportant directement depuis PMA par exemple ?
  • FKDEVFKDEV Membre
    06:27 modifié #14
    Le frimeur... J'y ai pensé aussi à  la forme décomposé.
    Mais je répète : il s'agit d'un double encodage quelque part.
    la preuve :

    ÄŸ = U+011F = C49F en utf8.

    Comme par hasard ton log t'affiche \u00C4\u009F.
    C'est donc que ta chaine contient les caracteres unicode C4 (A trema) et 9F encodé en utf8.

    Est-ce que tu passes par une conversion en json ou xml qui pourrait ajouter un encodage ?
  • LeChatNoirLeChatNoir Membre, Modérateur
    06:27 modifié #15
    'tin vous êtes calés les gars. Je suis tjs impressioné !
    Merci pour toutes ces réponses.

    Je creuserai le sujet quand je serai un peu reposé (en ce moment, je bosse pas mal sur la V1.1 de mon appli et je suis d'astreinte côté taf "réel" !) donc je dors pas bcp...

    Je creuserai donc chaque point (extraction de la base, xml et récup' cocoa) et je vous tiendrai au jus.

    En gros, en php, je lance mon select (pas de characterset particulier. Par défaut, utf8) et je fais un echo en php...
    C'est la chaine résultante que je récupère.

    C'est pas propre ?
    J'avoue que je suis pas très calé en WS donc j'y suis allé un peu à  l'ancienne....
    :-)
  • AliGatorAliGator Membre, Modérateur
    06:27 modifié #16
    Ah ouais... vérifie aussi que ton PHP est enregistré en UTF8 (et si ton éditeur de texte de propose "UTF8" ou "UTF8 No BOM", surtout pour du PHP prend sans BOM sinon tu auras des problèmes)
    Car si ton PHP est pas enregistré en UTF8, quand il va récupérer les données de mysql et faire son print ensuite, il va corrompre les données... Il faut vraiment que toute ta chaà®ne utilise le même encodage.
  • FKDEVFKDEV Membre
    06:27 modifié #17
    Je ne suis pas très calé en php mais j'ai trouvé ça sur stackoverflow:

    You've already mentioned that your DB table collation and editors are set properly. But there are more places where you need to check to make sure that everything is properly UTF-8:

    -Make sure that you are serving your HTML as UTF-8:
    header("Content-Type: text/html; charset=utf-8");

    -Change your PHP default charset to utf-8:
    ini_set("default_charset", 'utf-8');

    -if your database doesn't ALWAYS talk in utf-8, then you may need to tell it on a per connection basis to ensure it's in utf-8 mode, in MySQL you do that by issuing:
    charset utf8

    -You may need to tell your webserver to always try to talk in UTF8, in Apache this command is:
    AddDefaultCharset UTF-8

    Finally, you need to ALWAYS make sure that you are using PHP functions that are properly UTF-8 complaint. This means always using the mb_* styled 'multibyte aware' string functions. It also means when calling functions such as htmlspecialchars(), that you include the appropriate 'utf-8' charset parameter at the end to make sure that it doesn't encode them incorrectly.

    Source:http://stackoverflow.com/questions/1344692/i-need-help-fixing-broken-utf8-encoding/1348521#1348521
  • LeChatNoirLeChatNoir Membre, Modérateur
    06:27 modifié #18
    Bon ben ça y est, c'est résolu !
    En fait, tous les caractères accentués étranges (norvège, roumanie, turquie...) étaient impactés.
    Vous aviez raison, c'était bel et bien un pb d'encodage.
    J'ai résolu le pb en :
    * encodant le .php en UTF8 (là , je suis pas sûr que ce soit obligé mais bon),
    * mettant la directive mysql_query("SET NAMES 'utf8'"); qui assure que le select va bien me sortir de l'UTF8
    * enlevant la fonction utf8_encode que j'utilisais (qui transcode de latin à  utf8 mais comme c'était déjà  de l'UTF8 en base...).

    Merci à  tous !
    A+
Connectez-vous ou Inscrivez-vous pour répondre.