๊ณต๋ถํ ๋ด์ฉ์ ์ ๋ฆฌํ ๊ธ์ ๋๋ค.
๋ฌธ์
๋คํธ์ํฌ ๊ธฐ๋ฐ์ URL ์ด๋ฏธ์ง๋ฅผ ๋ฐ์์ฌ ๋ Data(contentsOf:)๋ฅผ ์ฌ์ฉํด๋ ๋ ๊น?
1. Data(contentsOf:)
NSData(constentsOf:)๋ ์ฃผ์ด์ง URL๋ก๋ถํฐ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ดํฐ ๊ฐ์ฒด๋ก ์ด๊ธฐํํ๋ ์์ ์ด๋ค. ๋ฐ๋ผ์ ์ด ๋ฉ์๋๋ฅผ ์ฌ์ฉํด URL๋ก๋ถํฐ ์ด๋ฏธ์ง๋ฅผ ๋ฐ์์จ๋ค๋ฉด ์ ์๋ํ๋ค. ํ์ง๋ง ํด๋น ๋ฉ์๋์ ๊ณต์๋ฌธ์์๋ ๋คํธ์ํฌ ๊ธฐ๋ฐ์ URL์ ๊ฒฝ์ฐ ํด๋น ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ง ๋ง๋ผ๊ณ ๋ช ์๋์ด์๋ค.
Important
๋คํธ์ํฌ ๊ธฐ๋ฐ์ URL์ ์์ฒญํ๊ธฐ ์ํด ๋๊ธฐ์ ์ธ ์ด๊ธฐํ ์์ ์ธ init(contentsOf:)๋ฅผ ์ฌ์ฉํ์ง ๋ง๋ผ. ๋๋ฆฐ ๋คํธ์ํฌ ๊ฒฝ์ฐ ๋คํธ์ํฌ ๊ธฐ๋ฐ์ URL์ ๋ํด ์ด ๋ฉ์๋๋ ์์ญ ์ด ๋์ ํ์ฌ ์ค๋ ๋๋ฅผ ์ฐจ๋จ(block)ํ ์ ์์ผ๋ฉฐ, ์ด๋ ์ฌ์ฉ์ ๊ฒฝํ์ ์ ํ์ํจ๋ค. ๊ทธ๋ฆฌ๊ณ iOS์์๋ ์ฑ์ด ์ค๋จ๋ ์๋ ์๋ค.
๋์ , ํ์ผ์ด ์๋ URL์ ๋ํด URLSessionํด๋์ค์ dataTask(with:completionHandler:) ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข๋ค. Fetching Website Data into Memory์์ ์์๋ฅผ ๋ณผ ์ ์๋ค.
์ฆ NSData(constentsOf:)๋ ๋๊ธฐ์ ์ธ ์์ ์ด๋ฏ๋ก ๋ง์ฝ ๋คํธ์ํฌ๊ฐ ๋๋ฆด ๊ฒฝ์ฐ main ์ค๋ ๋๊ฐ ์ฐจ๋จ๋์ด ์ฌ์ฉ์์ ๊ฐ์ฅ ๊ฐ๊น์ด UI๊ฐ ๋ฉ์ถ๋ค๋ ์๋ฏธ์ด๋ค. ๋ฉ์ถ์ง ์๋๋ผ๋ ์ด๋ฏธ์ง๊ฐ ๋ก๋๋๋ ๋์์ ๋ค๋ฅธ UI View๋ค์ด ์์ฑ๋์ง ๋ชปํ๋ฏ๋ก ์ฌ์ฉ์ ๊ฒฝํ(UX)์ด ์ข์ง ์๋ค.
๊ทธ๋ ๋ค๋ฉด DispaychQueue๋ฅผ ์ฌ์ฉํด global์์ ์ด๋ฏธ์ง ๋ก๋๋ฅผ ํ๋ฉด ๋์ง ์์๊น?
2. DispatchQueue.global(). async
private func confidureImagefromURL(_ url: String) {
guard let url = URL(string: url) else {return}
DispatchQueue.global().async { [weak self] in
guard let data = try? Data(contentsOf: url) else {return}
DispatchQueue.main.async {
self?.contentImage.image = UIImage(data: data)
}
}
}
์ ์ฝ๋์ฒ๋ผ DispatchQueue.global์์ URL๋ก๋ถํฐ ๋ฐ์ดํฐ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ UI์ ํด๋น ์ด๋ฏธ์ง๋ฅผ ํ ๋นํ๊ธฐ ์ํด DispatchQueue.main์ ์ฌ์ฉํด๋ณด์. ์ด๋ ๊ฒ ๊ตฌํํ๋ฉด ์ฑ์ ์ด๋ฏธ์ง๊ฐ ์ ๋ก๋๋๋ฉฐ, ์ด๋ฏธ์ง๊ฐ ์์ง ๋ก๋๋์ง ์์๋๋ผ๋ ๋ค๋ฅธ UI View๋ค์ด ์ ์์ฑ๋๋ค. ํ์ง๋ง ์ค๋ ๋๊ฐ ์ฐจ๋จ๋ ์ํ์ ์์ง ์กด์ฌํ๋ค.
DispatchQueue๋ฅผ ์ฌ์ฉํด main ์ค๋ ๋๊ฐ block ๋๋ ๊ฑธ ๋ฐฉ์งํ ์๋ ์์ง๋ง, ์ด์จ๋ ์ ํ๋ ์ซ์์ GCD์ ์ค๋ ๋ ์ค ํ ์ค๋ ๋๊ฐ ์ค๋จ๋์ด๋ฒ๋ฆฐ ๊ฒ์ด๋ค. ๋ง์ฝ ๊ทธ๋ฌํ ์ํฉ์์ ๊ฐ๋ฐ์๊ฐ ์ค๋ ๋ ํ์ ๋ชจ๋ ์ค๋ ๋๋ฅผ ์ฌ์ฉํ๋ค๋ฉด GCD๋ ์๋ฌด๊ฒ๋ ํ ์ ์๋ ์ํ๊ฐ ๋์ด๋ฒ๋ฆฐ๋ค.
๊ทธ๋ผ ๋คํธ์ํฌ ๊ธฐ๋ฐ์ URL์์ ์ด๋ฏธ์ง๋ฅผ ๋ฐ์์ค๋ ค๋ฉด ์ด๋ป๊ฒ ํด์ผ ํ ๊น?
3. URLSession
๊ณต์๋ฌธ์์์๋ URLSession์ dataTask(with:completionHandler:) ์ฌ์ฉ์ ์ถ์ฒํ๋ค.
URLSession์ ํตํด ์ด๋ฏธ์ง๋ฅผ ๋ฐ์์ค๋ฉด Data(contentsOf:)์ ํตํด ๋ฐ์์ค๋ ๊ฒ๊ณผ๋ ๋ค๋ฅด๊ฒ, ์ค๋ฅ ๋ฐ์ ์ ์๋ฏธ ์๋ ์ง๋จ์ ํ ์ ์์ผ๋ฉฐ ์ค๋ ๋๊ฐ block ๋๋ ๊ฒ์ ๋ฐฉ์งํ ์ ์๋ค.
Apple์ด ์ ๊ณตํ๋ Article ์ค Fetching Website Data into Memory์์๋ ์๋์ ๊ฐ์ ์ฝ๋๋ฅผ ์์๋ก ๋ณด์ฌ์ค๋ค.
func startLoad() {
let url = URL(string: "https://www.example.com/")!
let task = URLSession.shared.dataTask(with: url) { data, response, error in
if let error = error {
self.handleClientError(error)
return
}
guard let httpResponse = response as? HTTPURLResponse,
(200...299).contains(httpResponse.statusCode) else {
self.handleServerError(response)
return
}
if let mimeType = httpResponse.mimeType, mimeType == "text/html",
let data = data,
let string = String(data: data, encoding: .utf8) {
DispatchQueue.main.async {
self.webView.loadHTMLString(string, baseURL: url)
}
}
}
task.resume()
}
4. Alamofire
๋คํธ์ํฌ ์ฐ๊ฒฐ ์ ๋ง์ด ์ฌ์ฉํ๋ Alamofire๋ Apple์์ ์ ๊ณตํ๋ ๋คํธ์ํฌ API์ธ URLSession์ ๊ธฐ๋ฐํ์ฌ ๋ง๋ค์ด์ง ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ด๋ค. ๋ฐ๋ผ์ Alamofire ๋ํ ๋คํธ์ํฌ ๊ธฐ๋ฐ URL๋ก๋ถํฐ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ค๋ ๋ฐ ์ฌ์ฉํ ์ ์๋ค.
Never load data from a remote URL with synchronous API Data(contentsOf)
init(contentsOf:)
Fetching Website Data into Memory
GCD