1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[iOS][Swift 4] CodableでJSONのパース (2)

Posted at

[iOS][Swift 4] CodableでJSONのパースの続きです。

JSONのキーとパースするクラスのプロパティ名が異なる場合のパース方法です。
基本的には、Using JSON with Custom Typesに書かれている内容です。

以下のようなJSONをパースする場合
GitHub Gists - List all public gists

let json = """
[
  {
    "url": "https://api.github.com/gists/aa5a315d61ae9438b18d",
    "forks_url": "https://api.github.com/gists/aa5a315d61ae9438b18d/forks",
    "commits_url": "https://api.github.com/gists/aa5a315d61ae9438b18d/commits",
    "id": "aa5a315d61ae9438b18d",
    "node_id": "MDQ6R2lzdGFhNWEzMTVkNjFhZTk0MzhiMThk",
    "description": "description of gist",
    "public": true,
    "owner": {
      "login": "octocat",
      "id": 1,
      "node_id": "MDQ6VXNlcjE=",
      "avatar_url": "https://github.com/images/error/octocat_happy.gif",
      "gravatar_id": "",
      "url": "https://api.github.com/users/octocat",
      "html_url": "https://github.com/octocat",
      "followers_url": "https://api.github.com/users/octocat/followers",
      "following_url": "https://api.github.com/users/octocat/following/other_user",
      "gists_url": "https://api.github.com/users/octocat/gists/gist_id",
      "starred_url": "https://api.github.com/users/octocat/starred/owner/repo",
      "subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
      "organizations_url": "https://api.github.com/users/octocat/orgs",
      "repos_url": "https://api.github.com/users/octocat/repos",
      "events_url": "https://api.github.com/users/octocat/events/privacy",
      "received_events_url": "https://api.github.com/users/octocat/received_events",
      "type": "User",
      "site_admin": false
    },
    "user": null,
    "files": {
      "ring.erl": {
        "size": 932,
        "raw_url": "https://gist.githubusercontent.com/raw/365370/8c4d2d43d178df44f4c03a7f2ac0ff512853564e/ring.erl",
        "type": "text/plain",
        "truncated": false,
        "language": "Erlang"
      }
    },
    "truncated": false,
    "comments": 0,
    "comments_url": "https://api.github.com/gists/aa5a315d61ae9438b18d/comments/",
    "html_url": "https://gist.github.com/aa5a315d61ae9438b18d",
    "git_pull_url": "https://gist.github.com/aa5a315d61ae9438b18d.git",
    "git_push_url": "https://gist.github.com/aa5a315d61ae9438b18d.git",
    "created_at": "2010-04-14T02:15:15Z",
    "updated_at": "2011-06-20T11:34:15Z"
  }
]
""".data(using: .utf8)!

プロパティ名と対応するキーをCodingKeysにて指定する。

struct GitHubGistsContentFile: Codable {
    let size: Int
    let rawUrl: URL
    let type: String
    let truncated: Bool
    let language: String
    
    private enum CodingKeys: String, CodingKey {
        case size
        case rawUrl = "raw_url"
        case type
        case truncated
        case language
    }
}

struct GitHubGistsContentOwner: Codable {
    let login: String
    let identity: Int
    let nodeIdentity: String
    let avatarUrl: URL
    let gravatarIdentity: String
    let url: URL
    let htmlUrl: URL
    let followersUrl: URL
    let followingUrl: URL
    let gistsUrl: URL
    let starredUrl: URL
    let subscriptionsUrl: URL
    let organizationsUrl: URL
    let reposUrl: URL
    let eventsUrl: URL
    let receivedEventsUrl: URL
    let type: String
    let siteAdmin: Bool

    private enum CodingKeys: String, CodingKey {
        case login
        case identity = "id"
        case nodeIdentity = "node_id"
        case avatarUrl = "avatar_url"
        case gravatarIdentity = "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"
    }
}

struct GitHubGistsContent: Codable {
    let url: URL
    let forkUrl: URL
    let commitUrl: URL
    let identity: String
    let nodeIdentity: String
    let description: String
    let isPublic: Bool
    let owner: GitHubGistsContentOwner
    let user: String?
    let files: Dictionary<String, GitHubGistsContentFile>?
    let truncated: Bool
    let comments: Int
    let commentsUrl: URL
    let htmlUrl: URL
    let gitPullUrl: URL
    let gitPushUrl: URL
    let createdDate: Date
    let updatedDate: Date
    
    private enum CodingKeys: String, CodingKey {
        case url
        case forkUrl = "forks_url"
        case commitUrl = "commits_url"
        case identity = "id"
        case nodeIdentity = "node_id"
        case description = "description"
        case isPublic = "public"
        case owner = "owner"
        case user
        case files
        case truncated
        case comments
        case commentsUrl = "comments_url"
        case htmlUrl = "html_url"
        case gitPullUrl = "git_pull_url"
        case gitPushUrl = "git_push_url"
        case createdDate = "created_at"
        case updatedDate = "updated_at"
    }
}

let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"   // "2010-04-14T02:15:15Z"
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .formatted(formatter)

do {
    let contents = try decoder.decode([GitHubGistsContent].self, from: json)
    print("contents = \(content)")
} catch {
    print(error)
}
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?