์ผ | ์ | ํ | ์ | ๋ชฉ | ๊ธ | ํ |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- Codable
- ์ง๋ฒ๋ณํ
- nodejs
- components
- String.Index
- CRUD
- Filter
- Encodable
- Decodable
- DispatchQueue
- ์๊ณ ๋ฆฌ์ฆ
- UIRefreshController
- Reduce
- SWiFT
- map
- ExpressJS
- ์ฑ๋ง๋ค๊ธฐ
- ํ๋ก๊ทธ๋๋จธ์ค
- Core Data
- Mac
- ios
- ์ฑ๋์์ธ
- MongoDB
- Firestore
- Firestore CRUD
- AVAudioPlayer
- Cloud Firestore
- RxSwift
- Figma
- mongoose
- Today
- Total
Focus On Develop ๐ค๐ค
[Swift] Error Handling ๋ณธ๋ฌธ
์ด๋ฒ์๋ ์ ๋ง ์ค๋๋ง์ ๊ธ์ ์ฐ๋ค์~~ ใ ใ ๊ทธ๋์ ์์๋ Big Event๋ ์์ํ ์ผ์ ๋ธ๋ก๊ทธ์ ํฌ์คํ ํ๋ ๊ถ๊ธํ์ ๋ถ(?)์ ๋๋ฌ์ค์ธ์~!! ๐
์ค๋์ Swift์์ Error๋ฅผ ์ด๋ป๊ฒ Handlingํ๋ฉด ๋๋์ง ์ ๋ฆฌํด๋ณผ๊ฑฐ์์.
"๊ทผ๋ฐ Error Handling์ด ๋ญ๋ฐ~?"
๋ง ๊ทธ๋๋ก ํ๋ก๊ทธ๋จ์ด ์คํ๋๋ค๊ฐ ์๋ฌ๊ฐ ๋ฐ์ํ์๋, ์ด๋ป๊ฒ ์ฒ๋ฆฌํ ๊ฑด์ง~? ๋ผ๊ณ ํด์ํด๋ ๋ ๊ฒ ๊ฐ์์!
๊ตฌ๊ตฌ์ ์ ์ค๋ช ๋ณด๋ค๋.. ์ญ์ ๊ฐ๋จํ ์์ ๋ฅผ ๋ณผ๊ฒ์!
enum CustomError: Error {
case invalidUrl
case urlEmpty
case other
}
๋จผ์ Custom ํ์ ์ผ๋ก Error๋ฅผ ๋ง๋ค์ด ์ฃผ์์ด์.
์ด๋ฐ ์๋ฌํ์ ์ ์ํ๋๋๋ก ์ง์ ํด์ ๋ง๋ค ์ ์๊ณ , ์ํ๋ ๋งํผ case๋ฅผ ๋๋ ์๋ ์์ด์~!
์ฑ ๋ด๋ url ์ด ์ ํจํ์ง ์๋์ง ์๋ฌ๋ฅผ ์ฒดํฌํ๋ ๊ฒ ๊ฐ์ฃ ~~?
๊ทธ๋์ ์ด๊ฑธ๋ก ๋ญ ์ด๋ป๊ฒ ์ฐ๋๋ฐ์~~~
func validateUrl(urlString: String) throws -> Bool {
guard !urlString.isEmpty else {
throw CustomError.urlEmpty
}
guard URL(string: urlString) != nil else {
throw CustomError.invalidUrl
}
return true
}
๋ค ์ด๋ ๊ฒ์! Parameter๋ก ๋ค์ด์จ urlString์ด ์ ํจํ์ง๋ฅผ ํ๋จํ๋ Method์ธ๋ฐ์!
throws ํค์๋๊ฐ ๋ณด์ด์์ฃ ~~? throws๋ ๊ทธ๋๋ก ํด์ํด๋ "๋์ง๋ค"์ฃ ~~?
์ฆ throws๋ผ๊ณ ์จ์ฃผ๋๊ฑด ์ด Method๋ (์๋ฌ๋ฅผ) "๋์ง ์ ์๋ Method๋ค." ์์.
๋์ง๋ ์๋ฌ์ ์ข ๋ฅ๋ ์ฐ๋ฆฌ๊ฐ ์์์ ์ ์ํ Custom Error๋ก ์ง์ ํ๊ณ , ๊ทธ ์๋ฌ๋ฅผ ๋์ง๋๋ก(throw) ํ์ด์!
func checkValid() {
let urlString = "https:www.naver.com"
do {
let result = try validateUrl(urlString: urlString)
print(result)
} catch {
print(error)
}
}
์์์ ๋ง๋ validUrl ๋ฉ์๋๋ฅผ ์ฌ์ฉํด๋ณผ๊ฒ์!
์ด๋ ๊ฒ~~~ ์ฌ๊ธฐ์ do, try, catch ์ด ํค์๋๋ค์ด ๋ณด์ด์๋์~~? ์ฝ๊ฒ ํด์ํด๋ณด๋ฉด ์ด๋์!
do : { } ์์ ์๋ ์ด ์ฝ๋๋ฅผ ์คํํด๋ด.
try : ์ด๊ฑธ(validateUrl) ์คํํ ๋ ์๋ฌ๊ฐ throw๋ ์ ์๋ ๋ถ๋ถ์ด์ผ. ๊ทธ๋๋ ์ผ๋จ "์๋" ํด๋ณด์.
catch : do { } block ์์์ try๋ฅผ ์๋ํ๊ณ , ๊ทธ๋ ๋ง์ฝ ์๋ฌ๊ฐ throw ๋๋ฉด ๋ด๊ฐ ์ก์์ ์ฒ๋ฆฌํ ๊ฒ!
์ด๋ ๊ฒ ์๋ฌ๊ฐ throw๋ ์ ์๋ ๋ถ๋ถ์์๋, do~try~catch๋ฅผ ํตํด์ error๋ฅผ Handling ํด์ฃผ๋ฉด ๋ฉ๋๋ค!
๊ทธ๋ผ ์ค์ ๋ก url์ ์ด์ํ๊ฒ ๋ง๋ค์ด์ ํด๋ณผ๊น์~?
let urlString = "ใ
ใ
ใ
"
๋ค. URL๋ก ๋ง๋๋ ค๊ณ ์๋ํ๋ ๋ ๋ฐ๋ก ์ด๋ ๊ฒ ์ฐ๋ฆฌ๊ฐ ์ ์ํ๋๋ก invalidUrl์ด๋ผ๊ณ ๋์ค๋ค์!!
Custom Error๋ก ํ๋ ๋ ์ ์ํ์ผ๋๊น ์ด๊ฒ๋ ํด๋ณผ๊น์~~?
let urlString = ""
๋ค. ์ญ์ ๋น์ด์๋ค๊ณ ์ ํ์ํด์ฃผ๋ค์!
์ง๊ธ๊น์ง ๊ฐ๋ ์ค๋ช ์ ์ํด ๊ฐ๋จํ ์์ ๋ก ํ๋ฒ ์์๋ณด์๋๋ฐ์!
์๋๋ถํฐ๋ ์ค์ ๋ก ์ฐ๋ฆฌ๊ฐ URL์ ๊ธฐ๋ฐ์ผ๋ก ๋คํธ์ํฌ ํต์ ์ ํ๋ ๊ฒ์ฒ๋ผ ์๋ฅผ ๋ค์ด์ ์ข ๋ ์์๋ณผ๊ฒ์!
enum UserFetchError: Error {
case invalidUrl
case unknown
}
๋จผ์ ์์์ ํ๋ ๊ฒ์ฒ๋ผ Custom Errorํ์ ์ ์ ์ํด์ค๋๋ค.
func fetchUsers() throws {
guard let url = URL(string: "htttps://jsonplaceholder.typicode.com/users") else {
throw UserFetchError.invalidUrl
}
let task = URLSession.shared.dataTask(with: url) { data, _, error in
if let error = error {
throw error
} else if let data = data {
do {
let result = try JSONDecoder().decode([User].self, from: data)
// do something
} catch {
throw error
}
} else {
throw UserFetchError.unknown
}
}.resume()
}
์ด๋ ๊ฒ ์ฐ๋ฆฌ๊ฐ ๊ณต๋ถํ๋ ๊ฒ์ฒ๋ผ throw์, do~try~catch๋ ์ ์์ฑํด์คฌ์ด์! ๊ทธ๋ฐ๋ฐ..
์ด๊ฑด ๋ญฅ๋ฏธ~~!?
์ด Method๋ throws ํค์๋๋ฅผ ์ ์จ์ฃผ๋ฉด์ ์๋ฌ๋ฅผ ๋์ง๊ฒ๋ ๋ง๋ค์ด ์คฌ์ผ๋,, ์ด๋๊ฐ ์๋ชป๋..
์ด๊ฑด.. ๋ค ๊ทธ๋ ์ต๋๋ค.
์ฐ๋ฆฌ๊ฐ ํํ ์ฐ๋ URLSession์ dataTask { } ๋ async๋ก ์ฒ๋ฆฌ๋๋ ๋ถ๋ถ์ด์์.
์๋ฌ๊ฐ ๋ฐ์ํ๋ฉด async๋ก ์ฒ๋ฆฌ๋๋ฉด์ throw๋ฅผ ํตํด "์ผ!! ์ฌ๊ธฐ ์๋ฌ๋ฌ์ด!!" ๋ผ๊ณ ๋ญ๊ฐ ์๋ฌ๋ฅผ ์ด์ฌํ ๋์ ธ์.
๊ทธ๋ฐ๋ฐ.. ์๋ฌด๋ฆฌ ์๋ฆฌ์ณ๋ ๋์ง๊ธฐ๋ง ํ ๋ฟ ๋ฐ์ ๋ ์(catch)์ด ์์ด์ ๋ฌธ์ ๊ฐ ๋ฐ์ํด์.
ํ.. ๊ทธ๋ผ ์ด๋ป๊ฒ ํด์? ์ฐ๋ฆฌ ์๋ฌ ํธ๋ค๋ง ๋ชปํด์?ใ ใ
func fetchUsers(completion: @escaping(Result<[User], Error>) -> Void) throws {
guard let url = URL(string: "htttps://jsonplaceholder.typicode.com/users") else {
throw UserFetchError.invalidUrl
}
let task = URLSession.shared.dataTask(with: url) { data, _, error in
if let error = error {
completion(.failure(error))
} else if let data = data {
do {
let result = try JSONDecoder().decode([User].self, from: data)
completion(.success(result))
} catch {
completion(.failure(error))
}
} else {
completion(.failure(UserFetchError.unknown))
}
}.resume()
}
์ด๋ ๊ฒ ์กฐ๊ธ ๋ฐ๊ฟ๋ณผ๊ฒ์!
์ด๊ฒ๋ ์ฐ๋ฆฌ๊ฐ ํํ ์ฌ์ฉํ๋ completion ํธ๋ค๋ฌ๋ฅผ ํตํด ์๋ฌ๋ฅผ ํธ๋ค๋ง ํด์ฃผ๋๋ก ํ์ด์.
URLSession.shared.dataTask๋ async๋ก ๋์ํ๋๊น, ๊ทธ๋ผ ๋ฏธ๋ฆฌ ์ ์๋ completion ํธ๋ค๋ฌ๋ก ์ฒ๋ฆฌํด์ค~ ํ๋๊ฑฐ์ฃ .
์ด๋ ๊ฒ ํ๋ฉด ๋์ด์ "๋ ์๋ฌ๋ฌ์ด!" ๋ผ๊ณ ์๋ฆฌ์น๋ฉด์ ์๋ฌ๋ฅผ throw ํ ํ์๊ฐ ์์ด์ ธ์ ใ ใ
do {
try fetchUsers { result in
switch result {
case .success(let users):
print(users.count)
case .failure(let error):
print(error)
}
}
} catch {
print(error)
}
์๋ฌ๋ฅผ ๋ฐ์์ ํธ๋ค๋งํ๋ ๋ถ๋ถ๋ ์ด๋ ๊ฒ fetchUsers ๋ฉ์๋๋ฅผ ํธ์ถํ ๋ ๊ฐ์ด completion ํด๋ก์ ธ๋ก ๋ฃ์ด์ฃผ๋ฉด ๋~~
์ฌ์ค ์ฒซ๋ฒ์งธ ์์ ์, ๋๋ฒ์งธ ์์ ๊ฐ ํฌ๊ฒ ๋ค๋ฅผ ๊ฑด ์์ด์.
๋จ์ง.. ๋๋ฒ์งธ ์์ ๋ฅผ ๊ฐ์ ธ์จ๊ฑด async๋ก ๋์ํ๋ ๋ถ๋ถ์์ ์๋ฌด๋ฆฌ ์๋ฌ๋ฅผ ๋์ ธ๋.. ์๋ฌ๋ฌ๋ค๊ณ ์๋ฌด๋ฆฌ ์๋ฆฌ์ณ๋..
์๋ฌด๋ ๋ฐ์์ฃผ์ง ๋ชปํ๋ค๋ ๊ฑธ ๊ณต์ ํ๊ณ ์ถ์ด์ ๊ฐ์ ธ์๋ดค์ด์ ๐๐
๊ฐ๋จํ์ง๋ง ์ค์ํ Error Handling!! ๊ผผ๊ผผํ ์ ์ฒ๋ฆฌํด๋ณด์์~!!
์ค๋๋ ๋๊ตฐ๊ฐ์๊ฒ ๋์์ด ๋์๊ธธ ๋ฐ๋์ ๐
'iOS [Swift] > ๊ธฐ์ด๋ฅผ ํํํ!' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Swift] UITextField ํ๊ธ ๊ธ์์ ์ ํ (1) | 2021.10.26 |
---|---|
[Swift] AssociatedType (0) | 2021.08.23 |
[Swift] Bento #1. iPhone ์ฐ๋ฝ์ฒ ๊ฐ์ ธ์ค๊ธฐ (0) | 2021.04.27 |
[RxSwift] Subject (0) | 2021.03.30 |
[RxSwift] RxSwift ์ฅ๋จ์ (0) | 2021.03.30 |