SwiftUI : If let과 Guard
If let / Guard
안전한 코딩은 정말 좋은 코드입니다. 값이 있는지 없는지 선택적 변수인지의 여부 등을 안전하게 나타내 줍니다.
안전한 코딩에는 if let
과 guard let
이 있습니다.
If let
의 대안은 guard let
이며 unwrapping 옵셔널도 이에 해당합니다. guard let
은 우리를 위해 언래핑 되지만, 내부에서 nil을 찾으면 사용한 함수, 루프 또는 조건을 종료할 수 있습니다.
guard let
도 if let
과 비슷하지만 다른 점이 있습니다.
guard
라는 것은 지키다 라는 뜻처럼, guard
문은 특성상 함수(메서드)에서만 쓰이며, guard
구문의 조건을 만족하지 못하면 else
문으로 빠져서 함수의 실행을 종료시킬 때 사용합니다.
If let
SwiftUI
에서 사용해보도록 하겠습니다.
import SwiftUI
struct ContentView: View {
@State var title: String = ""
@State var isLoading: Bool = false
// MARK: BODY
var body: some View {
NavigationView {
VStack {
Text("안녕하세요 서근 개발 블로그입니다.")
Text(title)
if isLoading {
ProgressView()
}
Text(isLoading.description)
.foregroundColor(isLoading ? Color.blue : Color.red)
}
.navigationBarTitle("Safe Coding")
.onAppear {
data()
}
}
}
func data() {
isLoading = true
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
title = "빡코딩 합시다!"
isLoading = false
}
}
}
// MARK: PRESVIVEWS
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
이 코드는 프리뷰가 실행되면 ProgressView
가 실행되고 3초 후에 "빡코딩 합시다!"라는 문구가 나오게 됩니다. 함수에 isLoading
을 true
로 넣어 줬고 title
이 나오면 다시 isLoading
을 false
로 설정해줬습니다.
만약 처음부터 title
이 nil
이라면 어떨까요? @State var title
을 nil
로 설정해보겠습니다.
struct ContentView: View {
@State var title: String? = nil
@State var isLoading: Bool = false
Text(title)
이 오류가 났죠?
Value of optional type 'String?' must be unwrapped to a value of type 'String'
옵셔널 타입이 왔기 때문에 String
인지 Int
타입인지 Xcode는 알지 못합니다. 이럴 때 if let
문을 사용할 수 있습니다.
// MARK: BODY
var body: some View {
NavigationView {
VStack {
Text("안녕하세요 서근 개발 블로그입니다.")
if let text = title {
Text(text)
}
만약 title
에 값이 있으면 title
이 nil
이 아니다. 그렇기 때문에 title
이라는 새 변수를 만들어라.라는 뜻입니다.
즉, 실제 값이 있으면 true
가 되므로 코드를 실행하는 것이죠. 하지만 title
에 값이 없으면 생성할 수 없습니다. 이개체는 절대 실행되지 않으며 개체를 건너뛰게 됩니다.
한 가지 예를 들어볼 텐데 만약 로그인되어있는 사용자가 있고, 그렇지 않은 사용자가 있다고 가정했을 때 화면에 로그인되어있는 유저의 아이디를 나타내 주고 만약 로그인되어있지 않은 사용자가 있다면 대체 문구를 나오게 해 줄 수 있습니다.
func data() {
if let userID = currentID {
isLoading = true
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
title = "로그인 되어있는 아이디 : \(userID)"
isLoading = false
}
} else {
title = "계속하려면 로그인해주세요."
}
}
프리뷰를 실행해보면 당연시 currentID
가 nil
이기 때문에 화면에 "계속하려면 로그인해주세요."라는 문구가 뜹니다. 그럼 만약 nil
이 아닌 값을 부여해준다면 어떨까요?
이렇게 값이 있다면 if let
함수를 실행할 것이고 만약 값이 없다면 else
문을 실행하게 됩니다.
다른 방법으로는 guard let
을 사용할 수 있습니다. if let
과 guard let
은 동일하게 작동하지만 사용방법만 약간 다를 뿐입니다.
Guard let
data2라는 함수를 생성하고 아래와 같이 코드를 작성하겠습니다. guard let
은 항상 뒤에 else
가 와야 하고 return
이 반드시 같이 와야 합니다.
func data2() {
guard let userID = currentID else {
return
}
}
그리고 실행될 함수는 아래와 같습니다.
func data2() {
guard let userID = currentID else {
title = "계속하려면 로그인해주세요."
return
}
}
이제 만약 값이 있다면 실행될 코드를 넣어줘야 합니다.
func data2() {
guard let userID = currentID else {
title = "계속하려면 로그인해주세요."
return
}
isLoading = true
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
title = "로그인 되어있는 아이디 : \(userID)"
isLoading = false
}
}
body
의 onAppear
에 data()
를 data2()
로 수정하고 런해보겠습니다.
동일하게 실행되죠? 이처럼 if let과 guard let은 동일하게 사용됩니다.
읽어주셔서 감사합니다.🤟