본문 바로가기

Swift & SwiftUI

Networking for beginners

나중에 또 까먹을 저를 위해 기록하는 거여서 설명이 자세하지 않을 수 있습니다.

 

여기 아래 유튜브를 보시면 더 자세한 내용을 알 수 있습니다.

https://www.youtube.com/watch?v=ERr0GXqILgc 

서버에서 데이터를 받아 화면에 보여지도록 만드는 방법이다.

크게 4가지 순서로 나눌 수 있다.

  1. Build Dummy UI
  2. Create Model
  3. Write Networking Code
  4. Connect it

 

 


   1. Build Dummy UI

 

데이터를 받으면 어떻게 보여줄 것인지 보여줄 부분을 미리 만든다

 

 

   2.Create Model

 

Json 데이터를 받을 타입을 만듬.

Codable - Json 데이터로 encoding, decoding 할 수 있도록 해주는 프로토콜.

 

struct GitHubUser: Codable {
    let login: String
    let avatarUrl: String
    let bio : String
}

 

  3. Write Networking Code

 

서버에서 데이터를 받아오는데 시간이 걸릴 수 있기 때문에, async를 이용하여 비동기 처리를 한다.

async 함수를 호출하기 위해서는 await 키워드가 필요.

 

func getUser() async throws -> GitHubUser {
        let endPoint = "https://api.github.com/users/twostraws"
        
        //string 변수 endPoint를 URL 객체로 만들어줌
        guard let url = URL(string: endPoint) else {throw GHEerror.invalidURL}
        
        let (data, response) = try await URLSession.shared.data(from: url)
        
        guard let response = response as? HTTPURLResponse, response.statusCode == 200 else {
            throw GHEerror.invalidResponse
        }
		// do-try-catch
        do {
            let decoder = JSONDecoder()
			//snake case에서 camel case로 바꾸기 위해 (avatar_url → avatarUrl)
            decoder.keyDecodingStrategy = .convertFromSnakeCase
            return try decoder.decode(GitHubUser.self, from: data)
        } catch {
            throw GHEerror.invalidData
        }
    }
//custom error 객체를 만들어줌. 각 상황에 맞는 에러.
enum GHEerror: Error {
    case invalidURL
    case invalidResponse
    case invalidData
}

 

 

   4. Connect it

struct ContentView: View {
//@state user 설정하여 json 데이터를 받으면 UI 뷰에 반영할 수 있도록 한다. 
    @State private var user: GitHubUser?
    
    var body: some View {
        VStack {
            AsyncImage(url: URL(string: user?.avatarUrl ?? "")) { image in
                image
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .clipShape(Circle())
            } placeholder: {
                Circle()
                    .foregroundColor(.secondary)
            }
            .frame(width: 120, height: 120)
            
            Text(user?.login ?? "Login Placeholder" )
                .bold()
                .font(.title3)
            
            Text(user?.bio ?? "User Bio Placeholder")
                .padding()
            
            Spacer()
        }
        .padding()
		//task - Add an asynchronous task to perform before this view appears. 
        .task {
            do {
                user = try await getUser()
            } catch GHEerror.invalidURL{
                print("Invaloid URL")
            } catch GHEerror.invalidResponse {
                print("Invalid Response")
            } catch GHEerror.invalidData {
                print("Invalid Data")
            } catch {
                print("Unexpected error")
            }
        }
    }

 

 

 

 

 

 

'Swift & SwiftUI' 카테고리의 다른 글

100days of SwiftUi - project 7  (0) 2023.12.09
CS 193p Lecture 3~4 정리  (0) 2023.11.22
Optional Binding, Chaining  (0) 2023.10.09
사용자의 위치정보 가져오기  (0) 2023.10.05
Grid  (0) 2023.09.18