๋คํธ์ํฌ ํ๊ธฐ๋ง ๊ณผ์ : TCP ํต์ , UDPํต์ ๋ฑ Socket์ ์ฌ์ฉํ ์ฑํ ๊ธฐ๋ฅ ๊ด๋ จ ์๋น์ค ๋ง๋ค๊ธฐ :]
- ํ์๊ฐ์ , ๋ก๊ทธ์ธ ๊ธฐ๋ฅ
- ํ๋กํ ์ ์ฅ, ์ ๋ฐ์ดํธ ๊ธฐ๋ฅ (์ญ์ ๊ธฐ๋ฅ ๋ฏธ์)
- ๊ทธ๋ฃน ๊ฒ์ ๊ธฐ๋ฅ
- ๋ฉ์ธ ํ๋ฉด
- ๊ทธ๋ฃน ์ฑํ ๊ธฐ๋ฅ (with TCP socket :)
- ๊ธฐํ ์ ๋๋ฉ์ด์
- Without third party !!
iOS: ์์นํ | BE: ์๊ฒฝ์ |
---|---|
@SHcommit | @MoonDooo |
ํ์๊ฐ์
|
๋ก๊ทธ์ธ+ํ๋กํ ์ด๋ฏธ์ง ๋ณ๊ฒฝ |
๊ทธ๋ฃน ์ฑํ
์ถ๊ฐ ๊ธฐ๋ณธ ๊ธฐ๋ฅ |
๊ทธ๋ฃน ์ถ๊ฐ ๊ธฐ๋ฅ |
Carousel effect |
์๋ฒ ์ฐ๋ ์ ์ฑํ
|
TCP Socket ์ฐ๋ ํ ์ฑํ
๋ฐฉ |
TCP Socket์ผ๋ก ์ฑํ
์ค send, recv ... :) |
-
clean architecture + MVVM์ ์ฌ์ฉํ๋ ค ํ์ผ๋ ๊ตณ์ด use case์ ์ ์์ด๋ ๋ ๊ฒ ๊ฐ์ UseCase๋ฅผ ์ ์ธํ Clean architecture๋ฅผ ์ ์ฉํ์ต๋๋ค.
-
ViewController์ ViewModel๊ฐ Input/Output binding์ ์ฌ์ฉํด ๋น์ฆ๋์ค๋ก์ง๊ณผ UI๊ด๋ จ ์ฒ๋ฆฌ๋ฅผ ๋ถ๋ฆฌํ์ต๋๋ค.
-
์๋ฒ ์ฐ๋ ์ ๊น์ง Mock data ์ฌ์ฉ์ด ์ฉ์ดํ์ต๋๋ค.
-
๋ก๊ทธ์ธ ํ ๋ฉ์ธ ํ๋ฉด์ผ๋ก ๊ฐ ๋ Coordinator ํจํด์ ์ฌ์ฉํ์ง ์์๋ค๋ฉด ๋ธ๋ฆฌ๊ฒ์ดํธ๋ก SceneDelegate.swift์์ ๋ฃจํธ ์๋์ฐ๋ฅผ ๊ต์ฒดํ์ ๊ฒ์ ๋๋ค. ํ์ง๋ง Coordinator ํจํด์ ์ฌ์ฉํ๋ฉด์ parent, child์ ๊ด๋ฆฌ๋ง ์ํด์ค๋ค๋ฉด, ๊ทธ๋ฆฌ๊ณ ํน์ ํ๋ฉด์์ ๋ค๋ฅธ ํ๋ฉด์ผ๋ก ๋์ด๊ฐ ๊ฒฝ์ฐ๋ฅผ Coordiantor ์์ ์ ์ํด ์ค๋ค๋ฉด ๋์ฑ ํธ๋ฆฌํ๊ฒ ํ๋ฉด ์ ํ์ ๊ด๋ฆฌํ ์ ์๊ฒ ๋ค๊ณ ์๊ฐํด์ Coordinator ํจํด์ ๋์ ํ์ต๋๋ค.
-
๋ฉ์ธ ํ์์, ์ฌ์ด๋ ๋ฉ๋ด์ ์ฌ์ด๋ ๋ฉ๋ด์์ ๋ฐ์๋๋ ์ฌ๋ฌ ํ๋ฉด ์ ํ ์ปจํธ๋กค๋ฌ๋ค์ ๊ด๋ฆฌํ๊ธฐ ์ฉ์ดํ์ต๋๋ค.
-
ViewController์์ ํ๋ฉด ์ ํ์ ๋ถ๋ด์ ์ค์์ต๋๋ค.
- Side menu
์์ ์ ์น์ ํ ์ฌ์์จ ์ค์ ํธ์์ ๊ณต๋ถํ๋ Side menu ์ ๋ง ์ด๋ ต๊ฒ ๋๊ปด์ก์ง๋ง, ๊ทธ๋ผ์๋ third party๋ฅผ ์ฌ์ฉํ์ง ์๊ณ ๊ตฌํํ๋ ๊ฒฝํ์ด ์์ต๋๋ค. ๊ทธ๋ฌ๋ฉด์๋ side menu๊ฐ show๋ฌ์ ๋ ๊ธฐ์กด์ ์๋ ๋ฉ์ธ ํ๋ฉด์ด ํฐ์น๋์ ๋ฉ๋ชจ์ฅ์ ๋์์ ์์ฑํ๋ ๊ทธ๋ฐ ์ค๋ฅ๋ฅผ ๋ฐ๊ฒฌํ๊ณ ๋ ์์ ํ์ง ๋ชปํ์๋ ๊ธฐ์ต๋ ์์ต๋๋ค.
์ด๋ฒ์ ๋ค์ ์๋กญ๊ฒ ๊ตฌํํ๋ฉด์ CGAffineTransform์ ์๋ํจ์ ๋ค์ ๋๊ผ๊ณ ์ด์ ์๋ ํด๊ฒฐํ์ง ๋ชปํ๋ ๊ทธ๋ฐ ์๋ฌ๋ค์ ์์ฝ๊ฒ ํด๊ฒฐํ ์ ์์์ต๋๋ค.
- FirstResponder | InputAcecssoryView
์์ฃผ ์์ ์ ์ธ์คํ ๊ทธ๋จ ๊ฐ๋ฐํ ๋ UIResponder๊ด๋ จํด์ ๊ณต๋ถ๋ฅผ ํ์๋๋ฐ ๊ทธ์ ๊น๋จน์์ง๋ง ๋ค์ ์๋ฒฝํ๊ฒ ์๊ฒ ๋์์ต๋๋ค.
์ด๋ฒ ํ๋ก์ ํธ์์ ๋ ํํํ๊ฒ ์๊ฒ๋ ๊ฐ๋ ์ค ํ๋๋ InputAccessoryView์ ๋๋ค. ํ ์ค์ 1 thing 1page๋ฅผ ๋ณธ๋ฐ์ ํ์๊ฐ์ ๊ธฐ๋ฅ์ ๋ง๋ค์ด๋ณด๊ณ ์ถ์์ต๋๋ค. ์ด๋ ํ์๊ฐ์ ์์์ 1thing์ ์ปดํฌ๋ํธ๊ฐ ํ๋ฉด์์ ๋๋ฌด ์์ ์์ญ์ ์ํ๊ธฐ์ ๊ณ ๋ฏผ์ด ๋ง์์ง๋ง InputAccessoryView์ firstResponder๋ฅผ ์ ์งํ๋ฉฐ ํ๋ฉด์ ๋น ๊ณต๋ฐฑ์ ์ฑ์ ์ต๋๋ค.
๋ ๋์๊ฐ ์๋ฒ์์ ์ง์ ํ ์ผ์ ํ ์คํธ ์ด์์ ์ ๋ ฅํ๊ฑฐ๋ ์ ๋ ฅํ์ง ์์์ ๋, ๋ค์ ๋ฒํผ์ด ์ ๊ธฐ๊ณ ์ผ์ ์ ๋ ฅ์ ๋๊ฒผ์ ๋ ๊ฒ ํ ๋๋ฆฌ์ ๋ณํ ๋ฑ์ ๊ฐ์ง ๊ธฐ๋ฅ์ ์๋กญ๊ฒ ์ปค์คํ ํด์ ์ถ๊ฐํ์ต๋๋ค.
- UINavigationBar
์ด์ ๊น์ง ๊ฐ๋ฐํ๋ฉด์ status bar์ ๋ค๋น๊ฒ์ด์ ๋ฐ๋ ํ์์ ์ผ๋ก ํด๋น ์์ญ ์์ ์ถ๊ฐํด์ ์ฌ์ฉ๋์ผ ํ๋ค๊ณ ์๊ฐํ์ต๋๋ค. ๊ทธ๋ฌ๋ ์ง๊ธ๊ณผ ๊ฐ์ ํ ํ๋ฉด์ ๊ตฌํํ ๋ navigation bar์ subview๋ก ๋ฃ๊ฒ ๋๋ค๋ฉด SafeAreaLayoutGuide๊ฐ ์ธ์งํ์ง ๋ชปํด์ ์คํ ๋ ์ด์์์ top์์ญ ๋ ์ด์์ ์ก๊ธฐ๊ฐ ํ๋ค์ด ์ง ๊ฒ์ด๊ณ .. ์ปค์คํ ๋ค๋น๋ฐ๋ฅผ ๋ง๋ค์ด๋ ์ ์ด์ ๋ค๋น๊ฒ์ด์ ๋ฐ์ ๊ธฐ๋ณธ ํฌ๊ธฐ๊ฐ 44?๋ก ์ ํด์ ธ ์๊ธฐ์ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ด ํ์ํ์ต๋๋ค. ๋์ ํ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ๋ชฐ๋๊ณ , iOS๊ฐ๋ฐ ๋จํก๋ฐฉ์ ์ง๋ฌธํ์๋๋ฐ ์ ์พํ๊ฒ .. ์์ฐ๋ฉด ๋๋๊ฑฐ ์๋๋๋ ๋ต๋ณ์ด.. (์ํ)
- Chatting UI
์ฑํ ๊ธฐ๋ฅ์ ์ฒ์์ ๊ตฌํํ๋ ค๊ณ ํ์ ๋ ํ๋ฉด ๊ตฌ์ฑ์ ์ด๋ป๊ฒ ํด์ผํ ์ง ๋ง๋งํ๋ฉด์๋ ์์ ์ ๋ดค๋ ๋ผ์ธ message cell colllectionView๋ก ๋ฆฌํํฐ๋ง ํ ๊ธ์ด ๋ ์ฌ๋๊ณ ์ด์, ์นด์นด์คํก์ UI๋ฅผ ๋ณธ๋ฐ์ ๋ง๋ค๊ฒ ๋์์ต๋๋ค. ๋ผ์ธ์ ๊ธ์ ๋ณด๋ ์ ๋ง ๋ง์ ๊ธฐ๋ฅ๋ค์ ๊ตฌํํ์์ ์ ์ ์์์ต๋๋ค. ์๊ฐ์ ์ฌ์ ๊ฐ ์๋ค๋ฉด ๊ณ์ํด์ ์ถ๊ฐ ๊ธฐ๋ฅ์ ๊ฐ๋ฐํ๊ณ ์ถ์๋ฐ ์ง๊ธ ๋ ๋๋ฐ์ธ ์ฑ์ ๊ฐ๋ฐ์ค์ ์์ด์.. (์๊ฐ์ด 48์๊ฐ์ด์์ผ๋ฉด ์ข์์ํ ๋ฐ.. :)
- Multipart form-data
์ผ์ผ... ๊ธฐ์กด์ ๊ฐ๋ฐํ ๋ base64๋ฅผ ์ผ์๋ค๊ฐ ์ธ์คํ๊ทธ๋จ ๊ฐ๋ฐํ๋ฉด์ ํ์ด์ด๋ฒ ์ด์ค์์ ์ง์๋๋ ํจ์๋ฅผ ์ฌ์ฉํ๊ณ firesbase์ storage์์ url์ ๋ถ๋ฌ์์์ต๋๋ค. ์ด๋ฒ์ ์ฒ์์ผ๋ก Multipart ํ์์ผ๋ก ์ด๋ฏธ์ง๋ฅผ requsetํด์ผ ํ์์ต๋๋ค. ์ ๋ง ์ด๋ ค์ ๋๋ฐ.. ๊ทธ๋ผ์๋ ์๋ฒ์ธก์์ ๊ธฐ๋ฅ์ ์ด๋ฏธ ๊ตฌํํ๊ธฐ์...
์ด๋ฒ์ ์๋กญ๊ฒ ์ ํ Multipart ๋ ๊ณ์ํด์ ์ฝ๋๋ฅผ ๋ณด๋ ์ต์ํด์ ธ ๋ฒ๋ ธ์ต๋๋ค. boundary๋ฅผ ์ฌ์ฉํ๋ฉด์ ์๋ฒ์์ ์๊ตฌํ๋ json data๋ฅผ ์์์ ๋ง๊ฒ ์ฌ๋ฌ ํํธ๋ก ๋๋ ์ ๋ณด๋ด๋ฉด ๋๋ ๊ฒ์ด์์ต๋๋ค. (์ฒ์์ด ์ด๋ ต์ง..)
- HTTP/HTTPs header, body param, method, query param... Endpoints | Encodable, Decodable
๊ธฐ์กด https ํต์ ์ ๊ทธ์ ์ํ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์จ๋ค๋์ง, ๋ด์ค ์ ๋ณด๋ฅผ ๊ฐ์ ธ์จ๋ค๋์ง ๋ฑ + ๋ด๊ฐ ์ํ๋ ์ ๋ณด๋ง Decodable๋ก mappingํด์ ๋ฐ์์ค๋ฉด ๋์ด์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ํ์ด์ด๋ฒ ์ด์ค๋ฅผ 5๊ฐ์๊ฐ ์ฌ์ฉํ์๋๋ฐ,, ์ด๋ฒ ๊ธฐํ์ ์๋ฒ๋ ํต์ ์ ํ๋ฉด์ ์ฒ์์ผ๋ก.... post๋ method๋ก body param๋ ๋ฃ์ด๋ณด๊ณ get์ผ๋ก query param๋ ๋ฃ๋ ๊ฒฝํ์ ํ์์ต๋๋ค. ์ด์ ์๋ Codable์ ์ ์ ์ํ์๊น? (์ฃผ๋ก Decodable ๋ง ์ฌ์ฉํ์๊ธฐ ๋๋ฌธ์ ๋๋ค.) ์ด๋ฒ ์๋ฒ์์ ํต์ ์ ํตํด Encodable์ request!!! Decodable์ response๋ผ๋ ๊ฒ์ ์ ํํ ์๊ฒ ๋ฌ๊ณ ์ Decodable์ init์ผ๋ก ์์๋๋๊ฐ? ์๋ํ ํด๋ต์ ์์ฐ์ค๋ ์๊ฒ ๋์์ต๋๋ค. "์๋ฒ์์์ data๋ฅผ Decodableํ์ ์ ๋ชจ๋ธ ๊ฐ๊ฐ์ ์ธ์คํด์ค์ ๊ฐ์ ๋ฃ๊ธฐ ์ํด init์ ์ฌ์ฉํ๋ค๋..." ์ฐ์.. ์ ๋ง ํ๋กํ ์ฝ ์ ์ง์๋ค๋ ์๊ฐ์ด..
Endpoints๋ Clean architecture์์๋ ์ ์๋ฅผ ํ๋๋ฐ ๊น์ข ๊ถ๋์ด ์ ์ํ ๊ฒ์ ์ถ๊ฐ์ ์ผ๋ก Multipart form data requestํ์์ ์ถ๊ฐํด์ ํ๋ก์ ํธ์ ์ ์ฉํ์ต๋๋ค.
- TCP ํต์ ์ ์ค๊ณํ ๋ ํ๋ฉด ๋จ์์๋ ์คํฌ๋กค์ด๋ ํค๋ณด๋ ์ ๋ ฅ๊ณผ ๊ฐ์ user interactive๊ด๋ จ ์์ ์ ์ํํด์ผํฉ๋๋ค. ์ด์ ๋์์ TCP์ recv()๋ ์๋ฒ๋ก๋ถํฐ ๋ค๋ฅธ ์ ์ ๊ฐ ๋ณด๋ธ send()๋ฅผ ์ธ์ ๋ ์ง listening์ ํด์ผ ํฉ๋๋ค.
๊ทธ๋ฃน๋ฐฉ์ Socket์ connectํ๊ธฐ ์ํ ์๋ฒ ๊ฐ๋ฐ์๊ฐ ์ ํ ์ด๊ธฐ ๊ท์น์ ์ค์ ํ ๊ฒฝ์ฐ ์ฑ๊ณต์ ์ผ๋ก serv socket์ผ๋ก๋ถํฐ recv๋ฅผ ํ ์ ์๊ฒ ๋ฉ๋๋ค. ์์์ ์ธ๊ธํ ๊ฒฝ์ฐ ๋๋ฌธ์ background thread๋ฅผ ํ์ฉํด recv()ํจ์๋ ๊ณ์ํด์ listening์ํ๋ฅผ ์ ์งํ๊ณ , ์ฌ์ฉ์์ ์ ๋ ฅ์ด ์์ ๊ฒฝ์ฐ์๋ง ์๋ฒํํ send()๋ฅผ ๋ณด๋ด๋ ๋ก์ง์ ๊ตฌํํ์ต๋๋ค.
Restful ํต์ ์ ํ ๋๋ ํด๋ผ์ด์ธํธ ๋จ์์ request๊ฐ ์์ด์ผ๋ง server์ธก์์ response๋ฅผ ํฉ๋๋ค. ๊ทธ๋์ ์ ๋ ์์ ์ ์ธ์คํ ๊ทธ๋จ ๊ฐ๋ฐ์ ํ ๋, ์ฑํ ๊ธฐ๋ฅ์ ๊ตฌํํ ๋ ๊ฒ์๊ธ ์ฒ๋ผ ์๋ก ๋น๊ฒจ์ refresh๋ฅผ ํด์ผ๋ง ํ ์ ์ ๊ฐ ๋จ๊ธด ๊ธ์ ๋ณผ ์ ์์์ต๋๋ค. ์ด์ ๋ฐ๋ฉด Socket ํต์ ์ recv()๋ฅผ ํ์ฉํด์ ์๋ฒ์ ๋ค๋ฅธ ์ ์ ๊ฐ send() ํ ๊ฒฝ์ฐ recv()์ค์ธ ํด๋ผ์ด์ธํธํํ ํ ์ ์ ๊ฐ ๋ณด๋ธ ๊ธ์ ๋ค๋ฅธ ํด๋ผ์ด์ธํธ์๊ฒ๋ ์ ์กํ ์ ์๋ค๋๊ฒ ์ ๋ง ์ ๊ธฐํ๊ณ ์ด ๊ธฐ๋ฅ์ ์๊ฐํด๋ธ ๊ฒฝ์์ด๋ ๋๋จํ๋ค๊ณ ์๊ฐํ์ต๋๋ค.
-
์ด ๋ ์ ์ํด Socket๊ด๋ จ ๊ฐ๋ ๋ค์ ๊ณต๋ถํ๋ฉฐ ๊ตฌํํ๋ TCP, UDP serv, client ...๋ฑ C์ธ์ด๋ก ๊ตฌํํ๋ ํ๋ก์ ํธ๋ฅผ ๊ทธ๋๋ก Swift๋ก ํผ์ ๊ตฌํํ์๋๋ฐ ๊ทธ ๋ณด๋์ด ์์๋ ๊ฒ ๊ฐ์์ต๋๋ค. BSD socket ์์ฒด๊ฐ C์ธ์ด๋ก ๊ฐ๋ฐ๋ ๊ฑฐ๋ผ ์ด๋ฅผ wrappingํ ํจ์๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์ withUnsafePointer()๋ฑ ์ฒ์ ์ ํ๋ ํจ์๋ค์ ์ฌ์ฉํ ์ค ์์์ผ ํ๊ณ ์๋กญ๊ฒ ํ์ตํ๊ฒ ๋์์ต๋๋ค.
-
๊ธธ๋ค๋ฉด ๊ธธ๊ณ ์งง์ ๊ธฐ๊ฐ์ด์์ง๋ง,, ์ ๋ง ๋ง์ ์๋ก์ด ๊ธฐ๋ฅ๋ค์ ํ์ตํ๋ฉฐ ์ ์ฉํด ๋๊ฐ์ต๋๋ค. ์ด๋ก ์ผ๋ก ๊ณต๋ถํ๋ฉฐ ์ด๋ฆผ์ก์ ์๊ณ ์์๋ ์ ๋๋ฉ์ด์ ๊ณผ ์ด๋ก ์ผ๋ก ๊ณต๋ถ๋ง ํ์๋ Clean architecture, ๋ธ๋๋์์ ์ ๊ณตํ datasource, delegate๋ฅผ ๋ค๋ฃจ๋ adapter pattern ๋ฑ ๋ค์ํ ์ด๋ก ์ ์ค์ ๋ก ์ ์ฉํ๋ฉด์ ์ง์๋ค์ด ์น๊ทผํด์ง ๊ฒ ๊ฐ์ต๋๋ค.
-
์ด TCP ํ๋ก์ ํธ๋ ๊ต์๋์ด ์๋ฌด ์ธ์ด๋ ์ฌ์ฉํด๋ ๋๋ค๊ณ ํ์ จ๊ธฐ์ Swift๋ฅผ ์ฌ์ฉํ ์ ์์ด ์ ๋ง ์ฌ๋ฐ์ ๊ฒ ๊ฐ์์ต๋๋ค. ํ์ง๋ง ์ด๊ธฐ ํ๋ฉด์ UI๋ฅผ ์ฑ์ ๋ฃ์ ๋ฐ์ดํฐ๊ฐ ๋๋ฌด ์์ด์ ๋ง๋งํ์์ต๋๋ค. ๊ทธ๋์ ๋ถ์กฑํ ๋ถ๋ถ๋ค์ ์ ๋๋ฉ์ด์ ๋ค์ ๋ถ๋ถ ๋ถ๋ถ ์ ์ฉํด์ ์์ ์ ์ด๋๋ ค๊ณ ์๋ํ์ต๋๋ค.
-
Carousel ๊ด๋ จ ๊ธฐ๋ฅ ๊ฐ๋ฐ์ ์ธ๋ก๋ก๋ ํด๋ณด๊ณ ๊ฐ๋ก๋ก๋ ํด๋ดค๊ณ ๋ธ๋ก๊ทธ์ 3ํธ ์ ๋ ์ ๋ฆฌ๋ฅผ ํ์ต๋๋ค. ์ด๋ฒ์๋ collectoinView์ contentInset์ ๋ฃ์๊ณ ์ด ๊ฒฝ์ฐ๋ ๋ ์ฒ์์ด๊ธฐ์ ๋ ์๋ก์ด ๋ฒฝ์ ๋ง๋ฌ์ต๋๋ค. ๊ทธ๋ฌ๋ฉด์ ์๋ก ์๊ฒ๋ ์ ์ scrollView.content.x๋ collectionView์ content inset๋ฅผ ์ธ์งํ์ง ๋ชปํ๋ค๋ ๊ฒ์ด๊ธฐ์ contentinset.leading์ ๊ฐ๋งํผ ๋นผ์ผํ๊ณ , collectionView.contentSize.x์ ๋ ๋ถ๋ถ๋ ๋ง์ฐฌ๊ฐ์ง์์ต๋๋ค. ์ด๋ถ๋ถ์ด ์ ๋ง ๊น๋ค๋กญ๋ค๋ ๊ฒ์ ๋ ์ด๋ ๊ฒ ์๋ก ๊ฒฝํํ์ต๋๋ค.