q409195961
V2EX  ›  iOS

iOS 下,如何解析接口传回的 emoji 表情??

  •  
  •   q409195961 · Sep 22, 2017 · 4348 views
    This topic created in 3162 days ago, the information mentioned may be changed or developed.

    问题是这样的,在请求中发送 emoji 表情到接口,无论是直接发还是转码成 Unicode 再发,接口返回的就变成"������",导致解析不了

    网络请求返回的 NSData,转 NSDict 报错“ Code=3840 Unable to convert data to string around character 481.”,转 NSString(UTF8)返回也 nil。

    然后让后端把 MySQL 的编码 utf8mb4,还是不行

    关键是安卓能显示,iOS 显示不了,直接走网络错误,然后后端就不配合了,让我们自己想办法解决

    17 replies    2017-09-23 22:48:31 +08:00
    laoyur
        1
    laoyur  
       Sep 22, 2017
    接口返回就已经是\ufffd 了,那果断服务端的锅啊,你返回一个「 replacement character 」(就是上面的�),居然还指望客户端能显示出 emoji 来?
    q409195961
        2
    q409195961  
    OP
       Sep 22, 2017
    @laoyur 但安卓特么就显示出来了,感觉好奇怪
    laoyur
        3
    laoyur  
       Sep 22, 2017   ❤️ 1
    光看你这个截图,貌似返回的 json 里面,混杂了 utf32 和 utf8 两种编码?
    抓包把返回的数据扔上来才能下定论,包括 content-type 啥的所有 headers
    b821025551b
        4
    b821025551b  
       Sep 22, 2017
    半年前踩过这个坑,接口不能转义 unicode 字符,iOS 那边不干。
    但是你这个接口的截图,是\ufffd 啊,本身就是无效 emoji,怎么显示?
    还是抓包看看 android 和你的接口原始数据有什么不同吧。
    q409195961
        5
    q409195961  
    OP
       Sep 22, 2017
    @laoyur
    这个 Charles 抓的报文,Postman 发的请求
    https://i.loli.net/2017/09/22/59c476297f15e.png
    laoyur
        6
    laoyur  
       Sep 22, 2017
    切换到 Hex 显示,发截图来看看,怀疑 commentContext 传的字符串并不是有效的 utf8 编码
    laoyur
        8
    laoyur  
       Sep 22, 2017
    看上面截图,�一共显示了 6 个,然后看此帖,\ufffd 一共 18 个,那不就是把「\ufffd\ufffd\ufffd 」当做一个 utf8 字符了嘛
    传过来的数据错了,并不是 utf8 编码,服务端的锅
    vmebeh
        9
    vmebeh  
       Sep 22, 2017
    试了一下 hex,是“😒😒😒”

    \xed\xa0\xbd\xed\xb8\x92\xed\xa0\xbd\xed\xb8\x92\xed\xa0\xbd\xed\xb8\x92
    laoyur
        10
    laoyur  
       Sep 22, 2017
    Hex 看上去是有效的 utf8 码流
    @vmebeh \xed\xa0\xbd\xed\xb8\x92\xed\xa0\xbd\xed\xb8\x92\xed\xa0\xbd\xed\xb8\x92 这段当做 utf8 来解析的话,对应上面 三个 emoji 字符?不对吧,怎么解的呢
    laoyur
        11
    laoyur  
       Sep 22, 2017
    >>> a = b'\xed\xa0\xbd\xed\xb8\x92\xed\xa0\xbd\xed\xb8\x92\xed\xa0\xbd\xed\xb8\x92'
    >>> print a.decode('utf-8')
    😒😒😒

    的确是这三个笑脸,不过我还是没懂怎么会解析成这么三个字符,求高人指点
    vmebeh
        12
    vmebeh  
       Sep 22, 2017
    @laoyur

    #coding: utf-8

    from Tkinter import Tk
    r = Tk()
    r.withdraw()
    r.clipboard_clear()
    r.clipboard_append('\xed\xa0\xbd\xed\xb8\x92\xed\xa0\xbd\xed\xb8\x92\xed\xa0\xbd\xed\xb8\x92'.decode('utf-8'))
    r.update()
    r.destroy()

    python2,搜的复制代码……
    q409195961
        13
    q409195961  
    OP
       Sep 22, 2017
    @laoyur
    >>> a = b'\xf0\x9f\x98\x92\xf0\x9f\x98\x92\xf0\x9f\x98\x92'
    >>> print a.decode('utf-8')
    😒😒😒


    \xf0\x9f\x98\x92\xf0\x9f\x98\x92\xf0\x9f\x98\x92
    才能解析出来吧
    laoyur
        14
    laoyur  
       Sep 22, 2017
    minbaby
        16
    minbaby  
       Sep 23, 2017
    ```
    <?php

    $a = ['key' => '😄 👹'];

    $b = json_encode($a);

    $c = json_decode('{"key":"\ud83d\ude04 \ud83d\udc79"}');

    var_dump($a, $b, $c);
    ```



    ```
    [Running] php "/tmp/a.php"
    array(1) {
    ["key"]=>
    string(18) "😄 👹"
    }
    string(44) "{"key":"\ud83d\ude04 \ud83d\udc79"}"
    object(stdClass)#1 (1) {
    ["key"]=>
    string(18) "😄 👹"
    }
    ```

    这种问题之前数据库编码没整对会有问题,编码问题好了就没问题了。看返回的确是有问题,正常的应该是一个 emoji 对应两个 \u 也就是 utf8
    minbaby
        17
    minbaby  
       Sep 23, 2017
    @minbaby @q409195961 只需要用正确的 json 用 oc 解析一下就好了,看看是 oc 解析问题还是返回数据问题。这是需要先确认的
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   1452 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 36ms · UTC 17:02 · PVG 01:02 · LAX 10:02 · JFK 13:02
    ♥ Do have faith in what you're doing.