Skip to content

Instantly share code, notes, and snippets.

@KentarouKanno
Last active September 6, 2018 04:15
Show Gist options
  • Save KentarouKanno/f337d9bc9300dd7678c66bd1cf29e851 to your computer and use it in GitHub Desktop.
Save KentarouKanno/f337d9bc9300dd7678c66bd1cf29e851 to your computer and use it in GitHub Desktop.

Codable

参考URL: DecodableのDecodeを簡潔に書きたい

Codableに準拠していて、プロパティに使える型

Bool, Int, Int8, Int16, Int32, Int64, UInt, UInt8, UInt16, UInt32, UInt64, Int, Double, String あとは上記の型を要素に持つOptional, Array, Dictionary

  • Codableに準拠した構造体のUserDefaultsへの保存
// Codableに準拠した構造体
struct User: Codable {
    let id: UInt
    let name: String
}

// 構造体 → Data にしてをUserDefaultsに保存
let user = User(id: 12345, name: "kentarou")
let data = try? JSONEncoder().encode(user)
UserDefaults.standard.set(data, forKey: "user")

// UserDefaultsからData → 構造体 にして読み込み
if let udData = UserDefaults.standard.object(forKey: "user") as? Data,
    let user = try? JSONDecoder().decode(User.self, from: udData) {
    print(user.id) //=> 12345
    print(user.name) //=> kentarou
}
  • 開始がArrayの場合
import Foundation

let list = """
[
  {
    "login": "mojombo",
    "node_id": "MDQ6VXNlcjE=",
    "avatar_url": "https://avatars0.githubusercontent.com/u/1?v=4",
    "gravatar_id": "",
    "url": "https://api.github.com/users/mojombo",
    "html_url": "https://github.com/mojombo",
    "followers_url": "https://api.github.com/users/mojombo/followers",
    "following_url": "https://api.github.com/users/mojombo/following{/other_user}",
    "gists_url": "https://api.github.com/users/mojombo/gists{/gist_id}",
    "starred_url": "https://api.github.com/users/mojombo/starred{/owner}{/repo}",
    "subscriptions_url": "https://api.github.com/users/mojombo/subscriptions",
    "organizations_url": "https://api.github.com/users/mojombo/orgs",
    "repos_url": "https://api.github.com/users/mojombo/repos",
    "events_url": "https://api.github.com/users/mojombo/events{/privacy}",
    "received_events_url": "https://api.github.com/users/mojombo/received_events",
    "type": "User",
    "site_admin": false
  },
  {
    "login": "defunkt",
    "id": 2,
    "node_id": "MDQ6VXNlcjI=",
    "avatar_url": "https://avatars0.githubusercontent.com/u/2?v=4",
    "gravatar_id": "",
    "url": "https://api.github.com/users/defunkt",
    "html_url": "https://github.com/defunkt",
    "followers_url": "https://api.github.com/users/defunkt/followers",
    "following_url": "https://api.github.com/users/defunkt/following{/other_user}",
    "gists_url": "https://api.github.com/users/defunkt/gists{/gist_id}",
    "starred_url": "https://api.github.com/users/defunkt/starred{/owner}{/repo}",
    "subscriptions_url": "https://api.github.com/users/defunkt/subscriptions",
    "organizations_url": "https://api.github.com/users/defunkt/orgs",
    "repos_url": "https://api.github.com/users/defunkt/repos",
    "events_url": "https://api.github.com/users/defunkt/events{/privacy}",
    "received_events_url": "https://api.github.com/users/defunkt/received_events",
    "type": "User",
    "site_admin": true
  },
  {
    "login": "pjhyett",
    "id": 3,
    "node_id": "MDQ6VXNlcjM=",
    "avatar_url": "https://avatars0.githubusercontent.com/u/3?v=4",
    "gravatar_id": "",
    "url": "https://api.github.com/users/pjhyett",
    "html_url": "https://github.com/pjhyett",
    "followers_url": "https://api.github.com/users/pjhyett/followers",
    "following_url": "https://api.github.com/users/pjhyett/following{/other_user}",
    "gists_url": "https://api.github.com/users/pjhyett/gists{/gist_id}",
    "starred_url": "https://api.github.com/users/pjhyett/starred{/owner}{/repo}",
    "subscriptions_url": "https://api.github.com/users/pjhyett/subscriptions",
    "organizations_url": "https://api.github.com/users/pjhyett/orgs",
    "repos_url": "https://api.github.com/users/pjhyett/repos",
    "events_url": "https://api.github.com/users/pjhyett/events{/privacy}",
    "received_events_url": "https://api.github.com/users/pjhyett/received_events",
    "type": "User",
    "site_admin": false
  },
  {
    "login": "wycats",
    "id": 4,
    "node_id": "MDQ6VXNlcjQ=",
    "avatar_url": "https://avatars0.githubusercontent.com/u/4?v=4",
    "gravatar_id": "",
    "url": "https://api.github.com/users/wycats",
    "html_url": "https://github.com/wycats",
    "followers_url": "https://api.github.com/users/wycats/followers",
    "following_url": "https://api.github.com/users/wycats/following{/other_user}",
    "gists_url": "https://api.github.com/users/wycats/gists{/gist_id}",
    "starred_url": "https://api.github.com/users/wycats/starred{/owner}{/repo}",
    "subscriptions_url": "https://api.github.com/users/wycats/subscriptions",
    "organizations_url": "https://api.github.com/users/wycats/orgs",
    "repos_url": "https://api.github.com/users/wycats/repos",
    "events_url": "https://api.github.com/users/wycats/events{/privacy}",
    "received_events_url": "https://api.github.com/users/wycats/received_events",
    "type": "User",
    "site_admin": false
  },
  {
    "login": "ezmobius",
    "id": 5,
    "node_id": "MDQ6VXNlcjU=",
    "avatar_url": "https://avatars0.githubusercontent.com/u/5?v=4",
    "gravatar_id": "",
    "url": "https://api.github.com/users/ezmobius",
    "html_url": "https://github.com/ezmobius",
    "followers_url": "https://api.github.com/users/ezmobius/followers",
    "following_url": "https://api.github.com/users/ezmobius/following{/other_user}",
    "gists_url": "https://api.github.com/users/ezmobius/gists{/gist_id}",
    "starred_url": "https://api.github.com/users/ezmobius/starred{/owner}{/repo}",
    "subscriptions_url": "https://api.github.com/users/ezmobius/subscriptions",
    "organizations_url": "https://api.github.com/users/ezmobius/orgs",
    "repos_url": "https://api.github.com/users/ezmobius/repos",
    "events_url": "https://api.github.com/users/ezmobius/events{/privacy}",
    "received_events_url": "https://api.github.com/users/ezmobius/received_events",
    "type": "User",
    "site_admin": false
  },
  {
    "login": "ivey",
    "id": 6,
    "node_id": "MDQ6VXNlcjY=",
    "avatar_url": "https://avatars0.githubusercontent.com/u/6?v=4",
    "gravatar_id": "",
    "url": "https://api.github.com/users/ivey",
    "html_url": "https://github.com/ivey",
    "followers_url": "https://api.github.com/users/ivey/followers",
    "following_url": "https://api.github.com/users/ivey/following{/other_user}",
    "gists_url": "https://api.github.com/users/ivey/gists{/gist_id}",
    "starred_url": "https://api.github.com/users/ivey/starred{/owner}{/repo}",
    "subscriptions_url": "https://api.github.com/users/ivey/subscriptions",
    "organizations_url": "https://api.github.com/users/ivey/orgs",
    "repos_url": "https://api.github.com/users/ivey/repos",
    "events_url": "https://api.github.com/users/ivey/events{/privacy}",
    "received_events_url": "https://api.github.com/users/ivey/received_events",
    "type": "User",
    "site_admin": false
  },
  {
    "login": "evanphx",
    "id": 7,
    "node_id": "MDQ6VXNlcjc=",
    "avatar_url": "https://avatars0.githubusercontent.com/u/7?v=4",
    "gravatar_id": "",
    "url": "https://api.github.com/users/evanphx",
    "html_url": "https://github.com/evanphx",
    "followers_url": "https://api.github.com/users/evanphx/followers",
    "following_url": "https://api.github.com/users/evanphx/following{/other_user}",
    "gists_url": "https://api.github.com/users/evanphx/gists{/gist_id}",
    "starred_url": "https://api.github.com/users/evanphx/starred{/owner}{/repo}",
    "subscriptions_url": "https://api.github.com/users/evanphx/subscriptions",
    "organizations_url": "https://api.github.com/users/evanphx/orgs",
    "repos_url": "https://api.github.com/users/evanphx/repos",
    "events_url": "https://api.github.com/users/evanphx/events{/privacy}",
    "received_events_url": "https://api.github.com/users/evanphx/received_events",
    "type": "User",
    "site_admin": false
  },
  {
    "login": "vanpelt",
    "id": 17,
    "node_id": "MDQ6VXNlcjE3",
    "avatar_url": "https://avatars1.githubusercontent.com/u/17?v=4",
    "gravatar_id": "",
    "url": "https://api.github.com/users/vanpelt",
    "html_url": "https://github.com/vanpelt",
    "followers_url": "https://api.github.com/users/vanpelt/followers",
    "following_url": "https://api.github.com/users/vanpelt/following{/other_user}",
    "gists_url": "https://api.github.com/users/vanpelt/gists{/gist_id}",
    "starred_url": "https://api.github.com/users/vanpelt/starred{/owner}{/repo}",
    "subscriptions_url": "https://api.github.com/users/vanpelt/subscriptions",
    "organizations_url": "https://api.github.com/users/vanpelt/orgs",
    "repos_url": "https://api.github.com/users/vanpelt/repos",
    "events_url": "https://api.github.com/users/vanpelt/events{/privacy}",
    "received_events_url": "https://api.github.com/users/vanpelt/received_events",
    "type": "User",
    "site_admin": false
  },
  {
    "login": "wayneeseguin",
    "id": 18,
    "node_id": "MDQ6VXNlcjE4",
    "avatar_url": "https://avatars0.githubusercontent.com/u/18?v=4",
    "gravatar_id": "",
    "url": "https://api.github.com/users/wayneeseguin",
    "html_url": "https://github.com/wayneeseguin",
    "followers_url": "https://api.github.com/users/wayneeseguin/followers",
    "following_url": "https://api.github.com/users/wayneeseguin/following{/other_user}",
    "gists_url": "https://api.github.com/users/wayneeseguin/gists{/gist_id}",
    "starred_url": "https://api.github.com/users/wayneeseguin/starred{/owner}{/repo}",
    "subscriptions_url": "https://api.github.com/users/wayneeseguin/subscriptions",
    "organizations_url": "https://api.github.com/users/wayneeseguin/orgs",
    "repos_url": "https://api.github.com/users/wayneeseguin/repos",
    "events_url": "https://api.github.com/users/wayneeseguin/events{/privacy}",
    "received_events_url": "https://api.github.com/users/wayneeseguin/received_events",
    "type": "User",
    "site_admin": false
  },
  {
    "login": "brynary",
    "id": 19,
    "node_id": "MDQ6VXNlcjE5",
    "avatar_url": "https://avatars0.githubusercontent.com/u/19?v=4",
    "gravatar_id": "",
    "url": "https://api.github.com/users/brynary",
    "html_url": "https://github.com/brynary",
    "followers_url": "https://api.github.com/users/brynary/followers",
    "following_url": "https://api.github.com/users/brynary/following{/other_user}",
    "gists_url": "https://api.github.com/users/brynary/gists{/gist_id}",
    "starred_url": "https://api.github.com/users/brynary/starred{/owner}{/repo}",
    "subscriptions_url": "https://api.github.com/users/brynary/subscriptions",
    "organizations_url": "https://api.github.com/users/brynary/orgs",
    "repos_url": "https://api.github.com/users/brynary/repos",
    "events_url": "https://api.github.com/users/brynary/events{/privacy}",
    "received_events_url": "https://api.github.com/users/brynary/received_events",
    "type": "User",
    "site_admin": false
  },
  {
    "login": "kevinclark",
    "id": 20,
    "node_id": "MDQ6VXNlcjIw",
    "avatar_url": "https://avatars3.githubusercontent.com/u/20?v=4",
    "gravatar_id": "",
    "url": "https://api.github.com/users/kevinclark",
    "html_url": "https://github.com/kevinclark",
    "followers_url": "https://api.github.com/users/kevinclark/followers",
    "following_url": "https://api.github.com/users/kevinclark/following{/other_user}",
    "gists_url": "https://api.github.com/users/kevinclark/gists{/gist_id}",
    "starred_url": "https://api.github.com/users/kevinclark/starred{/owner}{/repo}",
    "subscriptions_url": "https://api.github.com/users/kevinclark/subscriptions",
    "organizations_url": "https://api.github.com/users/kevinclark/orgs",
    "repos_url": "https://api.github.com/users/kevinclark/repos",
    "events_url": "https://api.github.com/users/kevinclark/events{/privacy}",
    "received_events_url": "https://api.github.com/users/kevinclark/received_events",
    "type": "User",
    "site_admin": false
  },
  {
    "login": "technoweenie",
    "id": 21,
    "node_id": "MDQ6VXNlcjIx",
    "avatar_url": "https://avatars3.githubusercontent.com/u/21?v=4",
    "gravatar_id": "",
    "url": "https://api.github.com/users/technoweenie",
    "html_url": "https://github.com/technoweenie",
    "followers_url": "https://api.github.com/users/technoweenie/followers",
    "following_url": "https://api.github.com/users/technoweenie/following{/other_user}",
    "gists_url": "https://api.github.com/users/technoweenie/gists{/gist_id}",
    "starred_url": "https://api.github.com/users/technoweenie/starred{/owner}{/repo}",
    "subscriptions_url": "https://api.github.com/users/technoweenie/subscriptions",
    "organizations_url": "https://api.github.com/users/technoweenie/orgs",
    "repos_url": "https://api.github.com/users/technoweenie/repos",
    "events_url": "https://api.github.com/users/technoweenie/events{/privacy}",
    "received_events_url": "https://api.github.com/users/technoweenie/received_events",
    "type": "User",
    "site_admin": false
  },
  {
    "login": "macournoyer",
    "id": 22,
    "node_id": "MDQ6VXNlcjIy",
    "avatar_url": "https://avatars3.githubusercontent.com/u/22?v=4",
    "gravatar_id": "",
    "url": "https://api.github.com/users/macournoyer",
    "html_url": "https://github.com/macournoyer",
    "followers_url": "https://api.github.com/users/macournoyer/followers",
    "following_url": "https://api.github.com/users/macournoyer/following{/other_user}",
    "gists_url": "https://api.github.com/users/macournoyer/gists{/gist_id}",
    "starred_url": "https://api.github.com/users/macournoyer/starred{/owner}{/repo}",
    "subscriptions_url": "https://api.github.com/users/macournoyer/subscriptions",
    "organizations_url": "https://api.github.com/users/macournoyer/orgs",
    "repos_url": "https://api.github.com/users/macournoyer/repos",
    "events_url": "https://api.github.com/users/macournoyer/events{/privacy}",
    "received_events_url": "https://api.github.com/users/macournoyer/received_events",
    "type": "User",
    "site_admin": false
  },
  {
    "login": "takeo",
    "id": 23,
    "node_id": "MDQ6VXNlcjIz",
    "avatar_url": "https://avatars3.githubusercontent.com/u/23?v=4",
    "gravatar_id": "",
    "url": "https://api.github.com/users/takeo",
    "html_url": "https://github.com/takeo",
    "followers_url": "https://api.github.com/users/takeo/followers",
    "following_url": "https://api.github.com/users/takeo/following{/other_user}",
    "gists_url": "https://api.github.com/users/takeo/gists{/gist_id}",
    "starred_url": "https://api.github.com/users/takeo/starred{/owner}{/repo}",
    "subscriptions_url": "https://api.github.com/users/takeo/subscriptions",
    "organizations_url": "https://api.github.com/users/takeo/orgs",
    "repos_url": "https://api.github.com/users/takeo/repos",
    "events_url": "https://api.github.com/users/takeo/events{/privacy}",
    "received_events_url": "https://api.github.com/users/takeo/received_events",
    "type": "User",
    "site_admin": false
  },
  {
    "login": "Caged",
    "id": 25,
    "node_id": "MDQ6VXNlcjI1",
    "avatar_url": "https://avatars3.githubusercontent.com/u/25?v=4",
    "gravatar_id": "",
    "url": "https://api.github.com/users/Caged",
    "html_url": "https://github.com/Caged",
    "followers_url": "https://api.github.com/users/Caged/followers",
    "following_url": "https://api.github.com/users/Caged/following{/other_user}",
    "gists_url": "https://api.github.com/users/Caged/gists{/gist_id}",
    "starred_url": "https://api.github.com/users/Caged/starred{/owner}{/repo}",
    "subscriptions_url": "https://api.github.com/users/Caged/subscriptions",
    "organizations_url": "https://api.github.com/users/Caged/orgs",
    "repos_url": "https://api.github.com/users/Caged/repos",
    "events_url": "https://api.github.com/users/Caged/events{/privacy}",
    "received_events_url": "https://api.github.com/users/Caged/received_events",
    "type": "User",
    "site_admin": true
  },
  {
    "login": "topfunky",
    "id": 26,
    "node_id": "MDQ6VXNlcjI2",
    "avatar_url": "https://avatars3.githubusercontent.com/u/26?v=4",
    "gravatar_id": "",
    "url": "https://api.github.com/users/topfunky",
    "html_url": "https://github.com/topfunky",
    "followers_url": "https://api.github.com/users/topfunky/followers",
    "following_url": "https://api.github.com/users/topfunky/following{/other_user}",
    "gists_url": "https://api.github.com/users/topfunky/gists{/gist_id}",
    "starred_url": "https://api.github.com/users/topfunky/starred{/owner}{/repo}",
    "subscriptions_url": "https://api.github.com/users/topfunky/subscriptions",
    "organizations_url": "https://api.github.com/users/topfunky/orgs",
    "repos_url": "https://api.github.com/users/topfunky/repos",
    "events_url": "https://api.github.com/users/topfunky/events{/privacy}",
    "received_events_url": "https://api.github.com/users/topfunky/received_events",
    "type": "User",
    "site_admin": false
  },
  {
    "login": "anotherjesse",
    "id": 27,
    "node_id": "MDQ6VXNlcjI3",
    "avatar_url": "https://avatars3.githubusercontent.com/u/27?v=4",
    "gravatar_id": "",
    "url": "https://api.github.com/users/anotherjesse",
    "html_url": "https://github.com/anotherjesse",
    "followers_url": "https://api.github.com/users/anotherjesse/followers",
    "following_url": "https://api.github.com/users/anotherjesse/following{/other_user}",
    "gists_url": "https://api.github.com/users/anotherjesse/gists{/gist_id}",
    "starred_url": "https://api.github.com/users/anotherjesse/starred{/owner}{/repo}",
    "subscriptions_url": "https://api.github.com/users/anotherjesse/subscriptions",
    "organizations_url": "https://api.github.com/users/anotherjesse/orgs",
    "repos_url": "https://api.github.com/users/anotherjesse/repos",
    "events_url": "https://api.github.com/users/anotherjesse/events{/privacy}",
    "received_events_url": "https://api.github.com/users/anotherjesse/received_events",
    "type": "User",
    "site_admin": false
  },
  {
    "login": "roland",
    "id": 28,
    "node_id": "MDQ6VXNlcjI4",
    "avatar_url": "https://avatars2.githubusercontent.com/u/28?v=4",
    "gravatar_id": "",
    "url": "https://api.github.com/users/roland",
    "html_url": "https://github.com/roland",
    "followers_url": "https://api.github.com/users/roland/followers",
    "following_url": "https://api.github.com/users/roland/following{/other_user}",
    "gists_url": "https://api.github.com/users/roland/gists{/gist_id}",
    "starred_url": "https://api.github.com/users/roland/starred{/owner}{/repo}",
    "subscriptions_url": "https://api.github.com/users/roland/subscriptions",
    "organizations_url": "https://api.github.com/users/roland/orgs",
    "repos_url": "https://api.github.com/users/roland/repos",
    "events_url": "https://api.github.com/users/roland/events{/privacy}",
    "received_events_url": "https://api.github.com/users/roland/received_events",
    "type": "User",
    "site_admin": false
  },
  {
    "login": "lukas",
    "id": 29,
    "node_id": "MDQ6VXNlcjI5",
    "avatar_url": "https://avatars2.githubusercontent.com/u/29?v=4",
    "gravatar_id": "",
    "url": "https://api.github.com/users/lukas",
    "html_url": "https://github.com/lukas",
    "followers_url": "https://api.github.com/users/lukas/followers",
    "following_url": "https://api.github.com/users/lukas/following{/other_user}",
    "gists_url": "https://api.github.com/users/lukas/gists{/gist_id}",
    "starred_url": "https://api.github.com/users/lukas/starred{/owner}{/repo}",
    "subscriptions_url": "https://api.github.com/users/lukas/subscriptions",
    "organizations_url": "https://api.github.com/users/lukas/orgs",
    "repos_url": "https://api.github.com/users/lukas/repos",
    "events_url": "https://api.github.com/users/lukas/events{/privacy}",
    "received_events_url": "https://api.github.com/users/lukas/received_events",
    "type": "User",
    "site_admin": false
  },
  {
    "login": "fanvsfan",
    "id": 30,
    "node_id": "MDQ6VXNlcjMw",
    "avatar_url": "https://avatars2.githubusercontent.com/u/30?v=4",
    "gravatar_id": "",
    "url": "https://api.github.com/users/fanvsfan",
    "html_url": "https://github.com/fanvsfan",
    "followers_url": "https://api.github.com/users/fanvsfan/followers",
    "following_url": "https://api.github.com/users/fanvsfan/following{/other_user}",
    "gists_url": "https://api.github.com/users/fanvsfan/gists{/gist_id}",
    "starred_url": "https://api.github.com/users/fanvsfan/starred{/owner}{/repo}",
    "subscriptions_url": "https://api.github.com/users/fanvsfan/subscriptions",
    "organizations_url": "https://api.github.com/users/fanvsfan/orgs",
    "repos_url": "https://api.github.com/users/fanvsfan/repos",
    "events_url": "https://api.github.com/users/fanvsfan/events{/privacy}",
    "received_events_url": "https://api.github.com/users/fanvsfan/received_events",
    "type": "User",
    "site_admin": false
  },
  {
    "login": "tomtt",
    "id": 31,
    "node_id": "MDQ6VXNlcjMx",
    "avatar_url": "https://avatars2.githubusercontent.com/u/31?v=4",
    "gravatar_id": "",
    "url": "https://api.github.com/users/tomtt",
    "html_url": "https://github.com/tomtt",
    "followers_url": "https://api.github.com/users/tomtt/followers",
    "following_url": "https://api.github.com/users/tomtt/following{/other_user}",
    "gists_url": "https://api.github.com/users/tomtt/gists{/gist_id}",
    "starred_url": "https://api.github.com/users/tomtt/starred{/owner}{/repo}",
    "subscriptions_url": "https://api.github.com/users/tomtt/subscriptions",
    "organizations_url": "https://api.github.com/users/tomtt/orgs",
    "repos_url": "https://api.github.com/users/tomtt/repos",
    "events_url": "https://api.github.com/users/tomtt/events{/privacy}",
    "received_events_url": "https://api.github.com/users/tomtt/received_events",
    "type": "User",
    "site_admin": false
  },
  {
    "login": "railsjitsu",
    "id": 32,
    "node_id": "MDQ6VXNlcjMy",
    "avatar_url": "https://avatars2.githubusercontent.com/u/32?v=4",
    "gravatar_id": "",
    "url": "https://api.github.com/users/railsjitsu",
    "html_url": "https://github.com/railsjitsu",
    "followers_url": "https://api.github.com/users/railsjitsu/followers",
    "following_url": "https://api.github.com/users/railsjitsu/following{/other_user}",
    "gists_url": "https://api.github.com/users/railsjitsu/gists{/gist_id}",
    "starred_url": "https://api.github.com/users/railsjitsu/starred{/owner}{/repo}",
    "subscriptions_url": "https://api.github.com/users/railsjitsu/subscriptions",
    "organizations_url": "https://api.github.com/users/railsjitsu/orgs",
    "repos_url": "https://api.github.com/users/railsjitsu/repos",
    "events_url": "https://api.github.com/users/railsjitsu/events{/privacy}",
    "received_events_url": "https://api.github.com/users/railsjitsu/received_events",
    "type": "User",
    "site_admin": false
  },
  {
    "login": "nitay",
    "id": 34,
    "node_id": "MDQ6VXNlcjM0",
    "avatar_url": "https://avatars2.githubusercontent.com/u/34?v=4",
    "gravatar_id": "",
    "url": "https://api.github.com/users/nitay",
    "html_url": "https://github.com/nitay",
    "followers_url": "https://api.github.com/users/nitay/followers",
    "following_url": "https://api.github.com/users/nitay/following{/other_user}",
    "gists_url": "https://api.github.com/users/nitay/gists{/gist_id}",
    "starred_url": "https://api.github.com/users/nitay/starred{/owner}{/repo}",
    "subscriptions_url": "https://api.github.com/users/nitay/subscriptions",
    "organizations_url": "https://api.github.com/users/nitay/orgs",
    "repos_url": "https://api.github.com/users/nitay/repos",
    "events_url": "https://api.github.com/users/nitay/events{/privacy}",
    "received_events_url": "https://api.github.com/users/nitay/received_events",
    "type": "User",
    "site_admin": false
  },
  {
    "login": "kevwil",
    "id": 35,
    "node_id": "MDQ6VXNlcjM1",
    "avatar_url": "https://avatars2.githubusercontent.com/u/35?v=4",
    "gravatar_id": "",
    "url": "https://api.github.com/users/kevwil",
    "html_url": "https://github.com/kevwil",
    "followers_url": "https://api.github.com/users/kevwil/followers",
    "following_url": "https://api.github.com/users/kevwil/following{/other_user}",
    "gists_url": "https://api.github.com/users/kevwil/gists{/gist_id}",
    "starred_url": "https://api.github.com/users/kevwil/starred{/owner}{/repo}",
    "subscriptions_url": "https://api.github.com/users/kevwil/subscriptions",
    "organizations_url": "https://api.github.com/users/kevwil/orgs",
    "repos_url": "https://api.github.com/users/kevwil/repos",
    "events_url": "https://api.github.com/users/kevwil/events{/privacy}",
    "received_events_url": "https://api.github.com/users/kevwil/received_events",
    "type": "User",
    "site_admin": false
  },
  {
    "login": "KirinDave",
    "id": 36,
    "node_id": "MDQ6VXNlcjM2",
    "avatar_url": "https://avatars2.githubusercontent.com/u/36?v=4",
    "gravatar_id": "",
    "url": "https://api.github.com/users/KirinDave",
    "html_url": "https://github.com/KirinDave",
    "followers_url": "https://api.github.com/users/KirinDave/followers",
    "following_url": "https://api.github.com/users/KirinDave/following{/other_user}",
    "gists_url": "https://api.github.com/users/KirinDave/gists{/gist_id}",
    "starred_url": "https://api.github.com/users/KirinDave/starred{/owner}{/repo}",
    "subscriptions_url": "https://api.github.com/users/KirinDave/subscriptions",
    "organizations_url": "https://api.github.com/users/KirinDave/orgs",
    "repos_url": "https://api.github.com/users/KirinDave/repos",
    "events_url": "https://api.github.com/users/KirinDave/events{/privacy}",
    "received_events_url": "https://api.github.com/users/KirinDave/received_events",
    "type": "User",
    "site_admin": false
  },
  {
    "login": "jamesgolick",
    "id": 37,
    "node_id": "MDQ6VXNlcjM3",
    "avatar_url": "https://avatars2.githubusercontent.com/u/37?v=4",
    "gravatar_id": "",
    "url": "https://api.github.com/users/jamesgolick",
    "html_url": "https://github.com/jamesgolick",
    "followers_url": "https://api.github.com/users/jamesgolick/followers",
    "following_url": "https://api.github.com/users/jamesgolick/following{/other_user}",
    "gists_url": "https://api.github.com/users/jamesgolick/gists{/gist_id}",
    "starred_url": "https://api.github.com/users/jamesgolick/starred{/owner}{/repo}",
    "subscriptions_url": "https://api.github.com/users/jamesgolick/subscriptions",
    "organizations_url": "https://api.github.com/users/jamesgolick/orgs",
    "repos_url": "https://api.github.com/users/jamesgolick/repos",
    "events_url": "https://api.github.com/users/jamesgolick/events{/privacy}",
    "received_events_url": "https://api.github.com/users/jamesgolick/received_events",
    "type": "User",
    "site_admin": false
  },
  {
    "login": "atmos",
    "id": 38,
    "node_id": "MDQ6VXNlcjM4",
    "avatar_url": "https://avatars3.githubusercontent.com/u/38?v=4",
    "gravatar_id": "",
    "url": "https://api.github.com/users/atmos",
    "html_url": "https://github.com/atmos",
    "followers_url": "https://api.github.com/users/atmos/followers",
    "following_url": "https://api.github.com/users/atmos/following{/other_user}",
    "gists_url": "https://api.github.com/users/atmos/gists{/gist_id}",
    "starred_url": "https://api.github.com/users/atmos/starred{/owner}{/repo}",
    "subscriptions_url": "https://api.github.com/users/atmos/subscriptions",
    "organizations_url": "https://api.github.com/users/atmos/orgs",
    "repos_url": "https://api.github.com/users/atmos/repos",
    "events_url": "https://api.github.com/users/atmos/events{/privacy}",
    "received_events_url": "https://api.github.com/users/atmos/received_events",
    "type": "User",
    "site_admin": false
  },
  {
    "login": "errfree",
    "id": 44,
    "node_id": "MDEyOk9yZ2FuaXphdGlvbjQ0",
    "avatar_url": "https://avatars2.githubusercontent.com/u/44?v=4",
    "gravatar_id": "",
    "url": "https://api.github.com/users/errfree",
    "html_url": "https://github.com/errfree",
    "followers_url": "https://api.github.com/users/errfree/followers",
    "following_url": "https://api.github.com/users/errfree/following{/other_user}",
    "gists_url": "https://api.github.com/users/errfree/gists{/gist_id}",
    "starred_url": "https://api.github.com/users/errfree/starred{/owner}{/repo}",
    "subscriptions_url": "https://api.github.com/users/errfree/subscriptions",
    "organizations_url": "https://api.github.com/users/errfree/orgs",
    "repos_url": "https://api.github.com/users/errfree/repos",
    "events_url": "https://api.github.com/users/errfree/events{/privacy}",
    "received_events_url": "https://api.github.com/users/errfree/received_events",
    "type": "Organization",
    "site_admin": false
  },
  {
    "login": "mojodna",
    "id": 45,
    "node_id": "MDQ6VXNlcjQ1",
    "avatar_url": "https://avatars2.githubusercontent.com/u/45?v=4",
    "gravatar_id": "",
    "url": "https://api.github.com/users/mojodna",
    "html_url": "https://github.com/mojodna",
    "followers_url": "https://api.github.com/users/mojodna/followers",
    "following_url": "https://api.github.com/users/mojodna/following{/other_user}",
    "gists_url": "https://api.github.com/users/mojodna/gists{/gist_id}",
    "starred_url": "https://api.github.com/users/mojodna/starred{/owner}{/repo}",
    "subscriptions_url": "https://api.github.com/users/mojodna/subscriptions",
    "organizations_url": "https://api.github.com/users/mojodna/orgs",
    "repos_url": "https://api.github.com/users/mojodna/repos",
    "events_url": "https://api.github.com/users/mojodna/events{/privacy}",
    "received_events_url": "https://api.github.com/users/mojodna/received_events",
    "type": "User",
    "site_admin": false
  },
  {
    "login": "bmizerany",
    "id": 46,
    "node_id": "MDQ6VXNlcjQ2",
    "avatar_url": "https://avatars2.githubusercontent.com/u/46?v=4",
    "gravatar_id": "",
    "url": "https://api.github.com/users/bmizerany",
    "html_url": "https://github.com/bmizerany",
    "followers_url": "https://api.github.com/users/bmizerany/followers",
    "following_url": "https://api.github.com/users/bmizerany/following{/other_user}",
    "gists_url": "https://api.github.com/users/bmizerany/gists{/gist_id}",
    "starred_url": "https://api.github.com/users/bmizerany/starred{/owner}{/repo}",
    "subscriptions_url": "https://api.github.com/users/bmizerany/subscriptions",
    "organizations_url": "https://api.github.com/users/bmizerany/orgs",
    "repos_url": "https://api.github.com/users/bmizerany/repos",
    "events_url": "https://api.github.com/users/bmizerany/events{/privacy}",
    "received_events_url": "https://api.github.com/users/bmizerany/received_events",
    "type": "User",
    "site_admin": false
  }
]
""".data(using: .utf8)!

extension KeyedDecodingContainer {
    func decode<ResultType: Decodable>(forKey key: Key, defaultValue: ResultType) -> ResultType {
        do {
            return (try? decode(ResultType.self, forKey: key)) ?? defaultValue
        }
    }
}


struct User: Codable {
    
    let login: String
    let id: Int
    let nodeId: String
    let avatarUrl: String
    let gravatarId: String
    let url: String
    let htmlUrl: String
    let followersUrl: String
    let followingUrl: String
    let gistsUrl: String
    let starredUrl: String
    let subscriptionsUrl: String
    let organizationsUrl: String
    let reposUrl: String
    let eventsUrl: String
    let receivedEventsUrl: String
    let type: String
    let siteAdmin: Bool
    
    enum CodingKeys: String, CodingKey {
        case login
        case id
        case nodeId = "node_id"
        case avatarUrl = "avatar_url"
        case gravatarId = "gravatar_id"
        case url
        case htmlUrl = "html_url"
        case followersUrl = "followers_url"
        case followingUrl = "following_url"
        case gistsUrl = "gists_url"
        case starredUrl = "starred_url"
        case subscriptionsUrl = "subscriptions_url"
        case organizationsUrl = "organizations_url"
        case reposUrl = "repos_url"
        case eventsUrl = "events_url"
        case receivedEventsUrl = "received_events_url"
        case type
        case siteAdmin = "site_admin"
    }
    
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        login = container.decode(forKey: CodingKeys.login, defaultValue: "")
        id = container.decode(forKey: CodingKeys.id, defaultValue: 0)
        nodeId = container.decode(forKey: CodingKeys.nodeId, defaultValue: "")
        avatarUrl = container.decode(forKey: CodingKeys.avatarUrl, defaultValue: "")
        gravatarId = container.decode(forKey: CodingKeys.gravatarId, defaultValue: "")
        url = container.decode(forKey: CodingKeys.url, defaultValue: "")
        htmlUrl = container.decode(forKey: CodingKeys.htmlUrl, defaultValue: "")
        followersUrl = container.decode(forKey: CodingKeys.followersUrl, defaultValue: "")
        followingUrl = container.decode(forKey: CodingKeys.followingUrl, defaultValue: "")
        gistsUrl = container.decode(forKey: CodingKeys.gistsUrl, defaultValue: "")
        starredUrl = container.decode(forKey: CodingKeys.starredUrl, defaultValue: "")
        subscriptionsUrl = container.decode(forKey: CodingKeys.subscriptionsUrl, defaultValue: "")
        organizationsUrl = container.decode(forKey: CodingKeys.organizationsUrl, defaultValue: "")
        reposUrl = container.decode(forKey: CodingKeys.reposUrl, defaultValue: "")
        eventsUrl = container.decode(forKey: CodingKeys.eventsUrl, defaultValue: "")
        receivedEventsUrl = container.decode(forKey: CodingKeys.receivedEventsUrl, defaultValue: "")
        type = container.decode(forKey: CodingKeys.type, defaultValue: "")
        siteAdmin = container.decode(forKey: CodingKeys.siteAdmin, defaultValue: false)
    }
}


// Decode
let users = try? JSONDecoder().decode([User].self, from: data!)
if let user = users?.first {
    print(user.login)
    print(user.id)
    print(user.nodeId)
    print(user.avatarUrl)
    print(user.gravatarId)
    print(user.url)
    print(user.htmlUrl)
    print(user.followersUrl)
    print(user.followingUrl)
    print(user.gistsUrl)
    print(user.starredUrl)
    print(user.subscriptionsUrl)
    print(user.organizationsUrl)
    print(user.reposUrl)
    print(user.eventsUrl)
    print(user.receivedEventsUrl)
    print(user.type)
    print(user.siteAdmin)
}

// Encode
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
let encoded = try! encoder.encode(users)
print(String(data: encoded, encoding: .utf8)!)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment