์์ง์ด๋ gif๋ฅผ ๊ฒ์ํ ์ ์๊ณ , ์์ธ ์ ๋ณด๋ฅผ ๋ณผ ์ ์์ผ๋ฉฐ, ๋ง์์ ๋๋ gif๋ฅผ ์ฆ๊ฒจ์ฐพ๊ธฐํ ์ ์๋ iOS ์ฑ ๊ฐ๋ฐ ํ๋ก์ ํธ์ ๋๋ค.
- iOS Depolyment Target:
Xcode 11.6
- Supporting Device Target:
iOS 13
- CocoPods Version:
1.10.0.beta.2
- Language:
Swift
- Alamofire
HTTP ํต์ ์ค Alamofire๊ฐ ์ ๊ณตํ๋ Request&Response ์ฒด์ด๋ ํจ์์ URL/JSON ํํ์ ํ๋ผ๋ฏธํฐ ์ธ์ฝ๋ฉ ๊ธฐ๋ฅ์ ์ฌ์ฉํ๊ธฐ ์ํด ์ฑํํ์์ต๋๋ค. - Kingfisher
๊ฐ์ ์ด๋ฏธ์ง URL์ ๋งค๋ฒ ์๋กญ๊ฒ ํธ์ถํ๋ ๋ฐ์์ ์ค๋ ์ง์ฐ์ด ๊ฒ์ ํ์ด์ง์ ์ฆ๊ฒจ์ฐพ๊ธฐ ๋ฆฌ์คํธ์ ์ด๋ฏธ์ง ์ ๋ก๋ ์๋๋ฅผ ๋ฆ์ถ๋ค๊ณ ํ๋จํ์ต๋๋ค.
๋ฐ๋ผ์ ์ด๋ฏธ์ง ๋ก๋ ์๋ ๊ฐ์ ์ ์ํด Kingfisher์ ์ด๋ฏธ์ง ์บ์ ๊ธฐ๋ฅ์ ์ฌ์ฉํ์ต๋๋ค.
๊ฒ์ ํ๋ฉด | ์ฆ๊ฒจ์ฐพ๊ธฐ ํ๋ฉด | ๋ชจ๋ฌ ํ๋ฉด |
---|---|---|
๋ฒํธ | ์ค์๋ | ๊ธฐ๋ฅ | ๊ตฌํ ์ฌ๋ถ |
---|---|---|---|
1 | ๊ธฐ๋ณธ | Giphy API๋ฅผ ์ด์ฉํ ์ ์ ์ธ GIF ์ด๋ฏธ์ง ๊ฒ์ ๊ธฐ๋ฅ | O |
1-1 | ๊ธฐ๋ณธ | ์๋จ [๊ฒ์ํ๊ธฐ] ํ ์คํธํ๋๊ฐ ํฌ์ปค์ค ๋๋ฉด ํค๋ณด๋๊ฐ ๋ณด์ฌ์ง๋๋ก ๊ตฌํ | O |
1-2 | ๊ธฐ๋ณธ | ์คํฌ๋กค๋ทฐ๋ฅผ ์คํฌ๋กคํ์ ๋, ํค๋ณด๋์ Enter๋ฅผ ์ณค์ ๋, ํค๋ณด๋๊ฐ ๋ด๋ ค๊ฐ๋๋ก ๊ตฌํ | O |
1-3 | ๊ธฐ๋ณธ | ์๋จ์ด๋ฅผ ์ ๋ ฅํ์ ๋๋ง๋ค ๊ฒ์ API๋ฅผ ํธ์ถํ๋๋ก ๊ตฌํ | O |
2 | ๊ธฐ๋ณธ | ๊ฒ์ ํ๋์ ๋น ํ ์คํธ๊ฐ ์ ๋ ฅ๋์ด ์๋ค๋ฉด ๋น ํ๋ฉด์ ๋ณด์ฌ์ฃผ๋๋ก ๊ตฌํ | O |
3 | ๊ธฐ๋ณธ | ํ์ด์ง์ ์ด์ฉํด API์ ์ต๋๋ก ์กฐํ ๊ฐ๋ฅํ ์ด๋ฏธ์ง ๊ฐฏ์ (limit=24)๋งํผ ๋ถ๋ฌ์ค๋๋ก ๊ตฌํ | O |
4 | ๊ธฐ๋ณธ | ๋ฆฌ์คํธ ์ตํ๋จ์ <๋๋ณด๊ธฐ> ๋ฒํผ์ ๋์ด, ์ดํ์ ๋ ๋ง์ ์ด๋ฏธ์ง๋ฅผ ๋ถ๋ฌ์ฌ ์ ์๋๋ก ๊ตฌํ | O |
5 | ๊ธฐ๋ณธ | ๊ฐ ์ด๋ฏธ์ง๋ฅผ ๋๋ฅผ ๋ Modal์ด ๋จ๋๋ก ๊ตฌํ | O |
6 | ํ์ | ์ด๋ ๋๋ฐ์ด์ค์์๋ ํ row์ ์ต๋ 3๊ฐ ๋จ์์ ์ด๋ฏธ์ง๊ฐ ๊ทธ๋ฆฌ๋ ํ์์ผ๋ก ๋ ธ์ถ๋๋๋ก ๊ตฌํ | O |
6-1 | ํ์ | ๊ทธ๋ฆฌ๋ ๋ด์ Cell์ ๊ฐ๋ก ์ธ๋ก์ ๊ธธ์ด๋ 1:1๋ก ๋์ผํ๊ฒ ๊ตฌํ | O |
7 | ํ์ | ์ด๋ฏธ์ง ๋น์จ์ ์ ์ง๋ ์ฑ ์ฌ์ด์ฆ๊ฐ Cell์ ์ฌ์ด์ฆ๋ฅผ ๋์ง ์๋๋ก ๋ง์ถ๊ธฐ | O |
1 | ์ถ๊ฐ | ์ ์ ์ธ GIF ์ด๋ฏธ์ง๋ฅผ ๋์ ์ผ๋ก ์์ง์ด๊ฒ ๊ตฌํ | X |
2 | ์ถ๊ฐ | ๋ฌดํ์คํฌ๋กค์ ์ ์ฉํ์ฌ ๋์ ์์ด ์ด๋ฏธ์ง๊ฐ ๋ก๋๋ ์ ์๋๋ก ๊ตฌํ | O |
3 | ์ถ๊ฐ | ๊ฒ์์ด๊ฐ ์ ๋ ฅ๋์ง ์์๋ค๋ฉด trend API๋ฅผ ์ด์ฉํ์ฌ ์ต์ ํธ๋ ๋ GIF๋ฅผ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ฆฌ์คํ ํ๋๋ก ๊ตฌํ | O |
4 | ์ถ๊ฐ | ์ด๋ฏธ์ง๊ฐ ๋ก๋ฉ๋ ๋ placeholder ์ด๋ฏธ์ง ๋ฃ๊ธฐ | O |
5 | ์ถ๊ฐ | ๋คํธ์ํฌ ์๋ฌ ๋ฑ์ ์ํด API ํต์ ์ด ๋ถ๊ฐ๋ฅํ ๊ฒฝ์ฐ Alert ๋ฑ์ผ๋ก ์ฌ์ฉ์์๊ฒ ์๋ดํ๊ธฐ | O |
์ฆ๊ฒจ์ฐพ๊ธฐ ํด์ | ์ฆ๊ฒจ์ฐพ๊ธฐ ์ถ๊ฐ | ์ฆ๊ฒจ์ฐพ๊ธฐ ๊ฐฏ์ ์ ํ | ์ฆ๊ฒจ์ฐพ๊ธฐ ํ๋ฉด ๊ฒฐ๊ณผ | ์ฆ๊ฒจ์ฐพ๊ธฐ ๊ฐ์ 0๊ฐ์ผ ๋ |
---|---|---|---|---|
๋ฒํธ | ์ค์๋ | ๊ธฐ๋ฅ | ๊ตฌํ ์ฌ๋ถ |
---|---|---|---|
1 | ๊ธฐ๋ณธ | ๋ด๊ฐ ์ฆ๊ฒจ์ฐพ๊ธฐํ ์ด๋ฏธ์ง ๋ณผ ์ ์๊ฒ ๊ตฌํ | O |
2 | ๊ธฐ๋ณธ | ๊ฐ ์ด๋ฏธ์ง๋ฅผ ๋๋ฅผ ๊ฒฝ์ฐ Modal ๋์ฐ๊ธฐ | O |
3 | ๊ธฐ๋ณธ | ์ฑ์ ์ข ๋ฃํ๊ธฐ ์ ๊น์ง ๋ด๊ฐ ์ฆ๊ฒจ์ฐพ๊ธฐํ ์ด๋ฏธ์ง๊ฐ ํ๋ฐ๋์ง ์๊ฒ ๊ตฌํ | O |
4 | ๊ธฐ๋ณธ | ์ต๋ 20๊ฐ์ ์ด๋ฏธ์ง๋ฅผ ์ฆ๊ฒจ์ฐพ๊ธฐ ๋ฑ๋กํ ์ ์๋๋ก ๊ตฌํ | O |
4-1 | ๊ธฐ๋ณธ | ์ต๋ 20๊ฐ ์ด์ ๋ฑ๋ก ์ ๊ฒฝ๊ณ ๋ฌธ๊ตฌ์ ํจ๊ป ์ฆ๊ฒจ์ฐพ๊ธฐ์ ๋ฑ๋ก๋์ง ์๋๋ก ๊ตฌํ | O |
5 | ๊ธฐ๋ณธ | ์ด๋ ๋๋ฐ์ด์ค์์๋ ํ row์ ์ต๋ 3๊ฐ ๋จ์์ ์ด๋ฏธ์ง๊ฐ ๊ทธ๋ฆฌ๋ ํ์์ผ๋ก ๋ ธ์ถ๋๋๋ก ๊ตฌํ | O |
5-1 | ๊ธฐ๋ณธ | ๊ทธ๋ฆฌ๋ ๋ด์ Cell์ ๊ฐ๋ก ์ธ๋ก์ ๊ธธ์ด๊ฐ 1:1๋ก ๋์ผํ๋๋ก ๊ตฌํ | O |
6 | ๊ธฐ๋ณธ | ์ด๋ฏธ์ง ๋น์จ์ ์ ์ง๋ ์ฑ ์ฌ์ด์ฆ๊ฐ Cell์ ์ฌ์ด์ฆ๋ฅผ ๋์ง ์๋๋ก ๋ง์ถ๊ธฐ | O |
7 | ์ถ๊ฐ | ์ ์ ์ธ GIF ์ด๋ฏธ์ง๋ฅผ ๋์ ์ผ๋ก ์์ง์ด๊ฒ ๊ตฌํ | X |
8 | ์ถ๊ฐ | ์ฆ๊ฒจ์ฐพ๊ธฐ ํ ๋ด์ฉ์ด ์์ ๋ ๋นํ๋ฉด์ ํจ๊ณผ์ ์ผ๋ก ์ ์ ์๊ฒ ์ปค๋ฎค๋์ผ์ด์ | O |
9 | ์ถ๊ฐ | ์ฑ์ ์ข ๋ฃํ๋๋ผ๋ Local Storage๋ฅผ ์ด์ฉํ์ฌ ํ๋ฐ๋์ง ์๋๋ก ๊ตฌํ | O |
10 | ์ถ๊ฐ | ๊ฐ์ฅ ์ต๊ทผ์ ์ฆ๊ฒจ์ฐพ๊ธฐํ ์ด๋ฏธ์ง๊ฐ ์ต์๋จ์ ๋ณด์ผ ์ ์๋๋ก ๊ตฌํ | O |
11 | ์ถ๊ฐ | ์ด๋ฏธ์ง๊ฐ ๋ก๋ฉ๋ ๋ placeholder ์ด๋ฏธ์ง ๋ฃ๊ธฐ | O |
12 | ์ถ๊ฐ | ๋คํธ์ํฌ ์๋ฌ ๋ฑ์ ์ํด API ํต์ ์ด ๋ถ๊ฐ๋ฅํ ๊ฒฝ์ฐ Alert ๋ฑ์ผ๋ก ์ฌ์ฉ์์๊ฒ ์๋ดํ๊ธฐ | O |
ํญ1, ํญ2์์ ์ด๋ฏธ์ง ์ ํ ์ ๋ณด์ฌ์ง๋ Modal์ฐฝ
์ ์ฒด ๊ณต์ | ํ์ผ ๊ณต์ |
---|---|
๋คํธ์ํฌ ์ค๋ฅ |
---|
๋ฒํธ | ์ค์๋ | ๊ธฐ๋ฅ | ๊ตฌํ ์ฌ๋ถ |
---|---|---|---|
1 | ๊ธฐ๋ณธ | Modal๋ก ๋ณด์ฌ์ง๊ฒ ๊ตฌํ | O |
2 | ๊ธฐ๋ณธ | ์ ์ ์ธ ์ด๋ฏธ์ง์ ๊ด๋ จ ์ ๋ณด(์ด๋ฆ, rate ๋ฑ) ํ ์คํธ๋ฅผ ๋ณด์ฌ์ฃผ๋๋ก ๊ตฌํ | O |
3 | ๊ธฐ๋ณธ | ํ์ธ์๊ฒ ์ด๋ฏธ์ง ์ฃผ์์ ์ด๋ฆ์ ๊ณต์ ํ ์ ์๋ ๋ฒํผ์ ํฌํจ | O |
4 | ๊ธฐ๋ณธ | ๋ณ ํ์ ๋ฒํผ์ ํตํด ๋ง์์ ๋๋ ์ด๋ฏธ์ง๋ฅผ ์ฆ๊ฒจ์ฐพ๊ธฐ, ํด์ ํ ์ ์๊ฒ ๊ตฌํ | O |
5 | ํ์ | ์ด๋ฏธ์ง์ ํฌ๊ธฐ๋ 160X160 ์ด๋ด์์ ๋น์จ์ด ์ ์ง๋ ์ฑ๊ณ ๋ณด์ฌ์ง๋๋ก ๊ตฌํ | O |
6 | ํ์ | ์ด๋ฏธ ์ฆ๊ฒจ์ฐพ๊ธฐ์ ๋ฑ๋กํ ์ด๋ฏธ์ง๊ฐ 20๊ฐ ์ด์์ด๋ผ๋ฉด ์ ๊ท๋ก ์ฆ๊ฒจ์ฐพ๊ธฐํ ์ ์๋๋ก ๊ตฌํ | O |
7 | ์ถ๊ฐ | ์ ์ ์ธ GIF ์ด๋ฏธ์ง๋ฅผ ๋์ ์ผ๋ก ์์ง์ด๊ฒ ๊ตฌํ | X |
8 | ์ถ๊ฐ | ์ด๋ฏธ์ง๊ฐ ๋ก๋ฉ๋ ๋ placeholder ์ด๋ฏธ์ง ๋ฃ๊ธฐ | O |
9 | ์ถ๊ฐ | ๋คํธ์ํฌ ์๋ฌ ๋ฑ์ ์ํด API ํต์ ์ด ๋ถ๊ฐ๋ฅํ ๊ฒฝ์ฐ Alert ๋ฑ์ผ๋ก ์ฌ์ฉ์์๊ฒ ์๋ดํ๊ธฐ | O |
Resources
ํด๋: ์ด๋ฏธ์ง ๋ฑ๊ณผ ๊ฐ์ ํ๋ก์ ํธ ๋ฆฌ์์ค๋ฅผ ๊ด๋ฆฌSources
ํด๋: ํ๋ก์ ํธ ์์ค(Storyboard, ViewController, View, Model, Service)๋ฅผ ๊ด๋ฆฌUtils
ํด๋: ํ๋ก์ ํธ ์ ์ฒด์ ์ผ๋ก ์ฌ์ฉ๋๋ ๊ธฐํ ํ์ผ์ ๊ด๋ฆฌNetwork
ํด๋: ์ ์ฒด ๋คํธ์ํน์ ์ง์ํ๋ ํ๋กํ ์ฝ ํ์ผ ๊ด๋ฆฌExtensions
ํด๋:UIView
,UIViewController
๋ฑ์ ๋ค์ํ Extension ๊ด๋ฆฌ
SupportingFiles
ํด๋: ๊ทธ ๋ฐ์ ํ๋ก์ ํธ๋ฅผ ์ง์ํ๋ ํ์ผ(AppDelegate, SceneDelegate, Info.plist)์ ๊ด๋ฆฌ
ํด๋ผ์ด์ธํธ์์ Giphy API ๋ด์ฉ์ ์ฝ์ด๋ค์ด๊ธฐ ์ํด์๋ ๋ง์ ํจ์๋ฅผ ๋ฐํ์ผ๋ก ํ ์์ฒญ์ด ํ์ํ๊ณ , ์ด ๊ณผ์ ์์ ์ ์ฌํ ์ฝ๋๋ฅผ ๋ฐ๋ณต์ ์ผ๋ก ์์ฑํด์ผ ํ์ต๋๋ค. ์ด๋ฌํ ๋ฐ๋ณต์ ํจ์๋ฅผ ์ ๋ค๋ฆญ์ ๋ฐํ์ผ๋ก ํด๊ฒฐํ๊ธฐ ์ํด ๋คํธ์ํฌ ๋ ์ด์ด ๋ฐฉ์์ ๋์ ํ์ต๋๋ค. ์ ๋ฐ์ ์ธ ๊ตฌ์กฐ๋ Controller, Middle Layer, Service Manager, Model ๋ก ๊ตฌ์ฑ๋ฉ๋๋ค.
1. Controller
Controller ๋ ์๋น์ค๋ฅผ ํธ์ถํ๋ ViewController
๋ฅผ ๋ปํฉ๋๋ค. ViewController
์์ ์๋น์ค๋ฅผ ํธ์ถํ๊ฒ ๋๋ฉด Middle Layer๋ฅผ ํธ์ถํ๊ฒ ๋ฉ๋๋ค.
2. Middle Layer
Middle Layer๋ Controller์ Service Manager ์ฌ์ด์ ๋ธ๋ฆฟ์ง ์ญํ ์ ํฉ๋๋ค. Middle Layer์์๋ ์๋ต ์ฝ๋๋ฅผ ํตํ ๋คํธ์ํฌ ์ํ๋ฅผ ํ์ธํฉ๋๋ค.
3. Service Manager
๋คํธ์ํฌ ์ํ๊ฐ ์ฑ๊ณต์ ์ด๋ผ๋ฉด, ๋คํธ์ํฌ ๋ ์ด์ด์ ํต์ฌ์ธ Service Manager์์ Codable์ ํตํด ์ ์ํ Model์ ํตํด ํ์ฑํ ํ JSON ๋ฐ์ดํฐ์ ์ํ๊ฐ์ ๋ฐํํฉ๋๋ค.
์ดํ Controller์ธ ViewController
์์ ์ํ ์ฝ๋์ ์ ๋ฌ๋ฐ์ ๋ฐ์ดํฐ์ ๋ง๊ฒ View
๋ฅผ ๋ฐ๊ฟ์ฃผ๋ ํํ๋ก ๋คํธ์ํน์ ๊ตฌํํ์ต๋๋ค.
1. ๋ฌธ์ ์ ์: Gifhy API์์ ๋ถ๋ฌ์จ ์ด๋ฏธ์ง ๋ฐ์ดํฐ๋ค์ '๊ฒ์ํ๋ฉด' collectionView
์ cell
์ ํ์ํ๋ ์คํฌ๋กค ์ฑ๋ฅ์ ๋งค์ฐ ํฌ๊ฒ ์ ํ๋์ต๋๋ค.
2. ์์ธ: ๋ฌด๊ฑฐ์ด ์ฉ๋์ Gif ์ด๋ฏธ์ง๋ฅผ ํด๋น cell์ด ํ๋ฉด์ ํ์๋ ๋๋ง๋ค ์ฌ์์ฒญํ์ฌ ํ๋ฉด์ ํ์ํด์ผ ํ๊ธฐ ๋๋ฌธ์
๋๋ค.
3. ํด๊ฒฐ์ฑ
:
๋ฐ๋ผ์ ์ฒซ ๋ฒ์งธ๋ก, cell ๋ด์ imageView์ ๋ฐ์ดํฐ๋ฅผ ์
๋ก๋ํ๋ ๊ณผ์ ์ ๋น๋๊ธฐ์ ์ผ๋ก ์ํํ์ต๋๋ค.
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
...
DispatchQueue.global().async {
DispatchQueue.main.async {
cell.imageView.kf.setImage(with: url)
}
}
...
}
๋ ๋ฒ์งธ๋ก, UICollectionViewDataSourcePrefetching
ํ๋กํ ์ฝ์ ํ์ฉํ์ฌ collectionView cell์ด ํ์๋ ๊ฒ์ ๋ฏธ๋ฆฌ ์์ํ๊ณ ๋ฐ์ดํฐ๋ฅผ ๋ฏธ๋ฆฌ ๋ถ๋ฌ์ฌ ์ ์๋๋ก ํ์ต๋๋ค.
extension SearchVC: UICollectionViewDataSourcePrefetching {
func collectionView(_ collectionView: UICollectionView, prefetchItemsAt indexPaths: [IndexPath]) {
for indexPath in indexPaths {
if let cellToUpdate = collectionView.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath) as? GifCVCell {
if indexPath.row < gifDataList.count {
let url = gifDataList[indexPath.row].url
DispatchQueue.global().async {
DispatchQueue.main.async {
cellToUpdate.imageView.kf.setImage(with: url)
}
}
if let gifId = Int(gifDataList[indexPath.row].id) {
cellToUpdate.tag = gifId
}
}
}
}
}
}
1. ๋ฌธ์ ์ ์: collectionView์ ๋์ ๋ค๋ค๋ฅผ ๋๊น์ง ์คํฌ๋กค ํ์ ๋, ์๋ก๊ณ ์นจ์ด ๋์์ ์ผ๋ก ์ฌ๋ฌ๋ฒ ํธ์ถ๋๋ ํ์์ด ๋ฐ์ํ์ต๋๋ค.
2. ์์ธ
ํด๋น ์์ ์ ์ถ๊ฐ์ ์ธ gif ๋ฐ์ดํฐ๋ฅผ ์์ฒญํ๋ getGifList() ํจ์๊ฐ ๋น๋๊ธฐ๋ก ์คํ๋๋ ํจ์์๊ธฐ ๋๋ฌธ์ด์์ต๋๋ค.
3. ํด๊ฒฐ์ฑ
flag๋ฅผ ์ถ๊ฐํ์ฌ getGifList() ํจ์ ์คํ์ด ๋๋ ํ์ ์๋ก์ด ์๋ก๊ณ ์นจ์ ์์ฒญํ ์ ์๋๋ก ๊ตฌํํ์ต๋๋ค.
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if self.collectionView.window == nil {
return
}
let offsetTolerance = CGFloat(30)
let offsetY = collectionView.contentOffset.y
let contentHeight = collectionView.contentSize.height
if offsetY > contentHeight - (collectionView.bounds.size.height + offsetTolerance), !scrollViewReachedBottom {
self.scrollViewReachedBottom = true
self.offset += 25
getGifList(keyword: gsno(self.searchTextField.text), offset: offset)
}
}
}
func getGifList(keyword: String, offset: Int) {
GetGifSearchService.sharedInstance.getGifList(params: params) { (result) in
switch result {
case .networkSuccess(let data): //200
let gifData = data as? GifSearchModel
if let resResult = gifData {
if let resultData = resResult.data {
...
self.collectionView.reloadData()
self.scrollViewReachedBottom = false
}
}
break
...
}
1. ๋ฌธ์ ์ ์
UserDefault์ value์ Custom ๊ตฌ์กฐ์ฒด๊ฐ์ผ๋ก ์ค์ ํ๋ [User Defaults] Attempt to set a non-property-list
์๋ฌ๊ฐ ๋ฐ์ํ์ต๋๋ค.
2. ์์ธ
UserDefault๊ฐ ์ง์ํ๋ value ํ์
์์ ๋ฒ์ด๋ฌ๊ธฐ ๋๋ฌธ์ด์์ต๋๋ค.
3. ํด๊ฒฐ์ฑ
๋ฐ๋ผ์ UserDefault๊ฐ ์ง์ํ๋ ํ์
๊ผด๋ก ๋ณ๊ฒฝํ๊ณ , ํด๋น key๊ฐ์ ์ ๊ทผ์ ์ฉ์ดํ๊ฒ ํ๊ธฐ์ํด FavoriteGifCache
๊ตฌ์กฐ์ฒด๋ฅผ ๊ตฌํํ์ต๋๋ค.
- FavoriteGifCache ๊ตฌ์กฐ์ฒด ๋ด์ favorites ํค ๊ฐ์ ํด๋นํ๋ ์บ์๋ฅผ ๋ถ๋ฌ์ค๊ธฐ ์ํ get ํจ์ ๊ตฌํ
- FavoriteGifCache ๊ตฌ์กฐ์ฒด ๋ด์ favorites ํค ๊ฐ์ ํด๋นํ๋ ์บ์์ ๋ฐ์ดํฐ ์ถ๊ฐ๋ฅผ ์ํ save ํจ์ ๊ตฌํ
- FavoriteGifCache ๊ตฌ์กฐ์ฒด ๋ด์ favorites ํค ๊ฐ์ ํด๋นํ๋ ์บ์์ ๋ฐ์ดํฐ ์ญ์ ๋ฅผ ์ํ remove ํจ์ ๊ตฌํ
struct FavoriteGifCache {
static let key = "fatorites"
static func save(value: Dictionary<String, FavoriteGifInfo>) {
UserDefaults.standard.set(try? PropertyListEncoder().encode(value), forKey: key)
}
static func get() -> Dictionary<String, FavoriteGifInfo>! {
var userData: Dictionary<String, FavoriteGifInfo>!
if let data = UserDefaults.standard.value(forKey: key) as? Data {
userData = try? PropertyListDecoder().decode(Dictionary<String, FavoriteGifInfo>.self, from: data)
return userData ?? Dictionary<String, FavoriteGifInfo>()
} else {
return userData
}
}
static func remove() {
UserDefaults.standard.removeObject(forKey: key)
}
}
1. ๋ฌธ์ ์ ์
- ์ฆ๊ฒจ์ฐพ๊ธฐ ํ๋ฉด์์ Modal์ฐฝ์ ๋์ฐ๊ณ ์ฆ๊ฒจ์ฐพ๊ธฐ๋ฅผ ํด์ ํ ํ ๋ค์ ๊ธฐ์กด์ ๋ทฐ๋ก ๋์์ค๋ฉด ์ฆ๊ฒจ์ฐพ๊ธฐ ํ๋ฉด์ด ์ฆ๊ฐ์ ์ผ๋ก ๊ฐฑ์ ๋์ง ์์์ต๋๋ค.
- Modal์ฐฝ์ด ๋ด๋ ค๊ฐ๋ ์์ ์ ๊ธฐ์กด์ ์ฆ๊ฒจ์ฐพ๊ธฐ ํ๋ฉด์์
viewWillAppear/viewDidAppear
์ด ํธ์ถ๋๊ณ , ํด๋น ์์ ์ ํ๋ฉด ๊ฐฑ์ ์ ๊ธฐ๋ํ์ผ๋ ์์์๋๋ฆฌ์ค์ฒ๋ผ ๊ตฌํ๋์ง ์์์ต๋๋ค.
2. ์์ธ
UIModalPresentationStyle๋ก ๋ทฐ๊ฐ ํธ์ถ๋ ๋๋ ๊ธฐ์กด์ present์ ์๋ช
์ฃผ๊ธฐ์ ๋ค๋ฅธ ๊ฒ์ด ์์ธ์ด์์ต๋๋ค. modally presentํ ๋ ๊ธฐ์กด ๋ทฐ๊ฐ viewWill/Diddisappear
ํ์ง ์๊ธฐ ๋๋ฌธ์ Modal์ฐฝ์ด ์ฌ๋ผ์ง๋๋ผ๋ viewWillAppear
ํจ์๊ฐ ํธ์ถ๋์ง ์์ต๋๋ค. ๋ฐ๋ผ์ collectionView.reloadData()
๋ํ ํธ์ถ๋์ง ์์์ต๋๋ค. ์ด๋ก ์ธํด ๋ชจ๋ฌ์ฐฝ์์ ์ฆ๊ฒจ์ฐพ๊ธฐ ๋ฆฌ์คํธ๊ฐ ๊ฐฑ์ ๋์ง ์๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค.
3. ํด๊ฒฐ์ฑ
modal์ฐฝ์์ ์ฆ๊ฒจ์ฐพ๊ธฐ ํด์ ์, ์ด์ ๋ทฐ์ collectionView.reloadData()
๋ฅผ ํธ์ถํ๋ ํจ์๋ฅผ ์ฌ์ฉํ ์ ์๋๋ก NotificationCenter
๋ฅผ
NotificationCenter
ํ์ฉํ์ต๋๋ค.
- ๋ชจ๋ฌ ํ๋ฉด
NotificationCenter.default.post(name: Notification.Name(rawValue: "reloadCollectionView"), object: nil)
- ์ฆ๊ฒจ์ฐพ๊ธฐ ํ๋ฉด
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(reloadCollectionView(_ :)), name: Notification.Name(rawValue: "reloadCollectionView"), object: nil)
}
@objc func reloadCollectionView(_ notification: Notification) {
reloadView()
}
func reloadView() {
initializeFavoriteGifInfoList()
collectionView.reloadData()
}
. ..