[Swift Concurrency] Do, Try, Catch, Throws

Woozoo·2023년 4월 15일

[Swift Concurrency]

목록 보기
1/13
class DoCatchTryThrowsBootcampDataManager {
    
    let isActive: Bool = false
    
    func getTitle() -> String? {
        if isActive {
            return "New Text!"
        } else {
            return nil
        }
    }
}

class DoCatchTryThrowsBootcampViewModel: ObservableObject {
    @Published var text: String = "Starting text."
    let manager = DoCatchTryThrowsBootcampDataManager()
    
    func fetchTitle() {
        let newTitle = manager.getTitle()
        if let newTitle = newTitle {
            self.text = newTitle
        }
    }
}

struct DoCatchTryThrowsBootcamp: View {
    @StateObject private var viewModel = DoCatchTryThrowsBootcampViewModel()
    
    var body: some View {
        Text(viewModel.text)
            .frame(width: 300, height: 300)
            .background(Color.blue)
            .onTapGesture {
                viewModel.fetchTitle()
            }
    }
}

요런 flow가 있다고 해봅시다

지금 DataManager에 getTitle에서 옵셔널한 string이 실패할 때가 있는데 나 말고 협업하는 사람이 와서 보거나 하면 이게 error가 잘 처리되고 있는 건지 모르잖음



그럴 때 요렇게 error까지 튜플로 보내주는 거임!
그럼 error가 떴을 때 그 결과도 보내줄 수 있게 됨


조금 더 가봅시다
지금 보면 성공이나 실패 둘 중에 하나만 나오는데도 tuple로 넘겨주고 있었잖음
이거 더 효율적으로 할 방법이 없을까?

Result를 쓰는겨

요런식으로!
Result에 들어가는 제네릭한 타입을 String이랑 Error로 지정하고
성공했을 때랑 실패했을 때 경우를 나눠줄 수 있음

ViewModel에서 이 getTitle2메소드를 불러보면

Result 타입이 나오는 걸 알 수 있습니다~
이거 어디서 했었죠!
combine 쓸 때 receivedValue completion에 대한 처리할 때 했었죠

이렇게 Result라는 enum타입으로
성공과 실패의 케이스에 대한 로직을 작성해줄 수 있습니다!


func getTitle3() throws -> String {
    if isActive {
        return "NEW TEXT!"
    } else {
        throw URLError(.badServerResponse)
    }
}

여기서 한번더 가면 Result를 반환하지 않고도 Error를 뱉으면서 코드를 빠져나가게 해주는 게 가능함!

함수 자체에 throws라는 키워드를 붙이게 되면 error가 뜨는 시점에 error를 던져주게 됨





메소드에 throws를 붙이고 나면 호출할 때 try라는 키워드가 필요하고
try를 사용하게 되면 error가 떴을 때 catch구문에서 이걸 어떻게 처리할 지 지정해주는거임!!

try구문이 실패하게되면 self.text = newTitle은 실행 되지 않고 바로 catch구문으로 넘어가게 된다!!!
참 그리고 catch let error도 그냥 catch로 생략가능

하나더!

try가 여러개인데 이 중에 하나가 실패했다,
다른 거 실행안하고 바로 catch로 넘어갑니다~



try에 물음표를 붙이게되면?

error 뜰 때 신경 안쓰고 이거 실패하면 nil로 반환할거임~!
해주는 거라 try? 를 사용하게 되면 do catch 구문이 따로 필요 없게 됩니다!!!

error가 떴을 때 유저한테 안보여줘도 되거나 third Party같은 것들 쓸 때 그냥 try?로 써서 시간을 절약해줄 수 있음


하나 생각해볼 점은 try?로 이렇게 옵셔널하게 값을 넘기겠다! 했을 때

getTitle3가 실패하더라도 catch 구문으로 넘어가지 않고, getTitle4까지도 실행하게 됨

profile
우주형

0개의 댓글