MyException - 我的异常网
当前位置:我的异常网» Swift » Swift 四 JSON 瑙f瀽鎸囧崡

Swift 四 JSON 瑙f瀽鎸囧崡

www.MyException.Cn  网友分享于:2018-04-16  浏览:0次
Swift 4 JSON 瑙f瀽鎸囧崡
Apple 缁堜簬鍦?Swift 4 鐨?Foundation 鐨勬ā鍧椾腑娣诲姞浜嗗 JSON 瑙f瀽鐨勫師鐢熸敮鎸併€?

铏界劧宸茬粡鏈夊緢澶氱涓夋柟绫诲簱瀹炵幇浜?JSON 瑙f瀽锛屼絾鏄兘澶熺湅鍒拌繖鏍蜂竴涓姛鑳藉己澶с€佹槗浜庝娇鐢ㄧ殑瀹樻柟瀹炵幇杩樻槸涓嶅厤鏈変簺鍏村銆?

鍊煎緱娉ㄦ剰鐨勬槸锛屽畼鏂圭殑瀹炵幇鏂瑰紡閫傜敤浜庝换浣?Encoder/Decoder 锛屼緥濡?PropertyListEncoder 銆傚綋鐒跺鏋滀綘闇€瑕?XML 鏍煎紡鐨勫唴瀹癸紝鍙互杩涜鑷畾涔夊疄鐜般€傚湪鎺ヤ笅鏉ョ殑鍐呭涓紝鎴戜滑灏嗕笓娉ㄤ簬 JSON 鏍煎紡鐨勮В鏋愶紝鍥犱负杩欐槸 iOS 寮€鍙戜腑鏈€甯歌鐨勬暟鎹牸寮忋€?

鍩虹
濡傛灉浣犵殑 JSON 鏁版嵁缁撴瀯鍜屼綘浣跨敤鐨?Model 瀵硅薄缁撴瀯涓€鑷寸殑璇濓紝閭d箞瑙f瀽杩囩▼灏嗕細闈炲父绠€鍗曘€?

涓嬮潰鏄竴涓?JSON 鏍煎紡鐨勫暏閰掕鏄庯細
{
    "name": "Endeavor",
    "abv": 8.9,
    "brewery": "Saint Arnold",
    "style": "ipa"
}

瀵瑰簲鐨?Swift 鏁版嵁缁撴瀯濡備笅锛?
enum BeerStyle : String {
    case ipa
    case stout
    case kolsch
    // ...
}

struct Beer {
    let name: String
    let brewery: String
    let style: BeerStyle
}

涓轰簡灏?JSON 瀛楃涓茶浆鍖栦负 Beer 绫诲瀷鐨勫疄渚嬶紝鎴戜滑闇€瑕佸皢 Beer 绫诲瀷鏍囪涓?Codable銆?

Codable 瀹為檯涓婃槸 Encodable & Decodable 涓や釜鍗忚鐨勭粍鍚堢被鍨嬶紝鎵€浠ュ鏋滀綘鍙渶瑕佸崟鍚戣浆鎹㈢殑璇濓紝浣犲彲浠ュ彧閫夌敤鍏朵腑涓€涓€傝鍔熻兘涔熸槸 Swift 4 涓紩鍏ョ殑鏈€閲嶈鏂扮壒鎬т箣涓€銆?

Codable 甯︽湁榛樿瀹炵幇锛屾墍浠ュ湪澶у鏁版儏褰笅锛屼綘鍙互鐩存帴浣跨敤璇ラ粯璁ゅ疄鐜拌繘琛屾暟鎹浆鎹€?
enum BeerStyle : String, Codable {
   // ...
}

struct Beer : Codable {
   // ...
}

涓嬮潰鍙渶瑕佸垱寤轰竴涓В鐮佸櫒锛?
let jsonData = jsonString.data(encoding: .utf8)!
let decoder = JSONDecoder()
let beer = try! decoder.decode(Beer.self, for: jsonData)

杩欐牱鎴戜滑灏卞皢 JSON 鏁版嵁鎴愬姛瑙f瀽涓轰簡 Beer 瀹炰緥瀵硅薄銆傚洜涓?JSON 鏁版嵁鐨?Key 涓?Beer 涓殑灞炴€у悕涓€鑷达紝鎵€浠ヨ繖閲屼笉闇€瑕佽繘琛岃嚜瀹氫箟鎿嶄綔銆?

闇€瑕佹敞鎰忕殑鏄紝杩欓噷鐩存帴浣跨敤浜?try! 鎿嶄綔銆傚洜涓鸿繖閲屽彧鏄畝鍗曠ず渚嬶紝鎵€浠ュ湪鐪熷疄绋嬪簭涓綘搴旇瀵归敊璇繘琛屾崟鑾峰苟浣滃嚭瀵瑰簲鐨勫鐞嗐€?

浣嗘槸锛岀幇瀹炰腑涓嶅彲鑳戒竴鐩撮兘鏄畬缇庢儏褰紝寰堝ぇ鍑犵巼瀛樺湪 Key 鍊间笌灞炴€у悕涓嶅尮閰嶇殑鎯呭舰銆?

鑷畾涔夐敭鍊煎悕
閫氬父鎯呭舰涓嬶紝API 鎺ュ彛璁捐鏃朵細閲囩敤 snake-case 鐨勫懡鍚嶉鏍硷紝浣嗘槸杩欎笌 Swift 涓殑缂栫▼椋庢牸鏈夌潃鏄庢樉鐨勫樊寮傘€?

涓轰簡瀹炵幇鑷畾涔夎В鏋愶紝鎴戜滑闇€瑕佸厛鍘荤湅涓?Codable 鐨勯粯璁ゅ疄鐜版満鍒躲€?

榛樿鎯呭舰涓?Keys 鏄敱缂栬瘧鍣ㄨ嚜鍔ㄧ敓鎴愮殑鏋氫妇绫诲瀷銆傝鏋氫妇閬靛畧 CodingKey 鍗忚骞跺缓绔嬩簡灞炴€у拰缂栫爜鍚庢牸寮忎箣闂寸殑鍏崇郴銆?

涓轰簡瑙e喅涓婇潰鐨勯鏍煎樊寮傞渶瑕佸鍏惰繘琛岃嚜瀹氫箟锛屽疄鐜颁唬鐮侊細
struct Beer : Codable {
      // ...
      enum CodingKeys : String, CodingKey {
          case name
          case abv = "alcohol_by_volume"
          case brewery = "brewery_name"
          case style
    }
}

鐜板湪鎴戜滑灏?Beer 瀹炰緥杞寲涓?JSON 锛岀湅鐪嬭嚜瀹氫箟涔嬪悗鐨?JSON 鏁版嵁鏍煎紡锛?
let encoder = JSONEncoder()
let data = try! encoder.encode(beer)
print(String(data: data, encoding: .utf8)!)

杈撳嚭濡備笅锛?
{"style":"ipa","name":"Endeavor","alcohol_by_volume":8.8999996185302734,"brewery_name":"Saint Arnold"}

涓婇潰鐨勮緭鍑烘牸寮忓闃呰璧锋潵骞朵笉鏄お鍙嬪ソ銆備笉杩囨垜浠彲浠ヨ缃?JSONEncoder 鐨?outputFormatting 灞炴€ф潵瀹氫箟杈撳嚭鏍煎紡銆?

榛樿 outputFormatting 灞炴€у€间负 .compact锛岃緭鍑烘晥鏋滃涓娿€傚鏋滃皢鍏舵敼涓?.prettyPrinted 鍚庡氨鑳借幏寰楁洿濂界殑闃呰浣撴銆?
encoder.outputFormatting = .prettyPrinted

鏁堟灉濡備笅锛?
{
  "style" : "ipa",
  "name" : "Endeavor",
  "alcohol_by_volume" : 8.8999996185302734,
  "brewery_name" : "Saint Arnold"
}

JSONEncoder 鍜?JSONDecoder 鍏跺疄杩樻湁寰堝閫夐」鍙互鑷畾涔夎缃€傚叾涓湁涓€涓父鐢ㄧ殑闇€姹傚氨鏄嚜瀹氫箟鏃堕棿鏍煎紡鐨勮В鏋愩€?

鏃堕棿鏍煎紡澶勭悊
JSON 娌℃湁鏁版嵁绫诲瀷琛ㄧず鏃ユ湡鏍煎紡锛屽洜姝ら渶瑕佸鎴风鍜屾湇鍔$瀵瑰簭鍒楀寲杩涜绾﹀畾銆傞€氬父鎯呭舰涓嬮兘浼氫娇鐢?ISO 8601 鏃ユ湡鏍煎紡骞跺簭鍒楀寲涓哄瓧绗︿覆銆?
寮曠敤

鎻愮ず锛歯sdateformatter.com 鏄竴涓潪甯告湁鐢ㄧ殑缃戠珯锛屼綘鍙互鏌ョ湅鍚勭鏃ユ湡鏍煎紡鐨勫瓧绗︿覆琛ㄧず锛屽寘鎷?ISO 8601銆?

鍏朵粬鏍煎紡鍙兘鏄弬鑰冩棩鏈熻捣鐨勬€荤锛堟垨姣锛夋暟锛屽苟灏嗗叾搴忓垪鍖栦负 JSON 鏍煎紡涓殑鏁板瓧绫诲瀷銆?

涔嬪墠锛屾垜浠繀椤昏嚜宸卞鐞嗚繖涓棶棰樸€傚湪鏁版嵁缁撴瀯涓娇鐢ㄥ睘鎬ф帴鏀惰瀛楃涓叉牸寮忔棩鏈燂紝鐒跺悗浣跨敤 DateFormatter 灏嗚灞炴€ц浆鍖栦负鏃ユ湡锛屽弽涔嬩害鐒躲€?

涓嶈繃 JSONEncoder 鍜?JSONDecoder 鑷甫浜嗚鍔熻兘銆傞粯璁ゆ儏鍐典笅锛屽畠浠娇鐢?.deferToDate 澶勭悊鏃ユ湡锛屽涓嬶細
struct Foo : Encodable {
    let date: Date
}

let foo = Foo(date: Date())
try! encoder.encode(foo)

{
  "date" : 519751611.12542897
}

褰撶劧锛屾垜浠篃鍙互閫夌敤 .iso8601 鏍煎紡锛?
encoder.dateEncodingStrategy = .iso8601

{
  "date" : "2017-06-21T15:29:32Z"
}

鍏朵粬鏃ユ湡缂栫爜鏍煎紡閫夋嫨濡備笅锛?
  • .formatted(DateFormatter) - 褰撲綘鐨勬棩鏈熷瓧绗︿覆鏄潪鏍囧噯鏍煎紡鏃朵娇鐢ㄣ€傞渶瑕佹彁渚涗綘鑷繁鐨勬棩鏈熸牸寮忓寲鍣ㄥ疄渚嬨€?
  • .custom((Date, Encoder) throws -> Void ) - 褰撲綘闇€瑕佺湡姝f剰涔変笂鐨勮嚜瀹氫箟鏃讹紝浣跨敤涓€涓棴鍖呰繘琛屽疄鐜般€?
  • .millisecondsSince1970銆?.secondsSince1970 - 杩欏湪 API 璁捐涓笉鏄緢甯歌銆?鐢变簬鏃跺尯淇℃伅瀹屽叏涓嶅湪缂栫爜琛ㄧず涓紝鎵€浠ヤ笉寤鸿浣跨敤杩欐牱鐨勬牸寮忥紝杩欎娇寰椾汉浠洿瀹规槗鍋氬嚭閿欒鐨勫亣璁俱€?

瀵规棩鏈熻繘琛?Decoding 鏃跺熀鏈笂鏄浉鍚岀殑閫夐」锛屼絾鏄?.custom 褰㈠紡鏄?.custom((Decoder) throws -> Date )锛屾墍浠ユ垜浠粰浜嗕竴涓В鐮佸櫒骞跺皢浠绘剰绫诲瀷杞崲涓烘棩鏈熸牸寮忋€?

娴偣绫诲瀷澶勭悊
娴偣鏄?JSON 涓?Swift 鍙︿竴涓瓨鍦ㄤ笉鍖归厤鎯呭舰鐨勭被鍨嬨€傚鏋滄湇鍔″櫒杩斿洖鐨勪簨鏃犳晥鐨?"NaN" 瀛楃涓蹭細鍙戠敓浠€涔堬紵鏃犵┓澶ф垨鑰呮棤绌峰ぇ锛熻繖浜涗笉浼氭槧灏勫埌 Swift 涓殑浠讳綍鐗瑰畾鍊笺€?

榛樿鐨勫疄鐜版槸 .throw锛岃繖鎰忓懗鐫€濡傛灉涓婅堪鏁板€煎嚭鐜扮殑璇濆氨浼氬紩鍙戦敊璇紝涓嶈繃瀵规鎴戜滑鍙互鑷畾涔夋槧灏勩€?
{
   "a": "NaN",
   "b": "+Infinity",
   "c": "-Infinity"
}

struct Numbers {
  let a: Float
  let b: Float
  let c: Float
}
decoder.nonConformingFloatDecodingStrategy =
  .convertFromString(
      positiveInfinity: "+Infinity",
      negativeInfinity: "-Infinity",
      nan: "NaN")

let numbers = try! decoder.decode(Numbers.elf, from: jsonData)
dump(numbers)

涓婅堪澶勭悊鍚庯細
__lldb_expr_71.Numbers
  - a: inf
  - b: -inf
  - c: nan

褰撶劧锛屾垜浠篃鍙互浣跨敤 JSONEncoder 鐨?nonConformingFloatEncodingStrategy 杩涜鍙嶅悜鎿嶄綔銆?

铏界劧澶у鏁版儏褰笅涓婅堪澶勭悊涓嶅お鍙兘鍑虹幇锛屼絾鏄互闃蹭竾涓€涔熶笉缁欒繃銆?

Data 澶勭悊
鏈夋椂鍊欐湇鍔$ API 杩斿洖鐨勬暟鎹槸 base64 缂栫爜杩囩殑瀛楃涓层€?

瀵规锛屾垜浠彲浠ュ湪 JSONEncoder 浣跨敤浠ヤ笅绛栫暐锛?
  • .base64
  • .custom((Data, Encoder) throws -> Void)

鍙嶄箣锛岀紪鐮佹椂鍙互浣跨敤锛?
  • .base64
  • .custom((Decoder) throws -> Data)

鏄剧劧锛?base64 鏃舵渶甯歌鐨勯€夐」锛屼絾濡傛灉闇€瑕佽嚜瀹氫箟鐨勮瘽鍙互閲囩敤 block 鏂瑰紡銆?

Wrapper Keys
閫氬父 API 浼氬鏁版嵁杩涜灏佽锛岃繖鏍烽《绾х殑 JSON 瀹炰綋 濮嬬粓鏄竴涓璞°€?

渚嬪锛?
{
  "beers": [ {...} ]
}

鍦?Swift 涓垜浠彲浠ヨ繘琛屽搴斿鐞嗭細
struct BeerList : Codable {
    let beers: [Beer]
}

鍥犱负閿€间笌灞炴€у悕涓€鑷达紝鎵€鏈変笂闈唬鐮佸凡缁忚冻澶熶簡銆?

Root Level Arrays
濡傛灉 API 浣滀负鏍瑰厓绱犺繑鍥炴暟缁勶紝瀵瑰簲瑙f瀽濡備笅鎵€绀猴細
let decoder = JSONDecoder()
let beers = try decoder.decode([Beer].self, from: data)

闇€瑕佹敞鎰忕殑鏄紝鎴戜滑鍦ㄨ繖閲屼娇鐢?Array 浣滀负绫诲瀷銆傚彧瑕?T 鍙В鐮侊紝Array 灏卞彲瑙g爜銆?

Dealing with Object Wrapping Keys
鍙︿竴涓父瑙佺殑鍦烘櫙鏄紝杩斿洖鐨勬暟缁勫璞¢噷鐨勬瘡涓€涓厓绱犻兘琚寘瑁呬负瀛楀吀绫诲瀷瀵硅薄銆?
[
  {
    "beer" : {
      "id": "uuid12459078214",
      "name": "Endeavor",
      "abv": 8.9,
      "brewery": "Saint Arnold",
      "style": "ipa"
    }
  }
]

浣犲彲浠ヤ娇鐢ㄤ笂闈㈢殑鏂规硶鏉ユ崟鑾锋 Key 鍊硷紝浣嗘渶绠€鍗曠殑鏂瑰紡灏辨槸璁よ瘑鍒拌缁撴瀯鐨勫彲缂栫爜鐨勫疄鐜板舰寮忋€?

濡備笅锛?
[[String:Beer]]

鎴栬€呮洿鏄撲簬闃呰鐨勫舰寮忥細
Array<Dictionary<String, Beer>>

涓庝笂闈㈢殑 Array 绫讳技锛屽鏋?K 鍜?T 鏄彲瑙g爜 Dictionary<K,T> 灏辫兘瑙g爜銆?
let decoder = JSONDecoder()
let beers = try decoder.decode([[String:Beer]].self, from: data)
dump(beers)

1 element
  鈻?1 key/value pair
    鈻?(2 elements)
      - key: "beer"
      鈻?value: __lldb_expr_37.Beer
        - name: "Endeavor"
        - brewery: "Saint Arnold"
        - abv: 8.89999962
        - style: __lldb_expr_37.BeerStyle.ipa

鏇村鏉傜殑宓屽

鏈夋椂鍊?API 鐨勫搷搴旀暟鎹苟涓嶆槸閭d箞绠€鍗曘€傞《灞傚厓绱犱笉涓€瀹氬彧鏄竴涓璞★紝鑰屼笖閫氬父鎯呭喌涓嬫槸澶氫釜瀛楀吀缁撴瀯銆?

渚嬪锛?
{
    "meta": {
        "page": 1,
        "total_pages": 4,
        "per_page": 10,
        "total_records": 38
    },
    "breweries": [
        {
            "id": 1234,
            "name": "Saint Arnold"
        },
        {
            "id": 52892,
            "name": "Buffalo Bayou"
        }
    ]
}

鍦?Swift 涓垜浠彲浠ヨ繘琛屽搴旂殑宓屽瀹氫箟澶勭悊锛?
struct PagedBreweries : Codable {
    struct Meta : Codable {
        let page: Int
        let totalPages: Int
        let perPage: Int
        let totalRecords: Int
        enum CodingKeys : String, CodingKey {
            case page
            case totalPages = "total_pages"
            case perPage = "per_page"
            case totalRecords = "total_records"
        }
    }

    struct Brewery : Codable {
        let id: Int
        let name: String
    }

    let meta: Meta
    let breweries: [Brewery]
}

璇ユ柟娉曠殑鏈€澶т紭鐐瑰氨鏄鍚屼竴绫诲瀷鐨勫璞″仛鍑轰笉鍚岀殑鍝嶅簲锛堝彲鑳藉湪杩欑鎯呭喌涓嬶紝鈥渂rewery鈥?鍒楄〃鍝嶅簲涓彧闇€瑕?id 鍜?name 灞炴€э紝浣嗘槸濡傛灉鏌ョ湅璇︾粏鍐呭鐨勮瘽鍒欓渶瑕佹洿澶氬睘鎬у唴瀹癸級銆傚洜涓鸿鎯呭舰涓?Brewery 绫诲瀷鏄祵濂楃殑锛屾垜浠緷鏃у彲浠ュ湪鍏朵粬鍦版柟杩涜涓嶅悓鐨?Brewery 绫诲瀷瀹炵幇銆?

缁撹
Swift 4 涓熀纭€ Codable API 鐨勫唴瀹瑰凡缁忎粙缁嶅樊涓嶅浜嗐€傛洿澶氱殑鍐呭鍙互鏌ョ湅 Codable.swift銆乁sing JSON with Custom Types 銆?

文章评论

代码女神横空出世
代码女神横空出世
我的丈夫是个程序员
我的丈夫是个程序员
老美怎么看待阿里赴美上市
老美怎么看待阿里赴美上市
做程序猿的老婆应该注意的一些事情
做程序猿的老婆应该注意的一些事情
程序员和编码员之间的区别
程序员和编码员之间的区别
编程语言是女人
编程语言是女人
不懂技术不要对懂技术的人说这很容易实现
不懂技术不要对懂技术的人说这很容易实现
什么才是优秀的用户界面设计
什么才是优秀的用户界面设计
十大编程算法助程序员走上高手之路
十大编程算法助程序员走上高手之路
为什么程序员都是夜猫子
为什么程序员都是夜猫子
科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
程序员的一天:一寸光阴一寸金
程序员的一天:一寸光阴一寸金
初级 vs 高级开发者 哪个性价比更高?
初级 vs 高级开发者 哪个性价比更高?
2013年美国开发者薪资调查报告
2013年美国开发者薪资调查报告
10个调试和排错的小建议
10个调试和排错的小建议
Java程序员必看电影
Java程序员必看电影
Web开发人员为什么越来越懒了?
Web开发人员为什么越来越懒了?
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
2013年中国软件开发者薪资调查报告
2013年中国软件开发者薪资调查报告
10个帮程序员减压放松的网站
10个帮程序员减压放松的网站
鲜为人知的编程真相
鲜为人知的编程真相
老程序员的下场
老程序员的下场
5款最佳正则表达式编辑调试器
5款最佳正则表达式编辑调试器
程序员最害怕的5件事 你中招了吗?
程序员最害怕的5件事 你中招了吗?
我跳槽是因为他们的显示器更大
我跳槽是因为他们的显示器更大
Web开发者需具备的8个好习惯
Web开发者需具备的8个好习惯
总结2014中国互联网十大段子
总结2014中国互联网十大段子
 程序员的样子
程序员的样子
程序员必看的十大电影
程序员必看的十大电影
程序猿的崛起——Growth Hacker
程序猿的崛起——Growth Hacker
程序员应该关注的一些事儿
程序员应该关注的一些事儿
那些争议最大的编程观点
那些争议最大的编程观点
如何成为一名黑客
如何成为一名黑客
一个程序员的时间管理
一个程序员的时间管理
我是如何打败拖延症的
我是如何打败拖延症的
团队中“技术大拿”并非越多越好
团队中“技术大拿”并非越多越好
要嫁就嫁程序猿—钱多话少死的早
要嫁就嫁程序猿—钱多话少死的早
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
如何区分一个程序员是“老手“还是“新手“?
如何区分一个程序员是“老手“还是“新手“?
写给自己也写给你 自己到底该何去何从
写给自己也写给你 自己到底该何去何从
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
旅行,写作,编程
旅行,写作,编程
亲爱的项目经理,我恨你
亲爱的项目经理,我恨你
每天工作4小时的程序员
每天工作4小时的程序员
漫画:程序员的工作
漫画:程序员的工作
中美印日四国程序员比较
中美印日四国程序员比较
程序员都该阅读的书
程序员都该阅读的书
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
程序员周末都喜欢做什么?
程序员周末都喜欢做什么?
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有