안녕하세요 이웃님들~ 그리고 Swift 정보의 바다속에서 어쩌다가 제 블로그에 방문하신 여러분~
저는 모호한것을 참 싫어하는데요~ 그래서 앱개발과외할때도 그렇고 항상 퍼뜩 이해가 되는 설명을 하고 싶어해요~
Async/Await에 대해서 앞으로 몇개의 글을 올릴 예정인데요!
오늘은 들어가기에 앞서 기본적으로 알아야 하는 문법이 있어서 그것 먼저 설명을 드리겠습니다!
기존에 이 문법을 잘 알고계신 분이라면 다음 화로 진행하세요!
영어시간에 다들 Do, Try, Catch, Throw라는 단어 다 배우셨죠~ 저도 배웠습니다~ 하하
Do -> 해라
Try -> 해봐라
Catch -> 잡아라
Throw -> 던져라
네 참 쉬운데요?
Swift 문법에서도 이 단어들을 종종 보게 됩니다ㅎㅎ
오늘 설명할 Do, Try, Catch 문법에서 그렇습니다!
엄청 어려운건 아니고요~ 이런 상황에서 쓰입니다.
우리가 이미지를 받아오는 함수를 작성한다면 아래와 같은 모양이겠죠~~
func getImage() -> UIImage {
}
근데 이미지를 API로 받아오게 된다면... (대부분 API로 이미지 받아오잖아요.. 그쵸?)
이 동작은 비동기 적일겁니다.
비동기가 뭐냐!
우리가 API 요청을 하면 서버에 가서 응답을 받아와야 하잖아요? 아마 뭐 저기 땅끝마을 서버실에 갔다가 올수도 있고... 하여튼 좀 늦게옵니다. 그래서 요청하고 나서 저희는 저희 할 일을 좀 하다가 응답이 왔다고 하면? 그때 가서 그 이미지를 받아서 가공을 하든 그림을 바꿔주든 우리가 응답으로 받은 내용을 사용하고 싶습니다. 이런 동작을 비동기 라고 합니다.
자 그러면 일단 throws 키워드를 사용해서 우리가 만든 getImage 함수 안에 API 요청을 하는 코드를 작성해볼게요~!
어떤 함수를 만들었는데, 그 함수가 성공과 실패시에 서로 다른 타입의 값을 전달해준다면.. 우리 기존에는 어떻게 했을까요? Result 타입으로 성공 실패를 나누어주거나, escaping closure사용해서 completionHandler를 사용할때는 인자로 넣어주기도 하고 그랬을거예요~
throws는 조금더 명확하게~ 깔끔하게~ 성공과 실패를 나눠줄수가 있어요.
여기서 잠깐~ throw라는 단어 왜쓸까요? 우리도 에러를 던져준다고 하잖아요? 원래도 영어로 에러가 발생한다 할때 throws an error 이런식으로 말해서 사실 그냥 동사를 그대로 갖다 쓴거예요~
그래서 함수 리턴하기 전에 그앞에 throws가 써있다? 에러일때는 뭔가 다른걸 던져주고 있다 보시면 됩니다~!
// 주소는 예시예요! 이미지를 불러올 이미지 주소를 넣어주고
let url = URL(string: "https://ios-developer-storage.tistory.com/")!
func getImage() throws -> UIImage {
// 그럼 이 if문까지는 동기적으로 실행이 주욱 되다가
if URLSession.shared.dataTask(with: url) { data, response, error in
// 요 안에는 비동기로 나중에 실행이 되겠죠?
// 이 가드문을 잘 통과하면 이미지가 온거고, 아니면 실패를 한거겠죠?
guard
let data = data,
let image = UIImage(data: data),
let response = response as? HTTPURLResponse else {
// 실패했을때는 에러에 디스크립션을 전달해주고 싶어서 여기에서 throw를 사용합니다.
throw error.localizeddescription
}
// 여기는 성공했을 때니까 정상적으로 이미지를 리턴해줍니다.
return image
}
}
자 그러면~ 이렇게 작성한 함수를 사용할때는 어떻게 하면 될까요?
사용할때는 try를 기억하시면 됩니다.
이렇게 쓰면 "너 throw 라서 실패하면 이미지가 아니라 다른거 올건데 이렇게 쓰면 어떡해!" 라고 앵앵 웁니다.
let image = getImage()
이렇게 써주시면 됩니다. 정말 쉽군요.
let image = try getImage()
try를 쓰면 좋은점이 do, catch 구문을 써서 에러를 핸들링하기가 참 좋다는 것인데요.
굳이 throw로 에러처리를 했으니까 do, catch와 함께 깔끔한 에러처리를 해보겠습니다.
보시면 아시겠지만, do 안에는 throw하는 함수를 호출해서 성공했을 때의 처리를 해주시면 되는데요, try가 실패하면 그 이하의 코드는 모두 실행이 되지 않아요. 그리고 바로 catch로 넘어갑니다.
만약에 try가 실패하더라도 이하의 구문들이 실행이 되었으면 좋겠다면 try? 를 사용해서 옵셔널하게 해주시면 catch로 바로 넘어가지 않고 실행을 다 할겁니다.
do {
let image = try getImage()
} catch {
print(error)
}
자 이렇게 do { try } catch { 에러처리 } 를 다 배웠습니다!
다음 시간에는 do, try, catch가 async await 적용하면서 왜 필요한지 보면서
async await을 알아보도록 하겠습니다~!!
ㅎㅎ
[Swift Concurrency] Async/Await 진짜 쉽게 이해하기 (3) - 흔히 하는 실수 (1) | 2023.06.13 |
---|---|
[Swift Concurrency] Async/Await 진짜 쉽게 이해하기 (2) - 작성법 배우기 (0) | 2023.06.13 |
[Swift/iOS] 촬영한 이미지 돌아감 현상의 원인과 해결방법 (+카메라앱) (0) | 2023.02.13 |
[Medium/번역] Swift 로 Money Type 만들기 (0) | 2022.10.06 |
[RxSwift] Traits를 사용하는 이유와 Single, Driver, Signal 예제 (0) | 2022.09.06 |