iOS 说不能解析这样的 JSON? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
salamanderMH
V2EX    问与答

iOS 说不能解析这样的 JSON?

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

    题目描述

    返回的 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 感觉楼主是个新手,我这边后端接口要是出这样的数据可能会被我怼死。。。
    nxforce
        24
    nxforce  
       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 ?
    rb6221
        37
    rb6221  
       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     Solana     5337 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 31ms UTC 08:27 PVG 16:27 LAX 01:27 JFK 04:27
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86