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까지도 실행하게 됨