V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
salamanderMH
V2EX  ›  问与答

iOS 说不能解析这样的 JSON?

  •  
  •   salamanderMH · 2019-01-11 10:38:45 +08:00 · 5911 次点击
    这是一个创建于 2148 天前的主题,其中的信息可能已经有所发展或是发生改变。

    题目描述

    返回的 json 格式如下

    {
        "status": 1,
        "content": "get seats info successfully !",
        "data": {
            "seats": {
                "1": {
                    "nickname": "salamander",
                    "avatar": "*******************",
                    "uid": 5464
                },
                "3": {
                    "nickname": "coopk、",
                    "avatar": "***********************",
                    "uid": 54645645
                }
            }
        }
    }
    

    他说,seats中的数据不能以 1,3 这样的数字,无法解析,请教一下大家

    74 条回复    2019-01-12 17:54:13 +08:00
    yu5121199
        1
    yu5121199  
       2019-01-11 10:44:42 +08:00
    这个格式解析.确实麻烦一些。看需求了。
    seats 为什么不能是个数组。
    salamanderMH
        2
    salamanderMH  
    OP
       2019-01-11 10:47:14 +08:00
    @yu5121199
    我想用 hash 表的 key 对应每个座位位置
    他需要一个 Model,说不能用 1,2,这样的数字
    66beta
        3
    66beta  
       2019-01-11 10:50:25 +08:00 via Android
    解析式肯定可以的,但我觉得 seats 是数组才合理,配以 seatId:1
    gzf6
        4
    gzf6  
       2019-01-11 10:51:04 +08:00
    可以解析,不过把 seats 变成数组,里面放 id 也可以。
    jinksw
        5
    jinksw  
       2019-01-11 10:51:50 +08:00
    你这 json 格式正确呀 为啥不能解析
    key 会动态变吗? 比如有的 seats 只有"1","3"?有的只有"2","4"?
    suzic
        6
    suzic  
       2019-01-11 10:54:02 +08:00 via Android
    这种不光 ios 麻烦吧,楼上建议就可以,改成求组,key 放进去
    salamanderMH
        7
    salamanderMH  
    OP
       2019-01-11 10:54:05 +08:00
    @66beta
    他说 model 不能用 1,2,这样的数字做 key
    suzic
        8
    suzic  
       2019-01-11 10:54:30 +08:00 via Android
    @suzic 数组
    geelaw
        9
    geelaw  
       2019-01-11 10:56:37 +08:00 via iPhone
    @salamanderMH #7 model 和 JSON 是两回事儿,最不济先拿到 dictionary/map 再按照这种方式填上去。
    jinksw
        10
    jinksw  
       2019-01-11 10:57:04 +08:00
    @salamanderMH 你这 json 格式正确 从 json 角度来说可以做 key
    但是客户端一般会用一个库自动将 json 转换成一个对象
    在定义这个对象类的时候 因为语法 不能用纯数字 做变量名,所以他会跟你那么说
    想解决也是可以的,不过你这个最好定义个数组吧,把 id 放到每个 seat 里去
    justahri
        11
    justahri  
       2019-01-11 10:58:15 +08:00
    "data": [
    {
    "nickname": "salamander",
    "avatar": "*******************",
    "uid": 5464,
    "seats": "1"
    },
    {
    "nickname": "coopk、",
    "avatar": "***********************",
    "uid": 54645645,
    "seats": "3"
    }
    ]

    这样不好吗
    wysnylc
        12
    wysnylc  
       2019-01-11 10:58:36 +08:00
    ![]( )
    你这是字符串不是数字,的确前端 json 中 key 不兼容数字但你这不是
    jason19659
        13
    jason19659  
       2019-01-11 10:59:13 +08:00
    key 是固定的就可以
    finab
        14
    finab  
       2019-01-11 11:01:50 +08:00
    固定数字做 Key 是可以的,数字不能做字段名但可以 map
    例如 ObjectMapper 中 key1 <- map["1"] 这种

    不过你这种结构不能很好的解析成 Model,你的 key 是不固定的,只能把 seats 下当成字典来用
    salamanderMH
        15
    salamanderMH  
    OP
       2019-01-11 11:04:51 +08:00
    @finab
    key 是 1-6 的(取值是固定的),我只是想返回一个 hashtable 而已
    bbbb
        16
    bbbb  
       2019-01-11 11:07:20 +08:00 via iPhone
    他我觉得他的意思是设置 model 的时候属性不能为数字。他可以转换,你也可以改。
    salamanderMH
        17
    salamanderMH  
    OP
       2019-01-11 11:09:01 +08:00
    @bbbb
    感谢,我知道了
    cpdyj0
        18
    cpdyj0  
       2019-01-11 11:09:47 +08:00 via Android   ❤️ 1
    虽然符合 JSON 语法,但是 parse 起来很麻烦,很难直接映射到对象
    learnshare
        19
    learnshare  
       2019-01-11 11:11:54 +08:00
    seats 应该是个数组 /列表,编号属于每个成员

    不过这个结构问题不大,可以解析,然后转换为需要的格式就好了
    cnbobolee
        20
    cnbobolee  
       2019-01-11 11:15:42 +08:00
    这个不是不能解析的问题吧,只是你如果要 model 的话,怎么设计,key 是动态的,放到哪个语言也不能解析。设计有问题
    0x000007
        21
    0x000007  
       2019-01-11 11:35:31 +08:00
    11 楼那种很好,你这种没法直接转 Model,还要多操作一步
    0x000007
        22
    0x000007  
       2019-01-11 11:37:14 +08:00   ❤️ 1
    好奇这种 json 格式安卓那边没问题?好像安卓那边更恶心这种格式
    cc85060
        23
    cc85060  
       2019-01-11 11:50:38 +08:00   ❤️ 3
    @0x000007 感觉楼主是个新手,我这边后端接口要是出这样的数据可能会被我怼死。。。
    joyhub2140
        24
    joyhub2140  
       2019-01-11 11:53:13 +08:00
    解析没问题,不过设计有问题,seats 应该是一个数组,那些 key 如 1,3,应该作为 position 弄到 bean 属性里。
    maplejaw
        25
    maplejaw  
       2019-01-11 12:02:14 +08:00 via Android
    这种格式你必须保证 key 只有 1,3。否则建议 11 楼的格式。
    holonunu
        26
    holonunu  
       2019-01-11 12:13:55 +08:00
    @salamanderMH 可以解析,model 中 key 不能是数字。

    但是!!!

    可以把 model 中的 key 定为 key1、key2、key3,解析的时候映射一下:

    1 -> key1
    2 -> key2
    3 -> key3

    我猜你这个同事要么是嫌麻烦要么就是没了解第三方的 json-model 框架。
    Vegetable
        27
    Vegetable  
       2019-01-11 12:20:07 +08:00

    不推荐
    dremy
        28
    dremy  
       2019-01-11 12:48:42 +08:00 via iPhone
    如果 id 是订单号这种超长的数字串,做成 key 也不能解析???
    objective-c 和 swift 这么弱的嘛
    dremy
        29
    dremy  
       2019-01-11 12:56:33 +08:00 via iPhone
    @cnbobolee
    动态语言先了解一下
    静态语言的话,Java 有 Map,Go 有 interface{} 怎么不能解析?
    xqc6321
        30
    xqc6321  
       2019-01-11 13:03:13 +08:00 via Android   ❤️ 1
    这不是嫌麻烦的问题。
    这是操蛋的问题。
    严重同意 23 楼
    salamanderMH
        31
    salamanderMH  
    OP
       2019-01-11 13:06:30 +08:00
    结贴吧
    zr8657
        32
    zr8657  
       2019-01-11 13:15:34 +08:00
    11 楼正解,同意 23 楼
    zqx
        33
    zqx  
       2019-01-11 13:17:43 +08:00 via Android
    ios 不了解,但是大多数语言变量名是不能数字开头的
    Deville
        34
    Deville  
       2019-01-11 13:21:33 +08:00
    这根本不是数据格式能不能解的问题。。。。。。。而是看着闹心。。。
    wly19960911
        35
    wly19960911  
       2019-01-11 13:25:38 +08:00
    理解下,不是 iOS 说格式错误,而是格式解析出来不好用。
    cloverstd
        36
    cloverstd  
       2019-01-11 13:30:21 +08:00
    可以解析,你确定你是 "1" 不是 1 ?
    janus77
        37
    janus77  
       2019-01-11 13:31:00 +08:00 via iPhone
    目测 php 写的,安卓表示这种返回大概率会被怼
    allenhu
        38
    allenhu  
       2019-01-11 13:31:35 +08:00
    某些 json 库确实没法处理这种格式的 JSON,因为它没法 seats.1 这样取出结果,只能 seats.user1 ;所以还是建议换成数组吧,不管是语义上还是格式上,都更加清晰。
    OctWu
        39
    OctWu  
       2019-01-11 13:35:35 +08:00
    能解析啊。

    struct Fuck: Codable {
    var seats: [String: User]
    }

    见过这种,有的公司用组合接口,为了图方便,这个 seats.key 可能下面还有别的用。虽然说客户端写起来是挺烦躁的
    cnbobolee
        40
    cnbobolee  
       2019-01-11 13:44:22 +08:00
    @dremy 看清我的答案再说,说的是要 model 做解析。哎!
    OctWu
        41
    OctWu  
       2019-01-11 13:46:30 +08:00
    @cnbobolee model 也能解析啊。恶心而已
    0x000007
        42
    0x000007  
       2019-01-11 13:58:48 +08:00
    @OctWu 他的意思是 key 不固定的话,model 的属性就没法定吧
    cnbobolee
        43
    cnbobolee  
       2019-01-11 14:07:21 +08:00
    @OctWu 快告诉我,怎么定义这样的 model,我以前也遇到过这样的设计,就是不知道 seats 下面定义个什么字段?
    OctWu
        44
    OctWu  
       2019-01-11 14:24:04 +08:00
    @cnbobolee 我上面写了啊 #39
    OctWu
        45
    OctWu  
       2019-01-11 14:25:06 +08:00
    @0x000007 看这数据是个订座之类的需求。为啥要 key 固定。。。key 就是座位号。value 就是顾客。
    没看明白
    0x000007
        46
    0x000007  
       2019-01-11 14:42:07 +08:00
    struct Fuck: Codable {
    var seats: [String: User]
    }
    转成这样的 model 有什么意义么?直接用[String: User]不是更好么.
    我想楼主的同事是要转成这样的 model
    struct Seats: Codable {
    var key1:User
    var key2:User
    }
    首先这样做肯定是不对的,所以我说 key 不固定的话是没法弄得
    CommandZi
        47
    CommandZi  
       2019-01-11 14:50:55 +08:00
    @cloverstd 肯定是"1",我朋友公司的 PHPer 会返回 {"0": "xx", "1": "xxx"} 这样的 JSON。
    OctWu
        48
    OctWu  
       2019-01-11 14:52:36 +08:00
    @0x000007 这有什么没意义的。我说了能解,只是恶心而已。

    然后下面的那个例子,你自己看下不就是个字典么,你自己都写出来了。

    另外根本就不需要 key 固定,这需求我说了看着就是个订座之类的。不是知道多少号坐,坐的谁就行了么,10 个坐的时候写 10 个 property, 加了 11 个,还需要客户端发版么。

    Fuck().seats.enumerator().forEach 不好么
    icyalala
        49
    icyalala  
       2019-01-11 14:56:10 +08:00
    iOS 解析 JSON,一般都是用一些 JSON-Model 的库来自动处理,并转换为对象的。
    那么对象的属性(变量名称)是不可能使用数字的,所以自动处理肯定无法完成。
    这种情况下,只能手动去处理,非常麻烦而且容易出错。

    另外,#11 楼才是正确做法。
    Damon4V
        50
    Damon4V  
       2019-01-11 14:56:21 +08:00
    楼主改下吧,你这样的动态 key,随便哪一端解析都麻烦,会被喷的:-O
    OctWu
        51
    OctWu  
       2019-01-11 14:56:32 +08:00
    @0x000007 另外有个前提是人家要转 model 啊。我只是提出解决方案,尽可能保证合理,要不就让开发去怼后台呗。
    0x000007
        52
    0x000007  
       2019-01-11 14:58:09 +08:00
    @OctWu 我知道那是字典啊,人家同事想转成这样的 model,不是我要这么做啊,我只是想表达,如果要转成这样的 model,key 不固定根本就没法做嘛
    0x000007
        53
    0x000007  
       2019-01-11 14:59:55 +08:00
    @OctWu 也不是我想表达,是表达 20 楼的意思😂
    greenskinmonster
        54
    greenskinmonster  
       2019-01-11 15:11:24 +08:00
    我也搞过类似的结构,我们 ios 开发也跟我说过 ios 没法自动处理,需要特殊处理下。

    我的目的是让 "1" 这个 key 的数据只有一份,类似于 map 的 key。
    每次 put 的时候不需要再去轮询一遍,检查 id=“ 1 ”的有没有存在,直接 put 就好。

    其实我不明白的是 ,1 是数字,“ 1 ” 是字符串,根本是两回事,干嘛要混为一谈。
    rumengzhenxing
        55
    rumengzhenxing  
       2019-01-11 15:22:34 +08:00
    可以解析,但是这种格式拿出去不管 IOS 还是 Android 都会怼你的。
    bumz
        56
    bumz  
       2019-01-11 15:27:23 +08:00
    json 不能用 number 做 key,但 numeric 的字符串可以
    然而如果要把 json object 变成对象,key 还得是符合英文字母下划线开头的。。。也就是说连 numeric 的字符串都不可以
    bumz
        57
    bumz  
       2019-01-11 15:28:59 +08:00
    至于这种情况,合理的做法显然是用 "seat1", "seat2", ..., "seat6" 来命名
    只有 6 个可能不需要哈希表
    cnbobolee
        58
    cnbobolee  
       2019-01-11 15:32:41 +08:00
    @OctWu 那个 map 忽悠我,当我刚毕业的小学僧
    StubbornC
        59
    StubbornC  
       2019-01-11 15:34:45 +08:00
    楼主写 PHP 的吧,我们老项目也有这种结构的 JSON,被我和安卓同事狂喷好几次
    greenskinmonster
        60
    greenskinmonster  
       2019-01-11 15:43:44 +08:00
    @rumengzhenxing #55

    不是应该去怼 IETF,https://www.ietf.org/rfc/rfc4627.txt ,让他们改标准吗?禁止不合法变量 /函数名做 key 吗,综合 java/javascript/c/c++/go 等各种语言的要求。

    @bumz #56 这是个成本不高的这种折中解决办法。然而我对框架不能支持标准,还振振有词表示不能理解。
    ElvY
        61
    ElvY  
       2019-01-11 15:50:05 +08:00
    严重同意 30 楼,很操蛋。都是你这种的项目维护起来太麻烦了吧
    OctWu
        62
    OctWu  
       2019-01-11 16:13:54 +08:00
    @cnbobolee 有什么区别么。我自己写的话,直接给 response 做成 model

    struct ResponseData<T: Decodable> {
    let data: T
    }

    来个 ResponseData<Fuck>.self 呗

    不就完事了,解决方法千千万,那种 想要

    struct Seats {
    var key1: Seat
    var key2: Seat
    }

    的才是刚毕业的小学生吧。

    如果一个模型需要多个接口返回自己拼的,我一般才爱怼。这种我说了,看需求来说,还真不一定不方便
    reus
        63
    reus  
       2019-01-11 16:52:43 +08:00
    当然能解析,你这个是字符串 "1",又不是数字 1

    在 go 里,用 map[int]struct{...} 或者 map[string]struct{...} 都能正确解析,我不知道什么垃圾语言这都不支持。
    skaly
        64
    skaly  
       2019-01-11 17:20:28 +08:00
    无谓制造所有人的麻烦,搞点符合大多数人认知的东东出来,有些自以为设计很好的东东,增加了很多沟通成本,实现成本,挺不友好的。要是引起项目延期,你来背锅?
    ps:同意 11 楼
    NotNil1
        65
    NotNil1  
       2019-01-11 17:37:46 +08:00
    使用 json 时尽量不要直接把 map 转为 json。
    sanqian
        66
    sanqian  
       2019-01-11 17:47:36 +08:00
    可以是可以,但是你这样没必要。
    cinhoo
        67
    cinhoo  
       2019-01-11 17:53:07 +08:00 via iPhone
    可以,很恶心
    183387594
        68
    183387594  
       2019-01-11 18:02:54 +08:00

    我也遇到过 先和安卓对接的(左) 后来 ios 说取出来会乱序 改成 右边的了😂
    mht
        69
    mht  
       2019-01-11 18:03:51 +08:00
    这个形式 在只用 PHP 和 js 的前端对接情况下 有时候很好用 直接根据 key 去取对应的数据

    最近学了安卓 发现之前自己写的接口 如果是这种形式的话 想对接的确不是很容易 但是也还是可以解决的...
    v2yehen
        70
    v2yehen  
       2019-01-11 18:12:48 +08:00
    讲真,对接碰到这样的数据我会怼死他。
    改成数组万事大吉!
    Leu
        71
    Leu  
       2019-01-12 09:26:20 +08:00
    一看就是新手弄得,好好得数组不用。
    deepSeaCode
        72
    deepSeaCode  
       2019-01-12 09:40:07 +08:00
    iOS 可以解析这样的数据,只是很恶心而已。遇到后台出这样的数据,iOS 老人应该会问后台是不是新人吧。这样的数据只有新手才会这么写,楼主怕不是新手遇新手吧。
    bumz
        73
    bumz  
       2019-01-12 14:52:39 +08:00
    @183387594 #68 字典本来就是无序的
    而且右边也不对,key 每个都不一样
    应该这样

    [{"key": ..., "value": ...}, {"key": ..., "value": ...}]
    loren1994
        74
    loren1994  
       2019-01-12 17:54:13 +08:00
    "1","3"是动态的吧?确实不好解析的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5462 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 43ms · UTC 03:46 · PVG 11:46 · LAX 19:46 · JFK 22:46
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.