一般来说,一个好的命名可以让开发者更快速的明白这个字段所代表的意思,不过有些时候会事与愿违
诡异的命名
这是什么…
恩…对于一个母语为汉语的人或许阅读起来都有一些困难,他们分别代表着
如果不希望在代码中继续沿用这样子的命名,转而采用以下命名
username
userAge
userEmail
userPhone
那该如何让 Swift 这件事
接下来,将介绍 Swift 中的 CodingKey
对该数据建模中,将想使用的名字填入
1 2 3 4 struct User : Codable { let username, userEmail, userPhone: String let userAge: Int }
就像这样,很简单对吧
然后,在结构体 (或者类) 的内部建立一个叫做 CodingKeys 的枚举,该枚举将会是 private 属性修饰并且遵循 CodingKey 协议
完整的结构体如下所示
1 2 3 4 5 6 7 8 9 10 11 struct User : Codable { let username, userEmail, userPhone: String let userAge: Int private enum CodingKeys : String , CodingKey { case username = "yhm" case userAge = "yhnl" case userEmail = "yhyxdz" case userPhone = "yhsjhm" } }
这么做,在 Decode 之后就可以通过 username, userEmail, userPhone 和 userAge 属性来访问这些诡异的命名的字段了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 import Cocoaenum MyError : Error { case invlidUrl case invlidServerResponse } struct User : Codable { let username, userEmail, userPhone: String let userAge: Int private enum CodingKeys : String , CodingKey { case username = "yhm" case userAge = "yhnl" case userEmail = "yhyxdz" case userPhone = "yhsjhm" } } func getUsers () async throws -> [User ] { guard let url = URL (string: "https://my.api.mockaroo.com/bad_api.json?key=8795e870" ) else { throw MyError .invlidUrl } let (data, response) = try await URLSession .shared.data(from: url) guard let response = response as? HTTPURLResponse , response.statusCode == 200 else { throw MyError .invlidServerResponse } let decoded = try JSONDecoder ().decode([User ].self , from: data) return decoded } Task { let users = try await getUsers() for user in users { print ("Name: \(user.username) , Email: \(user.userEmail) " ) } }
1 2 3 4 5 6 7 8 9 10 Name: acawood0, Email: cwerndly0@pinterest.com Name: obrade1, Email: aaylmore1@tiny.cc Name: kfolliott2, Email: lpietraszek2@phpbb.com Name: cmclese3, Email: ccanedo3@wisc.edu Name: apottberry4, Email: hberecloth4@mlb.com Name: beyers5, Email: apenson5@weibo.com Name: fcarlozzi6, Email: nburleigh6@indiatimes.com Name: thastin7, Email: ctoogood7@miibeian.gov.cn Name: hbriers8, Email: nbosdet8@tinyurl.com Name: bgentry9, Email: gkilbey9@pinterest.com
snake_case
还有一些情况,一些开发者可能使用类似于 Python, PHP 等使用 snake_case 作为命名规范的语言
不过,Swift 采用的是小驼峰写法,在这里使用 snake_case 真的太奇怪了
可以使用上面提供的方法吗?是可以的,但是聪明的 Swift 还有另一个方法来处理 snake_case 的返回格式
现将上面的 User Struct 还原成
1 2 3 4 struct User : Codable { let username, userEmail, userPhone: String let userAge: Int }
接下来我们指定 JSONDecoder 的 Decode 策略
为了指定 JSONDecoder 的策略,我们就可以考虑将一个 JSONDecoder 的实例化赋值给一个常量
例如
1 2 3 4 5 let decoder = JSONDecoder () decoder.keyDecodingStrategy = .convertFromSnakeCase let decoded = try decoder.decode([User ].self , from: data)
最后 decoded 出来的数据还是跟上面的数据一致
1 2 3 4 5 6 7 8 9 10 Name: bgarm0, Email: cwindas0@businessinsider.com Name: nblasl1, Email: bdeaconson1@census.gov Name: gsandom2, Email: dpeddie2@columbia.edu Name: tgarlic3, Email: djoysey3@creativecommons.org Name: amacmoyer4, Email: pdogerty4@networkadvertising.org Name: bilyinski5, Email: ngelletly5@skyrock.com Name: wclapston6, Email: fmccraw6@deviantart.com Name: ekeynd7, Email: bgoutcher7@sciencedirect.com Name: sfarlam8, Email: phaestier8@engadget.com Name: cwormell9, Email: bwofenden9@engadget.com