โจ๏ธ ๊ฐค๋ญ์ ์ฒ์ง์ธ์ ๊ทธ๋ฆฌ์ํ๋ ์์ดํฐ ์ ์ ๋ค์ ์ํ ํค๋ณด๋

๋ฌผ๋ก ์ด์ฃ . ์ฑ์คํ ์ด์์ ์ค์นํด๋ณด์ธ์. GitHub ์ ์ฅ์๋ ์๋ต๋๋ค.
์ ํ ์์ดํฐ์ ์ฐพ๋ ์๋น์๋ค์ด ์ฆ๊ฐํ๊ณ ์๋ค. ๋์ ๋๋ ๋ถ๋ถ์ ์์ดํฐ์ ์ฐพ๋ ์ค์ฅ๋ ์ธต ์๋น์๊ฐ ๋์ด๋๊ณ ์๋ค๋ ์ ์ด๋ค. ๋๋ถ๋ถ์ ์ฌ๋๋ค์ ๊ฐค๋ญ์์์ ์์ดํฐ์ผ๋ก ๋ชป ๋์ด์ค๋ ์ด์ ๋ก ํตํ๋ น์๊ณผ ์ผ์ฑํ์ด๋ฅผ ๊ผฝ๋๋ฐ, ๋ถ๋ชจ๋์ด ์์ดํฐ์ผ๋ก ๋ฐ๊พธ์ ๋ค์ ๋ด๊ฐ ๊ด์ฐฐํ ๋ฐ๋ ์กฐ๊ธ ๋ฌ๋๋ค.
์๋ฌด๋ ์์ ๊ผฝ์ง ์์ ์์ ์ธ์ ๋๊ด์ ๋ฐ๋ก ํค๋ณด๋์๋ค. ๋ํ๋ฏผ๊ตญ ์๋น์๋ค์ 10ํค ํด๋์ ํ ์์ ๋ถํฐ ๋ฌธ์๋ฅผ ์ ๋ ฅํจ์ ์๋ฌด๋ฐ ๋ถํธํจ์ด ์์๋ค. ์ธ์ข ์ ์ ์ ์๋ฆฌ๋ฅผ ๋ณธ๋ฐ ๋ง๋ ์ฒ์ง์ธ์ด๋ผ๋ ๊ฐ๋ ฅํ ์ ๋ ฅ ๋ฐฉ์ ๋๋ฌธ์, ํ๋์ ๋ฒํผ์ ์ํ๋ฒณ์ด 3๊ฐ, 4๊ฐ์ฉ ๋ถ์ด์๋ ์๋ฏธ๊ถ์ ๋นํด ์ฟผํฐ ํค๋ณด๋์ ํ์์ฑ์ด ํ์ ํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค. ํ์ด๋ฌ์ ๋น์๋ถํฐ ์ค๋งํธํฐ์ด ์กด์ฌํ๋ ์ํ ์ธ๋๊ฐ ์๋ ์ด์ ์ฌ์ ํ ์ฒ์ง์ธ ํค๋ณด๋๋ฅผ ์ฌ์ฉํ๊ณ ๊ณ์๋ ๋ถ๋ค์ด ๋ง๋ค.
2010๋ ์ฒ์ง์ธ์ ํนํ๊ฐ ๊ฐ๋ฐฉ๋ ์ดํ ์์ดํฐ์๋ 2013๋ ๋ถํฐ ์ฒ์ง์ธ ํค๋ณด๋๊ฐ ์ถ๊ฐ๋์์ง๋ง, ์ด์ํ๊ฒ๋ ์์ดํฐ์ ํค๋ณด๋์ ๋ชจ์์ด ์กฐ๊ธ ๋ฌ๋๋ค. ๊ฐ์ฅ ๊ฒฐ์ ์ ์ธ ์ฐจ์ด์ ์ ์๋ฆฌ๋๊น ๋ฒํผ๊ณผ ๋์ด์ฐ๊ธฐ ๋ฒํผ์ด ๋ฐ๋ก ์กด์ฌํ๋ค๋ ์ ์ด๋ค.

- ๊ฐค๋ญ์:
ใ แใ กโ ๋์ด์ฐ๊ธฐ โใ ใ ฃแใดโ ๋์ด์ฐ๊ธฐ โใดแแใ ฃใ - ์์ดํฐ:
ใ แใ กโ ๋์ด์ฐ๊ธฐ โใ ใ ฃแใดโ ์๋ฆฌ๋๊น โใดแแใ ฃใ
์ด์ ๊ฐ์ด 2๊ฐ์ง ๋ค๋ฅธ ๋ฒํผ์ด ๋ฐ๋ก ์กด์ฌํ๋ ๊ฒ ๋ฟ๋ง ์๋๋ผ ๋ฒํผ์ ๊ฐ ํฌ๊ธฐ๋ ๋์ฑ์ด ์์์ ธ, ์คํ๊ฐ ์ง์์ ์ผ๋ก ๋ฐ์ํ๋ ๋ฑ ์ฌ์ฉ์ ๋ถํธํจ์ ํธ์ํ๋ ์ฌ๋๋ค์ด ๋ง์๋ค. ์ด๋ฐ ์ด์ ๋ก ๊ฐค๋ญ์ ์ฒ์ง์ธ๊ณผ ์ ์ฌํ ์์ดํฐ ํค๋ณด๋๋ฅผ ๋ง๋ค์ด๋ณด๊ณ ์ถ๋ค๋ ๊ฒฐ๋ก ์ ์ด๋ฅด๋ ๋ค.
ํ์ต ์์ด ์ฝ๊ฒ ์ฌ์ฉํ ์ ์๋ ์์ดํฐ์ฉ ์ฒ์ง์ธ ํค๋ณด๋๋ฅผ ๋ง๋ค์ด ๋ณด์!
์ด ํ๋ก์ ํธ์ ์ฐ๊ตฌ ๊ธฐ๋ก๋ ๊ณต๊ฐ๋์ด ์๋ค.
๐ ํนํ๊ถ ๋ฐ ๋ฒ์ ๊ถ๋ฆฌ
์ฐ์ ํนํ๊ถ๊ณผ ๋ฒ์ ๊ถ๋ฆฌ์ ์๋ฌด๋ฐ ๋ฌธ์ ๊ฐ ์๋์ง๋ฅผ ํ์ธํ๋ค. ์กฐ์ฌํ ๊ฒฐ๊ณผ, ์กฐ๊ดํ ํนํ๊ถ ๋ณด์ ์๋๊ป์ ํนํ๊ถ์ ์ ๋ถ์ ๊ธฐ์ฆํ์ ๊ตญ๊ฐ ํ์ค์ผ๋ก ์ฑํ๋ ์ดํ, ํ๊ธ ์ํ์ ๋ํ ํนํ๊ถ ์ฌ์ฉ๊ถ์ด ๋ฌด์์ผ๋ก ํ์ฉ๋์๋ค. ์ด์ ์๋ฌด๋ฐ ๋ฌธ์ ๊ฐ ์์์ ํ์ธํ ํ ๊ฐ๋ฐ์ ์ฐฉ์ํ๋ค.
๐ ๊ธฐ์ ์ ํ๊ธฐ
์์ดํฐ ์ํ์ ๋ง๋ค๊ธฐ ์ํด ์ ํ์ ์ปค์คํ ํค๋ณด๋ ๋ง๋ค๊ธฐ ๋ฌธ์๋ฅผ ์ ๋ ํ๋ค. ํ์ธ ๊ฒฐ๊ณผ ์ผ๋ฐ์ ์ธ ์์ดํฐ ์ฑ์ ์ ์ํ๋ ๋์ด๋์ ๋น์ทํด๋ณด์๋ค. ์ผ๋จ ViewController ๋ด์ ๋ฒํผ๊ณผ ๋ก์ง์ ๋๋ ค๋ฐ์ ๊ฐ๋ฐํ๋ ๊ฒ์ ์ฌ์๋ณด์์ผ๋, SwiftUI๋ฅผ ์ด์ฉํ iOS ๊ฐ๋ฐ์ ํ ์ ์ด ์์ด SwiftUI๋ก ๊ฐ๋ฐํด๋ณด๊ณ ์ถ์๋ค. ์ฒ์์๋ ์๋ก ๋์จ SwiftUI Grid ๊ธฐ๋ฅ์ ์ฐ๋ฉด ๊น๋ํ๊ฒ ๋ฒํผ์ ๋ฐฐ์ดํ ์ ์์ ๋ฏํ๋๋ฐ, ์ด๋ ์ฌ์ง ์ฑ์ฒ๋ผ ์๋ง์ ์๋ฆฌ๋จผํธ๋ค์ ํ๋ฉด์ ๋ฐฐ์ดํ๋ ๊ฒ์ ๋ ์ต์ ํ๋์ด์๊ณ , ๋์ ๊ฒฝ์ฐ์ฒ๋ผ ๋ฒํผ์ ๊ฐ์๊ฐ ์ ํด์ ธ์๋ ๊ฒฝ์ฐ์๋ (์น์์์ display: flex์ ์ ์ฌํ) HStack๊ณผ VStack์ผ๋ก ์ถฉ๋ถํ๋ค๊ณ ํ๋จํ๋ค.
์์ดํฐ ์จ๋ํํฐ ํค๋ณด๋๋ ์ต์คํ ์ ์ด๋ผ๋ ๋ ํนํ ๊ตฌ์กฐ๋ฅผ ์ด์ฉํด ์ ์ํ๋ค. iOS ์ฑ ๋ณธ์ฒด๊ฐ ์๋๋ฉด ์ ๋ถ ์ต์คํ ์ ์ด๋ผ๊ณ ์๊ฐํ๋ฉด ๋๋ค. ์ปค์คํ ํค๋ณด๋๋ ์ต์คํ ์ ์ด๊ณ , iOS ์์ ฏ๋ ์ต์คํ ์ ์ด๊ณ , ์ ํ ์์น ์ฑ์๋ ์ต์คํ ์ ์ด ํ์ฌ๋๋ค. Ray Wenderlich์ ๋ฌธ์๋ฅผ ์ฝ์ผ๋ฉฐ ๊ฐ๋จํ ๋ฐ๋ชจ๋ค์ ์ ์ํ๋ฉฐ ํค๋ณด๋ ์ต์คํ ์ ์ ๋ํ ์ดํด๋ฅผ ๋์๋ค.



๋ช ๊ฐ์ง ์ด๊ธฐ ๋ฒ์ ๋ค
๊ฐ์ด๋ฐ ์ด๋ฏธ์ง์ "ใ " ๊ทผ์ฒ์ ํ์ ๋ฐฐ๊ฒฝ์ iOS ๊ธฐ๊ธฐ์ NSRange์ setMarkedText๋ผ๋ ๊ธฐ๋ฅ์ด์๋ค. ์ ๋ ฅ ์ค์ธ ๊ธ์์ ์์ญ ์ฒ๋ฆฌ๋ฅผ ํด์ ์ ๋ ฅ์ ๋์์ฃผ๋ ๊ธฐ๋ฅ์ด์๋๋ฐ, ์ค๊ตญ์ด์ ํ์ด๋ณ์(Pinyin)์ฒ๋ผ ๋ฌธ์ ์ ๋ ฅ ์ง์ ์ ์กฐํฉ์ฉ์ผ๋ก ์ฌ์ฉ๋๋ ๊ฒ์ผ๋ก ์ฒ์ง์ธ์ฉ์ผ๋ก ์ ์ ํ์ง ์๋ค๊ณ ํ๋จํ๋ค. ๋ํ๋ ํฅ๋ฏธ๋ก์ด ์ ์ผ๋ก ์์ดํฐ ๊ธฐ๋ณธ ์ํ์ ์์๋ค์ ๊ธฐ๋ณธ์ผ๋ก ์ ๊ณต๋๋ ์ด๋ค systemColor์๋ ๋ฌ๋๋ค. ์๊น์ Color Meter๋ก ๋ฝ์ ํ๋ํ๋ ์ ๋ ฅํ๋ค.
๐ถโ๐ซ๏ธ ๊ทธ๋ฐ๋ฐ ์ฒ์ง์ธ์ ์ด๋ป๊ฒ ๋ง๋ค์ง
์ฒ์ง์ธ์ ์ ๋ ฅ ๋ก์ง์ ๊ตฌํํ๊ธฐ ์ํด ์ฐฌ์ฐฌํ ์๊ฐ์ ํ๋ ์ค, ์ด๊ฒ ๋๋จํ ๋ณต์กํ๋ค๋ ๊ฒ์ ์๊ฒ ๋์๋ค. ์๋ฅผ ๋ค์ด ๋ค์์ ๊ฒฝ์ฐ๋ฅผ ์๊ฐํด๋ณด์.
์์ ์ ๋ ฅํ๊ธฐ ์ํด์ใ์ด ์ ๋ ฅ๋์ด ์๋ ๊ฒฝ์ฐ์ใ ใ ๋ฒํผ์ ๋๋ฅด๋ฉด์์ด ๋์ด์ผ ํ๋ค. ์ด์ ๊ธ์์ ์ฌ๊ฒฐํฉ์ด ๊ฐ๋ฅํ์ง ํ๋จํด์ผ ํ๋ค.์์์ใ ก๋ฅผ ์ ๋ ฅํ๋ฉด์์ฆ๊ฐ ๋์ด์ผ ํ๋ค. ๋ง์ง๋ง ์ข ์ฑ ํ๋๊ฐ ์ถ์ถ ๊ฐ๋ฅํ์ง ํ์ธํด์ผ ํ๋ค. ์ด์ ๊ธ์์์ ์ถ์ถ์ด ๊ฐ๋ฅํ์ง ํ๋จํด์ผ ํ๋ค.๊น์์ใ ใ ํค๋ฅผ ๋๋ฅด๋ฉด๊นใ ์ด ๋์ด์ผ ํ๋ค. ์ฆ ์ข ์ฑ ์ถ์ถ + ๋์๋ฆฌ ๋ณ๊ฒฝ์ด ๊ฐ๋ฅํ์ง ํ๋จํด์ผ ํ๋ค.๊ฐ์์ใ ใ ํค๋ฅผ ๋๋ฅด๋ฉด๊ฐ์ด ๋์ด์ผ ํ๋ค. ์ฆ, ๋จ์ํ๊ฒใ,ใ ,ใ ๋ฅผ ์ํธ ๋ณ๊ฒฝํ๋ ๊ฒ ๋ฟ๋ง ์๋๋ผ,ใฝ๋ฑ์ ๊ฒน๋ฐ์นจ์ ๋ณํ๋ ํ๋จํด์ผ ํ๋ค.
์ด ์ธ์๋ ์๋ง์ ๊ฒฝ์ฐ๊ฐ ๋ง๋ค. ์กฐํฉํ ํ๊ธ์ ๋์ดํด๋๊ณ ํ๋ํ๋ ๊ณ์ฐ์ ํ๋ค๊ณ ํ๋๋ผ๋, ์ ๊ฒฝ์ฐ์ ์๋ฅผ ๋ชจ๋ ๊ณ ๋ คํ๋ ๊ฒ์ ๋งค์ฐ ์ด๋ ต๋ค. ์ ํ์ํ๊ธฐ๊ณ๋ก ์ ์ํ ๊ฒฝ์ฐ ๋๋ฒ์๋ณด๋ค ํจ์ฌ ๋ง์ ์ฝ 20๊ฐ ์ ๋์ ๋ฐ์ดํฐ ์ ์ฅ ์คํ๊ณผ ์์ญ ๊ฐ์ง์ ์ํ๊ฐ ํ์ํ๋ค๊ณ ํ๋จํ๋ค. (์ ํํ ๊ณ์ฐํ์ง๋ ์์์ผ๋ ๋ ๋จ์ํ ๊ตฌํ ๋ก์ง์ด ์กด์ฌํ ์๋ ์๋ค. ํน์๋ผ๋ ์ด ๋ฐฉ์๋๋ก ์ง์ง ๋ง๋ค์ด๋ณด๊ณ ์ถ์ ์ฌ๋์ด ์๋ค๋ฉด ์ด ํนํ์ ๋ค์ด์ด๊ทธ๋จ์ ์ฐธ๊ณ ํ์.) ์ธํฐ๋ท ์์ ๋ช ๊ฐ์ง ๊ตฌํ ๋ก์ง๋ค์ ๋ฐ๊ฒฌํ๊ธฐ๋ ํ์ง๋ง, ์ ๋ถ ๊ธธ๊ณ ๋ณต์กํด Swift๋ก์ ๋ฒ์ญ์ ์ฐจ์นํ๊ณ ์ฝ๋ ์์ฒด๋ฅผ ์ดํดํ๋๋ฐ๋ ํ์ธ์์ด ๊ฑธ๋ฆด ๋ฏ ํ๋ค. ๊ทธ๋ฌ๋ค ๋ฌธ๋ ์ด๋ฐ ์๊ฐ์ด ๋ค์๋ค.
๊ทธ๋ฅ ์ ๋ถ ํ๋์ฝ๋ฉํ๋ฉด ๋์์?
์๊ฐํด๋ณด๋ฉด ๊ฐ์ ๋ฒํผ ์กฐํฉ์ ์ ๋ ฅํ๋ฉด ๊ฐ์ ๊ธ์๋ก ์ฐํ์ผํ๋ ๊ฒ์ด ๋ฐ๋ก ํค๋ณด๋์ด๋ฆฌ๋ผ. ๊ทธ๋ฅ ๋ชจ๋ ๊ฒฝ์ฐ์ ์๋ฅผ ์์ฑํด์ ํ๋์ ๊ฑฐ๋ํ JSON ํ์ผ์ ๋ฃ์ด๋ฒ๋ฆฌ๋ฉด ์ด๋จ๊น! ๋จ์ํ๊ฒ ์ ์ ํด๋ณด์๋ ํ๊ธ์ ์ฝ 11,000์ ๋ฐ์ ์ ๋๊ณ , ์๋ค ๊ธ์๊น์ง ๊ฐ์ด ๊ณ ๋ คํ๋ ์ผ์ด์ค๋ง ๊ณ ๋ คํ๋ค๊ณ ํด๋ ์กฐํฉ์ ๋ง์์ผ 10๋ง ๋จ์๋ฅผ ๋์ด๊ฐ์ง ์์ ๊ฒ์ผ๋ก ํ๋จํ๋ค. JSON์ ํฌ๊ธฐ๋ 2MB ์ํ์์ ๋์ด๊ฐ์ง ์์ ๊ฒ์ด๋ค.
๊ณผ๊ฑฐ์ฒ๋ผ ์๋ฒ ๋๋ ํ๋์จ์ด์์ KB ๋จ์๋ก ๊ณจํ๋ฅผ ์น๋ฉฐ ๋ฉ๋ชจ๋ฆฌ ์ต์ ํ๋ฅผ ํด์ผํ๋ ์๋๊ฐ ์๋๋ค. ํ๊ธ์ด ์ธ๋ฅ์ ํจ๊ปํ๋ ์ด์ ๋ถ๋ช ๋ฏธ๋์ ๋๊ตฐ๊ฐ๊ฐ ์ฒ์ง์ธ์ ๋ค์ ์ ์ํ ์ผ์ด ์์ ๊ฒ์ด๊ณ , ๊ทธ๋ฅผ ์ํด์๋ ๋๊ตฐ๊ฐ๊ฐ ์จ์ ํ ์ฒ์ง์ธ ์ง๋๋ฅผ ๋ง๋ค ๊ฐ์น๊ฐ ์ถฉ๋ถํ ์กด์ฌํ๋ค.
๐จ๏ธ ํ์: ์ธ์์์ ๊ฐ์ฅ ๋จ์ํ ์ฒ์ง์ธ ๊ตฌํ์ฒด
๊ทธ๋ก ์ธํด์ ํ์๋ฅผ ๋ง๋ค์๋ค. ์ฒ์ง์ธ์ ๋ชจ๋ ์ํ์ ์กฐํฉ์ ๋ด์๋์ ํ๊ธ ์ง๋ ๐บ๏ธ ์ด๋ค. ์ด 5๋ง ์ฌ๊ฐ์ ์ ๋ ฅ ์ผ์ด์ค๊ฐ ์กด์ฌํ๋ฉฐ, ์์ถ๋ JSON์ 500KB ์ ๋ ํฌ๊ธฐ์ด๋ค.
๊ณ ์ฐจ์์ ๊ธฐ๋ฅ์ ๊ตฌํํ๊ธฐ ์ํด์๋ ๋ช ๊ฐ์ง ๊ธฐ๊ต๋ค์ด ๋ ํ์ํ์ง๋ง (๋ฐฑ์คํ์ด์ค ํค๋ฅผ ๋๋ ์ ๋ ๊ธ์ ๋จ์๋ก ์ง์์ง๋ ๊ฒ์ด ์๋๋ผ ์์ ๋จ์๋ก ์ง์์ง๋ค๊ฑฐ๋, ์๊ฐ์ ๋ฐ๋ฅธ ์๋ฆฌ๋๊น ์ฒ๋ฆฌ๋ฅผ ํ๋ค๊ฑฐ๋) ๊ถ๊ทน์ ์ผ๋ก ํต์ฌ ์ ๋ ฅ ๋ก์ง์ ๋ค์๊ณผ ๊ฐ์ด ๋จ์ํ๋ค.
const type = (์ด์ : string, ํ์: hwalja, ํค: string, ์์ ์ค: boolean) => {
const ๋ง์ง๋งํ๊ธ์ = ์ด์ .slice(-1)
const ๋ง์ง๋ง๋๊ธ์ = ์ด์ .slice(-2)
if (์์ ์ค && ๋ง์ง๋ง๋๊ธ์ in ํ์[ํค]) return ์ด์ .slice(0, -2) + ํ์[ํค][๋ง์ง๋ง๋๊ธ์]
if (์์ ์ค && ๋ง์ง๋งํ๊ธ์ in ํ์[ํค]) return ์ด์ .slice(0, -1) + ํ์[ํค][๋ง์ง๋งํ๊ธ์]
return ์ด์ + ํ์[ํค]['']
}
๋จ 5์ค ๋ง์ผ๋ก ์ฒ์ง์ธ ๋ก์ง ๊ตฌํ์ด ๊ฐ๋ฅํ๋ ๋๋ ๊ฐํ ์ด๊ฒ์ ์ ์ธ๊ณ์์ ๊ฐ์ฅ ๋จ์ํ ์ฒ์ง์ธ ๊ตฌํ์ฒด๋ผ๊ณ ์นญํ๊ฒ ๋ค.
์ ์ฒ๋ฆฌ ๋ฐฉ์์ด ๊ถ๊ธํ ์ฌ๋๋ค์ด ์์ํ
๋ฐ,
์
๋ ฅ ๊ฐ๋ฅํ 11,000์ฌ ์์ ํ๊ธ ๊ธ์๋ค์ ์ข
์ฐฉ์ ์ผ๋ก ์ผ์
๊ทธ ๊ธ์๋ฅผ ์์ฑํ๊ธฐ ์ํด ๋ง์ง๋ง์ผ๋ก ๋๋ฌ์ผํ์ ๊ธ์ ๋ ๋ฌด์์ธ์ง,
๊ทธ๋ฆฌ๊ณ ๊ทธ ๊ธ์ ๋ฅผ ๋๋ฅด๊ธฐ ์ ์ํ๋ ๋ฌด์์ธ์ง ์ญ์ฐํ๋ค.
์๋ฅผ ๋ค์ด ์ญ์ด ์๋ค๋ฉด ์ด์ ์ํ๋ ์ฌ์ด๊ณ ใฑ์ ๋๋ฌ์ ์ญ์ ๋๋ฌํ๊ฒ ๊ตฐํ๋ ์์ผ๋ก ์ญ์ผ๋ก ๊ณ์ฐํ ๊ฒ์ด๋ค.
๋ฌผ๋ก ์ด์ ๋ํด ์ฌ๋ฌ ์ฃ์ง ์ผ์ด์ค๋ค์ ์ฒ๋ฆฌํด์ผ ํ๋ค.
4๋
์ ์กฐ์ฑํ์ด ๋๋ฅผ ๋ง์ด ๋์์ฃผ์๋ค.
๋ค์ ์ฐฝ์ ํ์๋ฅผ ์ด์ฉํด ๊ฐ๋จํ๊ฒ ๊ตฌํํด๋ณธ ์ฒ์ง์ธ ์ ๋ ฅ ์์ฐ์ด๋ค.
ํ์๋ ๋ชจ๋ ํ๋ซํผ์ ์ฌ์ฉํ ์ ์๋๋ก ๊ณต๊ฐํ๋ค.
์ ๋ฐ๋ชจ๋ก ์ง์ ํ์๋ฅผ ์
๋ ฅํด๋ณด์!
๊ฐ์ฅ ๋จ์ํ ๊ตฌํ์ฒด์ด์ง ๊ฐ์ฅ ๊ฐ๋ฒผ์ด ๊ตฌํ์ฒด๋ ์๋๋ผ๋ ์ ์ ๋ช ์ฌํ์.
์กฐํฉํ ํ๊ธ๋ก ๋ฌธ์์ด ์ ๊ทํ๋ฅผ ํ๋ฉด ์ข ๋ ๊ฒฝ์ฐ์ ์๊ฐ ์ค์ง ์๋์?
ํ์ ํ๋ก์ ํธ์ ๋ํด ์ด์ฑ๊ด ๋๊ป์ NFD๋ก ๋ฌธ์์ด ์ ๊ทํ๋ฅผ ํด์ ์ด์ค์ข
์ฑ์ ๋ผ์ด๋๊ณ ๋ง๋ค๋ฉด ์ข ๋ ๊ฒฝ์ฐ์ ์๊ฐ ์ค์ง ์์๊น์ ๋ํ ์ง์ ์ ํด์ฃผ์
จ๋ค.
๋๋ ์์ฑํ ํ๊ธ๋ง ๋๊ณ ์๊ฐํ๋๋ฐ, ๋ง์ํ์ ๋๋ก ์กฐํฉํ์ผ๋ก ์ ์ ํ ์ ๊ทํ๋ฅผ ๊ฑฐ์น๋ฉด ๊ฒฝ์ฐ์ ์๊ฐ ํ์คํ ๋ง์ด ์ค๋ค.
์๋ฅผ ๋ค์ด ์ แแแใ
ฃใ
๊ฐ์ด ํ์ด๋๊ณ แแใ
ฃ ๋ถ๋ถ๋ง ใ
๋ก ์กฐํฉํ ๋ค, ใดใ
ใ
์ ์ ๊ทํ ๊ณผ์ ์ ํตํด ๋
์ผ๋ก ๋ณํํ๋ ๊ฒ์ด๋ค.
ํ์ ํ๋ก์ ํธ์ ๊ฒฝ์ฐ ํ ์ ๊ทผ์ ์ ์งํ๊ธฐ๋ก ํ๋ค.
ํ์๋ ๊ฐ์ฅ ์ฝ๊ณ ๋จ์ํ ์ฒ์ง์ธ ๊ตฌํ์ฒด๋ฅผ ์งํฅํ๋ ๋งํผ
ํ์ฌ์ ์ ๊ทผ์ด substring + replace ๋ง์ผ๋ก ๊ตฌํํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
๋ง์ฝ NFD์ ์ ๊ทํ์ ๋ํ ์ ๋ณด๋ฅผ ์ถ๊ฐํด์ผํ๋ค๋ฉด,
๋น๋ก ํ์ ํ๋ก์ ํธ ์์ฒด๋ ๊ฐ๋ฒผ์์ง๊ฒ ์ง๋ง,
๊ทธ๋ฅผ ์ฌ์ฉํ๋ ๊ฐ๋ฐ์ ์ธก์์ NFD์ ์ ๊ทํ์ ๋ํ ์ถ๊ฐ์ ์ธ ํ์ต ๋ฐ ๊ตฌํ์ด ํ์ํ๋ค.
์คํ ๋งํ๋ฅผ ์ด์ฉํ ํ์ต ๊ณก์ ์ ๋ถํธํจ์ ๋๊ปด
๋ชจ๋ ์ ๋ณด๋ฅผ ํ๋์ฝ๋ฉํด ๊ฐ์ฅ ๋จ์ํ ํํ๋ก ๊ตฌํํ๊ธฐ๋ก ํ ํ์ ํ๋ก์ ํธ์ ๋ณธ ๋ชฉ์ ์ ์ด๊ธ๋๋ค.
๋๋ถ์ด ์ด๋ฏธ ์์ถ๋ ๋ฒ์ ์ 500KB ์์ค์ด๊ธฐ์ ์
๋ ฅ ์์ง์ผ๋ก ์ฌ์ฉํ๊ธฐ์ ๋ถ๋ด์ด ๋๋ ํฌ๊ธฐ๊ฐ ์๋๋ค.
๐ค ์๋์์ฑ ํค๋ณด๋ ๋ง๋ค๊ธฐ
์ฒ์ง์ธ์ ์ฐ๋ ์ฌ๋๋ค์ด ๋น ๋ฅธ ์๋๋ก ํ์๋ฅผ ์น ์ ์๋ ์ด์ ๋ ๋ฐ๋ก ์๋ ์์ฑ ํ ์คํธ (๊ฐ๋ฐ ๋ช ์นญ: Apple QuickType)์ ์ ๊ทน์ ์ผ๋ก ํ์ฉํ๋ค๋ ์ ์ด๋ค. ์ด ์๋ ์์ฑ ํ ์คํธ๋ค์ ์ฌ์ฉ์๊ฐ ์ ๋ ฅํ๋ ํจํด์ ์ง์์ ์ผ๋ก ํ์ตํ์ฌ ์ฌ์ฉ์์ ์ ๋ ฅ์ ๋๋๋ค.
๋คํํ๋ ์ ํ UIKit์๋ Core ML๊ณผ Neural Engine์ ์ง์ ๊ฑด๋๋ฆฌ์ง ์๊ณ ๋
๋ฌธ๋งฅ ์๋ ์์ฑ ๊ธฐ๋ฅ์ ์ฌ์ฉํ ์ ์๋ UITextChecker๋ฅผ ์ ๊ณตํ๋ค.
ํ๊ตญ์ด๋ ๋ฌผ๋ก ์ง์ํ๋ฉฐ, learnWord()์ unlearnWord()๋ฅผ ์ฌ์ฉํ์ฌ ์ฌ์ฉ์์ ์
๋ ฅ์ ํ์ตํ๊ฑฐ๋ ์ญ์ ํ ์ ์๋ค.
let uiTextChecker = UITextChecker()
let input = "ํ๋ณตํ"
let guesses = uiTextChecker.completions(
forPartialWordRange: NSRange(location: 0, length: input.count),
in: input,
language: "ko-KR"
)
/*
[
"ํ๋ณตํ", "ํ๋ณตํฉ๋๋ค", "ํ๋ณตํ๊ฒ", "ํ๋ณตํ ", "ํ๋ณตํ๋ค", "ํ๋ณตํ๊ณ ", "ํ๋ณตํ์ง",
"ํ๋ณตํ๋ค๊ณ ", "ํ๋ณตํ๋ค๋", "ํ๋ณตํ๊ธฐ", "ํ๋ณตํ๋ฉด", "ํ๋ณตํ ๊น", "ํ๋ณตํ๊ธธ",
"ํ๋ณตํจ์", "ํ๋ณตํ๊ธฐ๋ฅผ", "ํ๋ณตํจ", "ํ๋ณตํ๋", "ํ๋ณตํํ
", "ํ๋ณตํ์", "ํ๋ณตํ๋ค"
]
*/
์ด ๊ธฐ๋ฅ์ ์ด์ฉํด ์๋์์ฑ ๊ธฐ๋ฅ์ ์์ฑํ๋ค. ๊ฐ๋ ๋ฌธ๋งฅ์ด ์ด์ํ๊ฑฐ๋ ์๋ฌด๋ฐ ์ถ์ฒ์ ํด์ฃผ์ง ์๊ฑฐ๋ ํ๋ ๋ฒ๊ทธ๊ฐ ์กด์ฌํ์ง๋ง, ์ต์ ๊ธฐ๋ฅ ์ ํ์ ์ํด์๋ ํ๋ฅญํ๊ฒ ๋์ํ๋ค!

โจ๏ธ ํค๋ณด๋ ๊ธฐ๋ฅ ๊ณ ๋ํ
์ฒ์ง์ธ์ ๋จ์ถํค์ ๊ธฐ์์ ๋๊ณ ์๋ ๋งํผ ๊ด๋ จ๋ ๊ณ ๋ ๊ธฐ๋ฅ๋ค์ด ์๋ค. ๋ฐฑ์คํ์ด์ค ํค๋ฅผ ๊ธธ๊ฒ ๋๋ฅด๋ฉด ๋ ๋๊น์ง ๊ธ์ด ์ญ์ ๋๋ ๊ธฐ๋ฅ์ด๋, ์ ๋ ฅ ํค๋ฅผ ๊ธธ๊ฒ ๋๋ฅด๋ฉด ๊ทธ ๋ฒํผ์ ๋์ํ๋ ์ซ์๊ฐ ์ ๋ ฅ๋๋ ๊ธฐ๋ฅ ๋ค์ด ์๋ค. ์ด ๊ธฐ๋ฅ๋ค์ ์ฌ์ฉํ๊ธฐ ์ํด Swift์ Closure๋ฅผ ํ์ฉํด์ ๋ค์๊ณผ ๊ฐ์ด ํค๋ณด๋ ๋ฒํผ ์ปดํฌ๋ํธ๋ฅผ ํ์ฅํ๋ค.
struct KeyboardButton: View {
var onPress: () -> Void
var onLongPress: () -> Void
var onLongPressFinished: () -> Void
var body: some View {
Button(action: {})
.simultaneousGesture(
DragGesture(minimumDistance: 0) // <-- A
.onChanged { _ in
// ๊ธธ๊ฒ ๋๋ฅด๊ฑฐ๋ ๋๋๊ทธํ์ ๋ ๊ตฌ๋๋ ์ฝ๋
onLongPress()
}
.onEnded { _ in
// ๊ธธ๊ฒ ๋๋ฅด๋ ๋์ ๋๋ ๋๋๊ทธ ๋์์ด ๋๋ ๋
onLongPressFinished()
}
)
.highPriorityGesture(
TapGesture()
.onEnded { _ in
// ํฐ์นํ์ ๋ ๊ตฌ๋๋ ์ฝ๋
onPress()
}
)
}
}
์ค๋ช ์ ์ํด ๊ฐ์ํ๋ ์ฝ๋์ด๋ค. KeyboardButton.swift
A๋ก ํํ๋ ๋ถ๋ถ์ ์ฌ์ฉํ๋ ๊ธฐ๋ฐํ ๋ฐฉ๋ฒ์ ์๊ฒ ๋์๋ค.
์ด๋ ๊ฒ ํ๋ฉด ๋ค์ ๋ ๋ง๋ฆฌ ํ ๋ผ๋ฅผ ํ ์ฝ๋๋ก ์ก์ ์ ์๋ค.
- ํ๊ธ ๋ฒํผ์ ์ค์์ดํ(flick)ํด ์ซ์๋ฅผ ์ ๋ ฅํ๋ ๊ธฐ๋ฅ
- ํ๊ธ ๋ฒํผ์ ๊ธธ๊ฒ ๋๋ฌ ์ซ์๋ฅผ ์ ๋ ฅํ๋ ๊ธฐ๋ฅ
DragGesture์ minimumDistance๊ฐ 0์ผ๋ก ์ค์ ๋์ด ์๋ค๋ฉด ๋กฑํ๋ ์ค๋ ๋์์ ์ธ์ํ์ฌ highPriorityGesture๋ฅผ ์ทจ์ํ๊ณ DragGesture์ ํด๋นํ๋ ๊ธฐ๋ฅ์ ์คํํ๋ค๋ ํน์ง์ ์ด์ฉํ ๊ฒ์ด๋ค.
๋๋ถ์ด iOS13๋ถํฐ ์๊ฐ๋ Combine ๋ฌธ๋ฒ์ ์๋ฒ์ ์ผ๋ก ์ฌ์ฉํด๋ณด์๋ค. Combine ํ๋ ์์ํฌ๋ ์๊ฐ์ ๋ฐ๋ฅธ ๋น๋๊ธฐ์ ๋์์ ์ฒ๋ฆฌํ๊ธฐ ์ํ Declarative Swift API์ด๋ค. ์ด๋ฅผ ์ด์ฉํด ํ์ด๋จธ๋ฅผ ์์ฑํ๊ณ "๋กฑํ๋ ์ค ๋ฐฑ์คํ์ด์ค" ๋์์ ๊ตฌํํ ์ ์๋ค.
struct DeleteButton: View {
@State var timer: AnyCancellable?
var body: some View {
KeyboardButton(systemName: "delete.left.fill", primary: false, action: {
// ํญํ์ ๋๋ ๊ธฐ๋ณธ ์ญ์ ๋์์ ์คํํ๋ค.
options.deleteAction()
},
onLongPress: {
// ๊ธธ๊ฒ ๋๋ฅด๊ณ ์์ ๊ฒฝ์ฐ 0.1์ด๋ง๋ค ์คํ๋๋ ํ์ด๋จธ๋ฅผ ์์ฑํ๋ค.
timer = Timer.publish(every: 0.1, on: .main, in: .common)
.autoconnect()
.sink { _ in
// ๋๋ฅด๊ณ ์๋ ๋์ 0.1์ด์ ํ ๋ฒ์ฉ ๊ธ์ ํ๋๋ฅผ ์ง์ด๋ค.
options.deleteAction()
}
},
onLongPressFinished: {
// ์์ ๋ผ๋ฉด ํ์ด๋จธ๊ฐ ์ทจ์๋๋ฉฐ ๋ฌดํ ๋ฐ๋ณต ์ญ์ ๋์์ด ํด์ ๋๋ค.
timer?.cancel()
})
}
}
์ค๋ช ์ ์ํด ๊ฐ์ํ๋ ์ฝ๋์ด๋ค. HangulView.swift
์ด๋ ๊ฒ ์กฐํฉ๋ ํ๋์ ์ฝ๋๋ฅผ ํตํด ๊ธธ๊ฒ ๋๋ฅด๊ฑฐ๋ ๋๋๊ทธ๋ฅผ ์ด์ฉํด ํน์ํ ๋์์ ์คํํ๋ ๊ธฐ๋ฅ์ ๊ตฌํํ ์ ์์๋ค.
๐ฆพ ์ ๊ทผ์ฑ๊ณผ ์ฌ์ฉ์ฑ
์ ์ฉํ๋ค๊ณ ์๊ฐํ ์ ๊ทผ์ฑ ๊ธฐ๋ฅ์ ๋ช ๊ฐ์ง ์ถ๊ฐํ๋ค. ์ฐ์ ๊ฐ์ฅ ๋จผ์ ์ฌ์ฉ์๊ฐ "๋ณผ๋์ฒด ํ ์คํธ" ๊ธฐ๋ฅ์ ํ์ฑํํ ๊ฒฝ์ฐ ๊ธ์ ๋๊ป๋ฅผ ๋๊ป๊ฒ ๋ณ๊ฒฝํ๋ ๊ฒ์ด๋ค. ๋ค์ ์ฝ๋๋ฅผ ์ด์ฉํด ์ฌ์ฉํ ์ ์๋ค.
let fontWeight: UIAccessibility.isBoldTextEnabled ? .bold : .regular


๋ ๋๋ฆ ํฐ ์๊ฐ์ ๋ฐ์ ๊ธฐ๋ฅ์ด ํ๋๊ฐ ์์๋ค. ๋ฐ๋ก ๊ฐค๋ญ์ ์ฌ์ฉ์๋ค์ด ์ฐ์ธก ํ๋จ์ "์ด์ " ๋ฒํผ์ ๋๋ฌ์ ํค๋ณด๋๋ฅผ ์ข ๋ฃํ๋ค๋ ์ฌ์ค์ ๊ด์ฐฐํ๋ค. ๊ทธ๋์ ๊ทธ ์๋ฆฌ์ ํค๋ณด๋๋ฅผ ์์ฝ๊ฒ ์ข ๋ฃํ ์ ์๋๋ก ํค๋ณด๋ ์ข ๋ฃ ๋ฒํผ์ ๋ฐฐ์นํ๋ค.

๐ง๐ปโ๐จ Midjourney๋ฅผ ์ด์ฉํ ์ฑ ์์ด์ฝ ์์ฑ

์์ฑ๋ ์ฌ๋ฌ ๊ฐ์ง ์ด๋ฏธ์ง๋ค
์ฑ ์์ด์ฝ์ ์์ฑํ๊ธฐ ์ํด Midjourney๋ผ๋ ๊ทธ๋ฆผ AI๋ฅผ ์ฌ์ฉํ๋ค. ์์ฆ์๋ ์ด๋ฐ ๊ฒ์ ํ๋กฌํํธ ์์ง๋์ด๋ง์ด๋ผ๊ณ ํ๋๋ฐ ๊ทธ๋ฅ ๋ค์ํ ํค์๋๋ค๋ก ๊ทธ๋ฆผ์ ๊ทธ๋ฆฌ๋ ๊ฒ์ด ์ฆ๊ฑฐ์ ๋ค.
โ๏ธ Xcode Cloud๋ฅผ ์ด์ฉํ CI/CD ์ฐ๊ฒฐ
๋ง์ง๋ง์ผ๋ก 2022๋ ์ ์ถ์๋ Xcode Cloud๋ฅผ ์ด์ฉํด CI/CD๋ฅผ ๊ตฌ์ถํ๋ค. ์ด๋ฅผ ์ด์ฉํ๋ฉด ๋ง์น GitHub์ ๋ฆฌ์กํธ ์ฝ๋๋ฅผ ํธ์ํ๋ฉด Vercel์ด ์์์ ๋น๋ ํ ๋ฐฐํฌํด์ฃผ๋ ๊ฒ์ฒ๋ผ, Apple Xcode Cloud ์๋ฒ์์ iOS ์ฑ์ด ์ปดํ์ผ๋์ด ๋ณด๊ด๋๋ค. ์ ํ ์์ดํฐ ์ฑ์ ๊ฒฝ์ฐ ์ฑ์คํ ์ด ๋ฆฌ๋ทฐ๋ผ๋ ์ ์ฐจ๊ฐ ์๊ธฐ ๋๋ฌธ์ ์์ ์๋ ๋ฐฐํฌ๊ฐ ๋์ง๋ ์๊ณ , ์ฑ์คํ ์ด ์ฝ์์์ ๋น๋๋ฅผ ์ ํํ๊ณ ๋ฆฌ๋ทฐ ์์ฒญ ๋ฒํผ์ ๋๋ฌ์ผ ํ์ง๋ง, ์ด์ ์ ์์ค์ฝ๋์์ ์์นด์ด๋ธ ํ์ผ์ ์์ฑํด ์๋์ผ๋ก ์ ๋ก๋ํด์ผํ๋ ๊ฒ์ ๋นํด์ ํจ์ฌ ํธํด์ก๋ค.


๐ ๋ง๋ฌด๋ฆฌํ๋ฉฐ
์ค๋๋ง์ iOS ๊ฐ๋ฐ์ ํ๋ ์ฆ๊ฑฐ์ ๋ค. iOS ํ๋ซํผ์ด ํจ์ฌ ์ฑ์ํด์ง ๊ฒ์ด ๋๊ปด์ก๋ค. ํนํ๋ ํ์ ํ๋ก์ ํธ๋ฅผ ์งํํ๋ฉฐ ํ๊ธ์ด ์ด๋ ๊ฒ ์๋ฆ๋ต๊ตฌ๋๋ผ๋ ๊ฐ์ ์ ๋ง์ด ๋๊ผ๋ค. ๋ฌด์๋ณด๋ค๋ ๋ถ๋ชจ๋๊ป ์ฐธ ์ข์ ์ ๋ฌผ์ ํด๋๋ฆฐ ๊ฒ ๊ฐ์ ๊ธฐ๋ถ์ด ์ข์๋ค. ์์ ํ ๋งํฌ๋ค์ ์ฒจ๋ถํ๋ฉฐ ๊ธ์ ๋ง๋ฌด๋ฆฌํ๋ค.