Swiftでhttp通信してデータの一覧表示&詳細表示の備忘録です。
詳細
import SwiftUI
struct DeatilView: View {
@State private var responseText: String = "Loading..."
@State private var post: Post? = nil // デコードしたデータを格納
struct Post: Codable {
var id: Int
var title: String
var body: String
}
var body: some View {
NavigationStack{
VStack {
if let post = post {
Text("ID: \(post.id)").padding()
Text("Title: \(post.title)").padding()
Text("Body: \(post.body)").padding()
} else {
Text(responseText).padding()
}
}
.onAppear {
fetchData()
}
.navigationTitle("詳細画面")
}
}
private func fetchData() {
// APIエンドポイントのURL
guard let url = URL(string: "https://jsonplaceholder.typicode.com/posts/1") else {
responseText = "Invalid URL"
return
}
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.addValue("application/json", forHTTPHeaderField: "Accept")
// 非同期にデータを取得
URLSession.shared.dataTask(with: request) { data, response, error in
if let error = error {
DispatchQueue.main.async {
responseText = "Error: \(error.localizedDescription)"
}
return
}
guard let data = data else {
DispatchQueue.main.async {
responseText = "No data received"
}
return
}
// JSONをデコードして表示
do {
let decodedPost = try JSONDecoder().decode(Post.self, from: data)
DispatchQueue.main.async {
post = decodedPost
}
} catch {
DispatchQueue.main.async {
responseText = "JSON error: \(error.localizedDescription)"
}
}
}.resume()
}
}
#Preview {
ContentView()
}
一覧
import SwiftUI
struct IndexlView: View {
@State private var responseText: String = "Loading..."
@State private var posts: [Post] = [] // 配列で格納
struct Post: Codable, Identifiable { // Identifiableを追加
let id: Int
let title: String
let body: String
// initは不要(Codableが自動生成)
}
var body: some View {
NavigationStack {
VStack {
if posts.isEmpty { // postsが空の場合
Text(responseText).padding()
} else { // データがある場合
List(posts) { post in // postをForEachで回す必要はない
VStack(alignment: .leading) { // VStackで整列
Text("ID: \(post.id)")
Text("Title: \(post.title)")
Text("Body: \(post.body)")
}
}
}
}
.onAppear {
fetchData()
}
.navigationTitle("HTTP通信:配列で一覧")
}
}
private func fetchData() {
guard let url = URL(string: "https://jsonplaceholder.typicode.com/posts") else { // postsエンドポイント
responseText = "Invalid URL"
return
}
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.addValue("application/json", forHTTPHeaderField: "Accept")
URLSession.shared.dataTask(with: request) { data, response, error in
if let error = error {
DispatchQueue.main.async {
responseText = "Error: \(error.localizedDescription)"
}
return
}
guard let data = data else {
DispatchQueue.main.async {
responseText = "No data received"
}
return
}
do {
let decodedPosts = try JSONDecoder().decode([Post].self, from: data) // [Post]の配列型
DispatchQueue.main.async {
posts = decodedPosts
}
} catch {
DispatchQueue.main.async {
responseText = "JSON error: \(error.localizedDescription)"
}
}
}.resume()
}
}
#Preview {
IndexlView()
}