Swiftでhttp通信してデータの一覧表示&詳細表示

Swiftでhttp通信してデータの一覧表示&詳細表示の備忘録です。

## 詳細


```swift
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()
}

```

## 一覧
```swift
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()
}

```