[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)
}