新手的 Swift JSON decode 練習題
Published in
4 min readApr 21, 2022
- 搭配 AI 建立自己感興趣的 JSON API
- iTunes
- apple marketing tools RSS generator
- Random User Generator
- GitHub
- Joke
- REST Countries
- Open Trivia(是非題/選擇題)
- IG
- Xcode Releases
- JSONPlaceholder
- UI Faces
- 請 AI 提供 API 網址
- 第三方 API 整理
題目
- 搭配 AI 建立自己感興趣的 JSON API
- iTunes
ex
https://itunes.apple.com/search?term=戴佩妮&media=music&country=tw
- apple marketing tools RSS generator
ex
https://rss.applemarketingtools.com/api/v2/tw/music/most-played/10/songs.json
- Random User Generator
ex
https://randomuser.me/api/?results=10
- GitHub
ex
https://api.github.com/users/twostraws/followers
- JokeAPI
- REST Countries
- Open Trivia API
- IG
抓取方法可參考以下連結。
若想直接練習,可從以下網址抓取最近退休的費神 Roger Federer 的 IG 動態 JSON。
https://raw.githubusercontent.com/AppPeterPan/CutePic/main/rogerfederer.json
- Xcode Releases
https://xcodereleases.com/data.json
- JSONPlaceholder
- UI Faces
- 請 AI 提供 API 網址
- 第三方 API 整理
解答
- iTunes
https://itunes.apple.com/search?term=戴佩妮&media=music&country=tw
struct SearchResponse: Decodable {
let resultCount: Int
let results: [StoreItem]
}
struct StoreItem: Decodable {
let artistName: String
let trackName: String
let collectionName: String?
let previewUrl: URL
let artworkUrl100: URL
let trackPrice: Double?
let releaseDate: Date
let isStreamable: Bool?
}
解碼的 decoder。
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
let searchResponse = try decoder.decode(SearchResponse.self, from: data)
- apple marketing tools RSS generator
https://rss.applemarketingtools.com/api/v2/tw/music/most-played/10/songs.json
struct SearchResponse: Decodable {
let feed: Feed
}
struct Feed: Decodable {
let title: String
let results: [Item]
}
struct Item: Decodable {
let artistName: String
let id: String
let name: String
let artworkUrl100: URL
let releaseDate: Date
let url: URL
}
解碼的 decoder。
let decoder = JSONDecoder()
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
decoder.dateDecodingStrategy = .formatted(dateFormatter)
let searchResponse = try decoder.decode(SearchResponse.self, from: data)
- Random User Generator
https://randomuser.me/api/?results=10
struct UsersResponse: Decodable {
let results: [User]
}
struct User: Decodable {
let gender: String
let name: Name
let email: String
let picture: Picture
let dob: Dob
let location: Location
}
struct Name: Decodable {
let title: String
let first: String
let last: String
}
struct Picture: Decodable {
let large: String
let medium: String
let thumbnail: String
}
struct Dob: Decodable {
let date: Date
let age: Int
}
struct Location: Decodable {
let city: String
let country: String
let state: String
let coordinates: Coordinate
let street: Street
}
struct Coordinate: Decodable {
let latitude: String
let longitude: String
}
struct Street: Decodable {
let number: Int
let name: String
}
解碼的 decoder。
let decoder = JSONDecoder()
let dateFormatter = ISO8601DateFormatter()
dateFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
decoder.dateDecodingStrategy = .custom({ decoder in
let container = try decoder.singleValueContainer()
let dateString = try container.decode(String.self)
if let date = dateFormatter.date(from: dateString) {
return date
} else {
throw DecodingError.dataCorruptedError(in: container, debugDescription: "Invalid date format")
}
})
let usersResponse = try decoder.decode(UsersResponse.self, from: data)
- GitHub
https://api.github.com/users/twostraws/followers
struct Follower: Decodable {
let login: String
let id: Int
let avatarUrl: URL
let htmlUrl: URL
let reposUrl: URL
}
解碼的 decoder。
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let followers = try decoder.decode([Follower].self, from: data)
- IG
https://www.instagram.com/rogerfederer/?__a=1&__d=dis
struct IGResponse: Decodable {
let graphql: Graphql
}
struct Graphql: Decodable {
let user: User
}
struct User: Decodable {
let biography: String
let fullName: String
let edgeFollowedBy: Count
let edgeFollow: Count
let profilePicUrl: URL
let edgeOwnerToTimelineMedia: EdgeOwnerToTimelineMedia
}
struct Count: Decodable {
let count: Int
}
struct EdgeOwnerToTimelineMedia: Decodable {
let count: Int
let edges: [Edge]
}
struct Edge: Decodable {
let node: Node
struct Node: Decodable {
let displayUrl: URL
let edgeMediaToCaption: Caption
let edgeMediaToComment: Count
let takenAtTimestamp: Date
let edgeLikedBy: Count
let dimensions: Dimension
let thumbnailResources: [Thumbnail]
}
}
struct Dimension: Decodable {
let height: Int
let width: Int
}
struct Caption: Decodable {
let edges: [TextEdge]
}
struct TextEdge: Decodable {
let node: Node
struct Node: Decodable {
let text: String
}
}
struct Thumbnail: Decodable {
let src: URL
let configWidth: Int
let configHeight: Int
}
解碼的 decoder。
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
decoder.dateDecodingStrategy = .secondsSince1970
let igResponse = try decoder.decode(IGResponse.self, from: data)