SwiftUI로 앱을 만들다 보면 데이터를 외부에서 받아오는 일이 꼭 생긴다.
예를 들어 JSON 데이터를 받아서 리스트로 보여주는 상황.
이럴 때 흔히 쓰는 코드가 바로 이거다.
let (data, _) = try! await URLSession.shared.data(from: url!)
이 한 줄에 !가 두 개나 들어간다.
근데 try! 이렇게 쓰는 방식은 권장은 안한다고 한다.
try! await URLSession.shared.data(from:) 이 한 줄이 뭘 의미할까?이 코드의 동작을 찬찬히 뜯어보자.
URLSession.shared.data(from:): 네트워크 요청을 보낸다.await: 네트워크 응답이 올 때까지 기다린다.try!: 오류가 나더라도 무시하고 실행한다.(data, _): 받은 응답 중 data만 쓰고, 메타정보는 무시한다.그럼 여기서 궁금한 게 하나 생긴다.
왜 !를 이렇게 두 번이나 쓰는 걸까....
Swift에서 !는 두 가지 상황에서 자주 등장한다.
url!: 옵셔널 강제 해제let url = URL(string: "https://example.com")!
URL(string:)은 옵셔널을 반환한다.
왜냐면 문자열이 진짜 URL일지 아닐지 알 수 없기 때문.
그래서 저렇게 !를 붙이면 "무조건 URL이 맞을 거야!" 하고 강제로 열어버린다.
근데 만약 문자열이 잘못돼서 nil이면
앱크래시 문구가 뜬다.
try!: 에러 강제 무시let (data, _) = try! await URLSession.shared.data(from: url!)
이 함수는 실패할 수도 있다.
예를 들어 인터넷이 안 된다든가, URL이 잘못됐다든가.
그럴 때 보통은 try?나 do-catch를 써야 하는데,
try!를 사용하게 되면 앱크래시가 발생하게 된다.
테스트할 때는 try!, url!을 써도 괜찮다.
데이터가 무조건 있다는 걸 알고 있고, 빠르게 확인하고 싶을 때.
하지만 실서비스 앱이라면,
✅ guard let으로 URL 안전하게 열고
✅ do-catch로 네트워크 요청 에러도 잡아줘야 한다.
- gpt 피셜 -
네트워크 응답으로 JSON을 받았다면
그걸 모델 객체로 바꾸는 작업이 필요하다.
그때 사용하는 게 바로 이 세 가지 프로토콜이다.
| 프로토콜 | 역할 | 언제 쓰나 |
|---|---|---|
Decodable | JSON → 객체 | 서버 응답 디코딩할 때 |
Encodable | 객체 → JSON | 서버에 요청 보낼 때 |
Codable | 둘 다 가능 | 대부분의 경우 이걸 씀 |
예를 들어 이런 모델이 있다
struct Drama: Codable {
let title: String
let year: Int
}
근데 JSON 키가 year가 아니라 releaseYear라면?
enum CodingKeys: String, CodingKey {
case title
case year = "releaseYear"
}
이렇게 키 매핑을 해주면 된다.
Swift에서는 구조체의 프로퍼티 이름과 JSON 키가 다르면 반드시 CodingKeys를 지정해줘야 제대로 파싱된다.