본문 바로가기
공부/스위프트

[스위프트] URLSession열고 데이터 받아와서 테이블뷰로 넘겨주고 테이블뷰에 데이터를 넣어서 보여주기 - 1

by 초코팅촉 2023. 9. 19.
728x90

날씨앱을 만들어보는 중인데 정말 여기저기 삽질을 많이 했다...

나같이 고생하는 사람이 없길 바라며 적어본다.

어체는 와리가리합니다잉

참고로 이 글은 OpenWeatherAPI를 이용한 글이며 가끔 왜 없는 내용이 튀어나오지? 할수있는데 그건 이미 제가 구조체를 만들어놨거나 다른데에 선언해놓은 내용을 그대로 적어놓은것이라 써있을 수 있습니다.(그게 갑자기 튀어나온다해서 이해를 못할 부분도 아니기도 하고 설명도 간략하게 적어놓을거에요. 쭉 읽어보시면 이해될겁니다.)

 

1. url세션으로 데이터 받아오기

우선 NetworkManager.swift를 만들고 여기안에서 url세션을 만들어 주고 데이터를 받아오는

performRequest(urlString: String) -> Void 함수를 만든다.

func performRequest(urlString: String) {
        if let url = URL(string: urlString) {
            let session = URLSession(configuration: .default)
            let task = session.dataTask(with: url) { (data, response, error) in
            
            //이 안이 앞으로 작성할 공간.
            
		}
        task.resume()
	}
}

1-1. 우선 performRequest 함수를 선언하는데 이때 우리는 미리 만들어놓은 url을 받아올 것이기에

urlString이라는 String변수를 받아온다.

1-2. 2번째 줄 - 받아온 url을 URL 인스턴스로 만든다.

1-3. 3번째 줄 - HTTP통신을 위해 우리가 앞서 만들어놓은 URL인스턴스를 이용해 URLSession을 만들어준다. 

1-4. dataTask 작업을 시작한다.

이때 여기서 중요한점은 뒤에 있는 (data, response, error) in ~~은 completion Handler를 후행 클로저로 만든것.

(마지막에 오는 매개변수가 클로저인경우 후행 클로저로 작성할 수 있다.)

let task = session.dataTask(with: url, completionHandler: (Data?, URLResponse?, Error?) -> Void)
//이것을 아래처럼

↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

let task = session.dataTask(with: url) { (data, response, error) in
	//body
}
//이렇게 후행 클로저(트레일링 클로저)방식으로 만들수 있다.

나는 안젤라 수업을 들어서 그랬는지(영어로 수업을 들으면서 기계번역된 자막을 보니 영상 내용을 제대로 이해 못했나보다.)

클로저 안의 내용이 비동기로 실행된다는 점을 몇일간의 삽질과 구글링끝에 알아냈다...

 

2.  클로저 안에서 실행될 내용 작성하기

자 그러면 이제 data와 response, error 이 세가지를 이용할 수 있게 되는데,

여기서 우리는 data와 error 두가지만 쓸꺼다.

//에러 발생하면 확인용
if error != nil {
	print(error)
}
//에러 내용을 사용자가 확인할 필요는 없고 우리(개발자)가 그걸 알아야겠죠?
//그래서 그냥 print하는걸로 합시다.

//옵셔널 바인딩을 이용해 data에 nil이 있는 경우엔 에러를 피해줍시다.
if let safeData = data {
	//body
}

1번의 body부분에 if문 두개를 작성한다.

 

첫번째 if문은 error를 nil인지 확인하고 nil인 경우엔 그냥 넘어가지만 nil이 아니면 에러가 발생했다는 거고 우리는 이를 확인해서 처리를 해줘야 한다. 그래서 일단은  print(error)를 써준다.

 

두번째 if문은 data가 데이터가 없이 nil만 있으면 이를 바로 가져다 쓰면 에러를 뿜으며 (장렬히 전사한다.) 애플리케이션이 죽어버린다.

이 문제를 해결하기 위해 안전하게 처리한다는 의미로 safeData라는 이름으로 변수를 만들어 옵셔널 바인딩을 한다.

여기서 data가 HTTP통신을 통해 받아온 JSON이다.

 

3. JSON 파싱하기

우리는 앞서 performRequest에서 JSON을 받아왔습니다.(그게 data입니다.)

자 그럼 이제 JSON을 파싱해야되지 않겠슴까?(JSON을 파싱(parsing; parse)한다는 말은 "구문분석 하다"라고도 합니다만 그냥 쉽게말해 우리가 미리 만들어 놓은 임의의 구조체로 맵핑한다 정도로 생각하면 될거 같아요.)

parseJSON 함수를 만듭니다.

func parseJSON(data: Data) -> WeatherData? {
        let decoder = JSONDecoder()
        do {
            let decodedData = try decoder.decode(WeatherData.self, from: data)
            return decodedData
        } catch {
            print(error)
            return nil
        }
    }

3-1. JSONDecoder()를  decoder로 인스턴스화 한다.

3-2. do catch문으로 앞서 미리 만들어놓은 WeatherData 구조체를 기반으로 data를 디코딩한다.

 

3-3. 성공하면 decodedData 반환하고 실패하면 nil을 반환한다.

이거 때문에 WeatherData 옵셔널로 반환형을 설정해준겁니다.

 

 

 

 

swift - 후행 클로저, url, urlsession, task.resume()