SwiftUI - 来自 GitHub REST API 的 JSON 无法解析
SwiftUI - JSON from GitHub REST API fails to parse
我正在尝试使用 GitHub 的 REST API 在 SwiftUI 中创建一个应用程序。我试图只检索给定用户的关注者的登录名和个人资料图片,然后填充 List
.
FollowersView.swift
import SwiftUI
struct Follower: Codable, Hashable {
public var login: String
public var avatar_url: String
}
struct Response: Codable {
var followers: [Follower] = [Follower]()
}
struct FollowersView: View {
@EnvironmentObject var followerInfo: FollowerInfo
@State var followers: [Follower] = [Follower]()
init() {
UINavigationBar.appearance().largeTitleTextAttributes = [.foregroundColor: UIColor.white]
}
var body: some View {
NavigationView {
ZStack {
Color.black.edgesIgnoringSafeArea(.all)
List(followers, id: \.self) { follower in
HStack(spacing: 10) {
Image(decorative: "\(follower.avatar_url).png")
.resizable()
.frame(width: 75, height: 75)
HStack(spacing: 5) {
Image(systemName: "person")
Text("\(follower.login)").fontWeight(.heavy)
}
}
}
.onAppear(perform: loadData)
}
.navigationBarTitle("\(followerInfo.followerUsername)")
}
}
func loadData() {
guard let url = URL(string: "https://api.github.com/users/\(followerInfo.followerUsername)/followers") else {
print("Invalid URL")
return
}
let request = URLRequest(url: url)
URLSession.shared.dataTask(with: request) { data, response, error in
if let data = data {
if let decodedResponse = try? JSONDecoder().decode(Response.self, from: data) {
DispatchQueue.main.async {
self.followers = decodedResponse.followers
}
return
}
}
print("Fetch failed: \(error?.localizedDescription ?? "Unknown Error")")
}.resume()
}
}
struct FollowersView_Previews: PreviewProvider {
static var previews: some View {
FollowersView()
}
}
代码到达 print("Fetch failed: \(error?.localizedDescription ?? "Unknown Error")")
并在崩溃前打印“未知错误”。检查返回的数据后,它什么也没有,至少我无法说出来。 (我并不完全习惯 Xcode 调试器)。我仔细检查了浏览器中的 API 响应,浏览器响应中的字段和 Codable 结构中的属性名称匹配。所以,我不确定这里发生了什么。关于如何解决这个问题有什么建议吗?
如果我没有正确理解你的问题。如下所示更新您的 Codable
:
import Foundation
// MARK: - FollowerElement
struct FollowerElement: Codable {
let login: String
let id: Int
let nodeID: String
let avatarURL: String
let gravatarID: String
let url, htmlURL, followersURL: String
let followingURL, gistsURL, starredURL: String
let subscriptionsURL, organizationsURL, reposURL: String
let eventsURL: String
let receivedEventsURL: String
let type: String
let siteAdmin: Bool
enum CodingKeys: String, CodingKey {
case login, 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"
}
}
typealias Follower = [FollowerElement]
您可以从上面的代码中删除不需要的属性。
现在更新您的 dataTask
方法
URLSession.shared.dataTask(with: request) { data, response, error in
if let error = error {
print("Fetch failed: \(error.localizedDescription)")
} else {
if let data = data {
do {
let follower = try JSONDecoder().decode(Follower.self, from: data)
DispatchQueue.main.async {
print(follower.count)
}
} catch {
print(error)
}
}
}
}.resume()
我正在尝试使用 GitHub 的 REST API 在 SwiftUI 中创建一个应用程序。我试图只检索给定用户的关注者的登录名和个人资料图片,然后填充 List
.
FollowersView.swift
import SwiftUI
struct Follower: Codable, Hashable {
public var login: String
public var avatar_url: String
}
struct Response: Codable {
var followers: [Follower] = [Follower]()
}
struct FollowersView: View {
@EnvironmentObject var followerInfo: FollowerInfo
@State var followers: [Follower] = [Follower]()
init() {
UINavigationBar.appearance().largeTitleTextAttributes = [.foregroundColor: UIColor.white]
}
var body: some View {
NavigationView {
ZStack {
Color.black.edgesIgnoringSafeArea(.all)
List(followers, id: \.self) { follower in
HStack(spacing: 10) {
Image(decorative: "\(follower.avatar_url).png")
.resizable()
.frame(width: 75, height: 75)
HStack(spacing: 5) {
Image(systemName: "person")
Text("\(follower.login)").fontWeight(.heavy)
}
}
}
.onAppear(perform: loadData)
}
.navigationBarTitle("\(followerInfo.followerUsername)")
}
}
func loadData() {
guard let url = URL(string: "https://api.github.com/users/\(followerInfo.followerUsername)/followers") else {
print("Invalid URL")
return
}
let request = URLRequest(url: url)
URLSession.shared.dataTask(with: request) { data, response, error in
if let data = data {
if let decodedResponse = try? JSONDecoder().decode(Response.self, from: data) {
DispatchQueue.main.async {
self.followers = decodedResponse.followers
}
return
}
}
print("Fetch failed: \(error?.localizedDescription ?? "Unknown Error")")
}.resume()
}
}
struct FollowersView_Previews: PreviewProvider {
static var previews: some View {
FollowersView()
}
}
代码到达 print("Fetch failed: \(error?.localizedDescription ?? "Unknown Error")")
并在崩溃前打印“未知错误”。检查返回的数据后,它什么也没有,至少我无法说出来。 (我并不完全习惯 Xcode 调试器)。我仔细检查了浏览器中的 API 响应,浏览器响应中的字段和 Codable 结构中的属性名称匹配。所以,我不确定这里发生了什么。关于如何解决这个问题有什么建议吗?
如果我没有正确理解你的问题。如下所示更新您的 Codable
:
import Foundation
// MARK: - FollowerElement
struct FollowerElement: Codable {
let login: String
let id: Int
let nodeID: String
let avatarURL: String
let gravatarID: String
let url, htmlURL, followersURL: String
let followingURL, gistsURL, starredURL: String
let subscriptionsURL, organizationsURL, reposURL: String
let eventsURL: String
let receivedEventsURL: String
let type: String
let siteAdmin: Bool
enum CodingKeys: String, CodingKey {
case login, 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"
}
}
typealias Follower = [FollowerElement]
您可以从上面的代码中删除不需要的属性。
现在更新您的 dataTask
方法
URLSession.shared.dataTask(with: request) { data, response, error in
if let error = error {
print("Fetch failed: \(error.localizedDescription)")
} else {
if let data = data {
do {
let follower = try JSONDecoder().decode(Follower.self, from: data)
DispatchQueue.main.async {
print(follower.count)
}
} catch {
print(error)
}
}
}
}.resume()