V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
q409195961
V2EX  ›  iOS

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

  •  
  •   q409195961 · 2017-09-22 09:23:41 +08:00 · 3825 次点击
    这是一个创建于 2420 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

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

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

    \xed\xa0\xbd\xed\xb8\x92\xed\xa0\xbd\xed\xb8\x92\xed\xa0\xbd\xed\xb8\x92
    laoyur
        10
    laoyur  
       2017-09-22 11:04:26 +08:00
    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  
       2017-09-22 11:12:06 +08:00
    >>> 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  
       2017-09-22 11:15:24 +08:00
    @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
       2017-09-22 11:25:16 +08:00
    @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  
       2017-09-22 11:47:44 +08:00
    laoyur
        15
    laoyur  
       2017-09-22 14:01:04 +08:00
    minbaby
        16
    minbaby  
       2017-09-23 22:46:30 +08:00
    ```
    <?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  
       2017-09-23 22:48:31 +08:00
    @minbaby @q409195961 只需要用正确的 json 用 oc 解析一下就好了,看看是 oc 解析问题还是返回数据问题。这是需要先确认的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3341 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 13:26 · PVG 21:26 · LAX 06:26 · JFK 09:26
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.