Android๋ 5์ 18์ผ ์ถ์.
iOS๋ 5์ 17์ผ ์ถ์.
๋ฒ์จ ๊ฐ ์คํ ์ด์ ์ฑ์ ์ถ์ํ์ง ํ ๋ฌ์ด ์ง๋ฌ๋๋ฐ, ๊ทธ ๋์ ๊ด๋ฆฌํ๋ฉด์ ์์๋ ํธ๋ฌ๋ธ ์ํ ์ด๋ ์์ฌ์ด ์ ? ๋ฑ... ํ๊ณ ๋ฅผ ํ ๋ฒ ํด๋ณด๋ ค ํ๋ค.
โธ๏ธ ๋ค์ด๊ฐ๊ธฐ ์
๋ณธ๊ฒฉ์ ์ผ๋ก ํ๊ณ ํ๊ธฐ ์ ์, ์ฑ์ ์คํํ๋ ์์ ๊ฐ์ ๊ฑธ ํ ๋ฒ๋ ์ ๋ก๋ํ ์ ์ด ์์ด์ ์ฑ ์คํ ์์๊ณผ ํด๋น ์ฑ์ ์ด๋ค ๊ธฐ๋ฅ์ด ์๋์ง ์๊ฐํ๋ ค ํ๋ค.
์ฑ ๊ธฐ๋ฅ ์ค๋ช
1. ์ฌ์ฉ์๊ฐ ์~๊ธ์์ผ์ ์๋จํ๋ฅผ ์์ ๋กญ๊ฒ ๋ณผ ์ ์๋ ์ข์ฐ ์คํฌ๋กค ๊ธฐ๋ฅ์ด ์๋ค.
2. ์์ผ์ ๋ง๋ ์๋จํ๋ฅผ ๋ฐ๋ก ๋ณด์ฌ์ค ์ ์๋๋ก ๋ฐ๋ก ๊ฐ๊ธฐ ๊ธฐ๋ฅ์ด ์๋ค.
์๋ฅผ ๋ค๋ฉด, ์ค๋์ด ํ์์ผ์ด๋ผ๋ฉด ์ฌ์ฉ์๊ฐ ์ง์ ์คํฌ๋กคํ์ง ์์๋, ์๋์ผ๋ก ํ์์ผ ์๋จํ๋ก ๋์ด๊ฐ ๋ณด์ฌ์ฃผ๋๋ก ํ๋ ๊ธฐ๋ฅ์ด๋ค.
(์ฃผ๋ง์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ, ์์์ผ์ ์์นํ๋๋ก ํ์๋ค.)
iOS ์ฑ ์คํ ์์ & Android ์ฑ ์คํ ์์
๐ฅ AWS
Amazon S3 : ์ด๋ฏธ์ง ์ ๋ก๋ ์๋ํ?
์๋จํ ์ด๋ฏธ์ง๋ฅผ ๋ฒํท์ ์ ๋ก๋ํ๋ฉด, ์๋์ผ๋ก Lambda ํจ์์์ ํด๋น ์ด๋ฏธ์ง๋ฅผ ์ฝ์ด์ OCR์ ์งํํ๊ฒ ๋๋ค.(ํธ๋ฆฌ๊ฑฐ)
์ด๋๋ง ๋ฉ๋ด ์ด๋ฏธ์ง๋ฅผ ์ ์ฅํ๋ ๋ฒํท์ 5์ ์ฒซ์งธ ์ฃผ ์ด๋ฏธ์ง๋ถํฐ 6์ ๋ท์งธ ์ฃผ ์ด๋ฏธ์ง๊น์ง ์ ๋ก๋๋ฅผ ์งํํ๋ค.
์ฆ, ๋ฒ์จ 9์ฃผ์ฐจ๋ฅผ ์ฌ๋ฆฐ ๊ฑด๋ฐ ๋งค์ฃผ ์ฃผ๋ง์ ๊น๋จน์ง ์๊ณ ์ ๋ก๋ ํ๋ ๊ฒ์ ์์ง ์๊ณ ์๋ค.
๊พธ์คํ ํ๋ ๊ฑธ ์ด๋ ค์ ํ๋ ๋ด๊ฐ, ๊น๋จน์ง ์๊ณ ๋ถ์ง๋ฐํ ์ ์งํ๋๊ณ ์๋ ์ ์ ๋คํ์ธ ๊ฒ ๊ฐ๋ค.
๊ทธ๋ ๋ค๋ฉด ์ด๋ ๊ฒ ๊ณ์ ์ฌ๋์ด ๋งค์ฃผ ์ผ์ผ์ด ๋ฃ์ด ์ฃผ๋ ๋ฐฉ๋ฒ ๋ง๊ณ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ ์์๊น?
"ํฌ๋กค๋ง์ ํตํด ์ด๋ฏธ์ง๋ฅผ ๋ฐ์์ S3์ ์ ์ฅํ๋ ๋ฐฐ์น ํ์ดํ๋ผ์ธ์ ๋ง๋ค๋ฉด ํด๊ฒฐํ ์ ์์ํ ๋ฐ"
์... ์๊ฐ๋ณด๋ค ์ด ๋ฐฉ๋ฒ์ ์ข ๊น๋ค๋กญ๋ค. ๋ ์ ํํ ๋งํ๋ฉด ๋ด ์๋น์ค์ ์ ์ฉํ๊ธฐ ์ด๋ ต๋ค? ์ ์ฉํ๋ ค๋ฉด ์ ์ฒด์ ์ธ ๊ตฌ์กฐ ์์ ์ด ์ผ์ด๋์ผ ํ๋ค.
์ฐ์ , ์๋จํ ์ฌ์ง ๊ฐ์ ๊ฒฝ์ฐ์๋ '๋ฉ๊ฐ์คํฐ๋ ๊ตฌ๋ด์๋น ๋ฉ๋ดํ' ์นดํ ๊ณ ๋ฆฌ์ ๋งค์ฃผ ํ ๋ฒ์ฉ ์ ๋ฐ์ดํธ ๋๋ค.
ํญ์ ๊ณ ์ ์ ์ธ url์ ์ ๋ก๋๊ฐ ๋๋ฏ๋ก, ํด๋น ์ด๋ฏธ์ง๋ฅผ ๊ฐ์ ธ์ค๋ ๊ฒ์ ์ด๋ ต์ง ์๋ค.
๊ทธ๋ฌ๋ ๋ฌธ์ ๋ ์ค๋ฅธ์ชฝ ์ฌ์ง์ฒ๋ผ ์ด๋ฏธ์ง์ ํฌ๊ธฐ๋ ์์น๊ฐ ํญ์ ๋ฐ๋๋ค๋ ์ ์ด๋ค.
ํฌ๋กค๋ง์ ํตํด ํด๋น ์ด๋ฏธ์ง๋ฅผ ๊ฐ์ ธ์์ S3์ ์ ์ฌํ๋๋ก ํ ์๋ ์์ง๋ง, ์์์ ์ธ๊ธํ ๋ฌธ์ ๋ก ์ธํด OCR ์ธ์์์ ๋ฌธ์ ๊ฐ ์๊ธด๋ค.
ํ์ฌ OCR ์ํ ์ธ์ ํํ๊ฐ ์ด๋ฐ ์์ธ๋ฐ, ๋ด๊ฐ ๋ฑ๋กํ ์ํ ์ด๋ฏธ์ง๊ฐ ์ ์ฌ ๋ฉ๋ด๋ง ์ ํ ์์ ํ ์ด๋ฏธ์ง์ด๋ฉด์, ์ธ์ํ ์์ญ์ ์ง์ ๋ฃ์ด์ค ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ์ด๋ฏธ์ง์ ํฌ๊ธฐ์ ์ํฅ์ ๋ง์ด ๋ฐ๋๋ค๋ ๊ฒ์ด๋ค.
๊ทธ๋ฆฌ๊ณ ๋ฐฐ์น ์ฒ๋ฆฌ ํ์ดํ๋ผ์ธ ์ญํ ์ ํ๋ airflow ๊ณต๋ถ๊ฐ ์์ง ๋ถ์กฑํ๊ธฐ๋ ํ๊ณ , ์ ๊ธฐ์ ์ผ๋ก airflow๋ฅผ ์คํ์ํฌ ์ ์๋ ํ๊ฒฝ์ ๋ถ์ฌ?
๋ณตํฉ์ ์ธ ์์ธ๋ค์ ์ฝํ์๊ณ , ๋น ๋ฅด๊ฒ ๊ฐ๋ฐํ๋ ๊ฒ์ด ๋ชฉํ์๊ธฐ์ ์ด๋ฌํ ๋ถ๋ถ์ ์ ์ฉํ์ง ๋ชปํ๊ฒ ์์ฝ๋ค.
(ํ๋ ค๋ฉด ํ ์ ์์ ๊ฒ ๊ฐ์๋ฐ ์ฐ์ ์์ ๊ฐ๋ฐ์ ๋ฐ๋ฆฌ๊ธฐ๋ ํ๊ณ , ์ ๋๋ก ๊ณต๋ถํ๋ฉด์ ์ฒ์ฒํ ํ๊ณ ์ถ์ด์ ์๋ง ์ถํ์ ๊ฐ์ ํ๊ฒ ๋ ๋ถ๋ถ์ผ ๊ฒ ๊ฐ๋ค.)
AWS Lambda : DB ์ฝ๊ธฐ ๋ฐ ์ฐ๊ธฐ ์๋ํ?
๋งค์ฃผ ์ด๋ฏธ์ง๋ฅผ S3์์ ํน์ ํ์ผ์ ์ฝ์ด์ค๊ธฐ ์ํด, ํ์ผ ์ด๋ฆ์ ๋งค๋ฒ ์ง์ ์์ ํด์ฃผ๊ณ ์๋ค.
์๋ง ์ด ๊ณผ์ ๋ airflow์์ ํ์ผ ์ด๋ฆ์ ๋ณ๊ฒฝํด์ฃผ๋ ํจ์ ํ๋, ๋ ์ง ์ด๋ฆ์ ๋ณ๊ฒฝํด์ฃผ๋ ํจ์ ํ๋๋ฅผ ๊ฐ๊ฐ ๋ง๋ค์ด์ ์๋ํํ ์ ์์ ๊ฒ ๊ฐ๋ค.
AWS Lambda : DB ์ฐ๊ธฐ ๋ฐ๋ณต ๋ฌธ์
์ ๋ฒ์๋ ์ด ํ์์ด ๋ฐ์ํด์ Lambda ํจ์๋ฅผ ์์ ํด์ฃผ์๋๋ฐ, ๊ทธ ๋ ์์ฑํ ๋ก์ง์ด ์๋ชป๋์์์ ๊นจ๋ฌ์๋ค.
### ์ด์ ์๋ต ###
try:
r = table.get_item(
Key={
'Period': {'S': period}
}
)
# ์ด๋ฏธ ํด๋น ํค ๊ฐ ๋ฐ์ดํฐ๊ฐ ์กด์ฌํ๋ ๊ฒฝ์ฐ, Lambda ํจ์ ์ข
๋ฃ
if 'Item' in r:
return {
'statusCode': 200,
'body': '์ด๋ฏธ Key๊ฐ ์กด์ฌํ์ฌ Lambda ํจ์๋ฅผ ์ข
๋ฃํฉ๋๋ค.'
}
except:
# dynamoDB ํ
์ด๋ธ์ ์๋ก ๋ฐ์ดํฐ ์ ์ฅํ๋ ๋ก์ง
### ์ดํ ์๋ต ###
์์๊ฐ ์ด์ ์ฝ๋์ธ๋ฐ, table์์ ํค๊ฐ 'Period' ์ด๋ฉด์ period ์ ํด๋นํ๋ ๊ฐ๋ค์ ๊ฐ์ ธ์ค๋๋ก(=r) ๋์ด์๋ค.
์ด์ํ๊ฒ ํด๋น ๋ก์ง์์ ๊ณ์ except๋ก ๊ฐ์ ๊ณ์ DB์ ๋ฐ์ดํฐ๊ฐ ์์ด๊ฒ๋ ๋์๋๊ณ ์์๋ค.
get_item ๋ฉ์๋์์ ์๊พธ ์๋ฌ๊ฐ ๋ฐ์ํ๋ ๊ฒ์ด๋ผ ํ๋จํ๋ค.
์ฐพ์๋ณด๋ ์ฌ๊ธฐ์ Key์ ํํฐ์ ํค ๋ฟ ๋ง ์๋๋ผ, ์ ๋ ฌ ํค๋ ๋ฃ์ด์ค์ผ ํด๊ฒฐ๋๋ ๊ฒ ๊ฐ๋ค.
๊ทธ๋ฌ๋ ๋ด๊ฐ ์๋ํ ๋ก์ง๊ณผ๋ ๋ฌ๋ผ์, ํํฐ์ ํค๊ฐ๋ง ์ฐพ๋ ๋ฉ์๋๋ก ์์ ํด ๋ก์ง์ ๋ค์ ์์ฑํ๋ค.
### ์ด์ ์๋ต ###
partition_key_name = "Period"
partition_key_value = period
try:
# ์ค์บ ์์
์ผ๋ก ํํฐ์
ํค ๊ฐ ํ์ธ
response = table.scan(
FilterExpression=f"#{partition_key_name} = :value",
ExpressionAttributeNames={f"#{partition_key_name}": partition_key_name},
ExpressionAttributeValues={
":value": partition_key_value
}
)
# ํญ๋ชฉ์ด ์กด์ฌํ๋์ง ํ์ธ
items = response['Items']
if len(items) > 0:
print(f"ํํฐ์
ํค ๊ฐ '{partition_key_value}'์(๋ฅผ) ๊ฐ์ง ํญ๋ชฉ์ด ํ
์ด๋ธ์ ์กด์ฌํฉ๋๋ค.")
else:
print(f"ํํฐ์
ํค ๊ฐ '{partition_key_value}'์(๋ฅผ) ๊ฐ์ง ํญ๋ชฉ์ด ํ
์ด๋ธ์ ์กด์ฌํ์ง ์์ต๋๋ค.")
idx = 0
for item in res_data[1:]:
table.put_item(
# ์์ผ๋ช
, ๋ฉ๋ด๋ด์ฉ
Item={
'Period': period,
'Menu': re.sub(pattern, r'\1 \2', str(idx) + " " + item['inferText'])
}
)
print(f"Data inserted successfully: {item['inferText']}")
idx += 1
except Exception as e:
print("์ค๋ฅ ๋ฐ์:", str(e))
ํ ์ด๋ธ scan ๋ฉ์๋๋ก ํด๋น ํํฐ์ ํค ๊ฐ์ ๋ฐ์ดํฐ๊ฐ ์กด์ฌํ๋ค๋ฉด, ํด๋น ๋ฐ์ดํฐ๊ฐ ์ด๋ฏธ ์ ๋ค์ด๊ฐ ์์ผ๋ฏ๋ก ๋์ด๊ฐ๊ณ , ์๋ ๊ฒฝ์ฐ์๋ ๋ฐ์ดํฐ๋ฅผ ๋ฃ์ด์ฃผ๋ ๋ก์ง์ผ๋ก ๋ฐ๊ฟจ๋ค.
์ด๋ ๊ฒ ์ ๊ฒํ๋ ๊ณผ์ ์ด ํ์ํ๋ ์ด์ ๋, DynamoDB์ ๋ค์ด๊ฐ๋ ๋ฐ์ดํฐ๋ค์ OCR ์ธ์ ๊ฒฐ๊ณผ๊ฐ์ด ๋ฐ๋ก ๋ค์ด๊ฐ๋๋ฐ, ์ด๋ ๊ฐ๋ ์ข ์ข ์ธ์์ ๋ชปํ๋ ํ์ ๊ฐ์ ๊ฒฝ์ฐ์๋ ์ง์ ์์ ํด์ ๋ฃ์ด์ฃผ์ด์ผ ํ๊ณ , ๊ทธ๋ฆผ์ด ์๋ ๊ฒฝ์ฐ ์ด์ํ ๋ฌธ์๋ก ์ธ์๋์ด ์ง์์ค์ผ ํ๋ค.
ํด๋น ๋ฐ์ดํฐ๋ฅผ ์์ ํด์ฃผ๋ฉด, ์๊น ๊ณ ์น๊ธฐ์ ๋ฐ์ดํฐ๊ฐ ๊ณ์ ์๊ฒผ๋ค. (์ด์ Lambda ํจ์ ๋ก์ง์์ ์ค๋ช ํ ์ด์ ๋๋ฌธ์)
๋ก์ง์ ์ ๋๋ก ์์ ํด์ค ๋๋ถ์, DynamoDB์ ๋ค์ด๊ฐ ๋ฐ์ดํฐ๋ฅผ ์์ ํด์ฃผ์ด๋ ๋์ด์ ๋ฐ๋ณตํด์ ๋ฐ์ดํฐ๊ฐ ๋ค์ด๊ฐ์ง ์์๋ค.
๐ฑ Android & iOS
๋ฐฑ๊ทธ๋ผ์ด๋ ์คํ์ ์๋ ์ ๋ฐ์ดํธ
Android๋ ์์ง ํ์ธ์ ๋ชปํ๋๋ฐ, iOS ๊ฐ์ ๊ฒฝ์ฐ์๋ ๋ฐฑ๊ทธ๋ผ์ด๋์์ ์คํํด๋๊ณ ์ฑ์ ์ข ๋ฃํ์ง ์์ผ๋ฉด ๋ฉ๋ด ์ ๋ฐ์ดํธ๊ฐ ๋์ง ์๋ ํ์์ด ์๋ค.
์๋ง ์๋๋ ๋ง์ฐฌ๊ฐ์ง์ผ ๊ฒ ๊ฐ์๋ฐ ํด๋น ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์๋ ์ฝ๋ ์์ ์ ํด์ ์๋ ๋ฐ ios ์ฑ ๋ฒ์ ์ ๊ทธ๋ ์ด๋๋ฅผ ์์ผ์ค์ผํ ๊ฒ ๊ฐ๋ค.
iOS
๋จผ์ iOS ๊ฐ์ ๊ฒฝ์ฐ,
1. Info.plist ํ์ผ์ ๋ฐฑ๊ทธ๋ผ์ด๋ ์์ ํ์ฉ์ ์ํ ์ค์ ์ ์ถ๊ฐํด์ผ ํ๋๋ฐ, UIBackgroundModes ํค๋ฅผ ์ถ๊ฐํ๊ณ fetch ๊ฐ์ ์ค์ ํด์ผ ํ๋ค.
2. ๋ฐฑ๊ทธ๋ผ์ด๋ ์์ ์ ์ฒ๋ฆฌํ๊ธฐ ์ํด AppDelegate ํด๋์ค์์ application(_:performFetchWithCompletionHandler:) ๋ฉ์๋๋ฅผ ๊ตฌํํด์ผ ํ๋ค.
3. ์ฑ์์ ๋ฐฑ๊ทธ๋ผ์ด๋ ์์ ์ ์ํํ๋๋ก, ์ฑ ๋ด์์ ๋ฐฑ๊ทธ๋ผ์ด๋ ์์ ์ ์์ํ๋ ค๋ ์ง์ ์์ UIApplication.shared.setMinimumBackgroundFetchInterval(_:) ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ ๋ฐฑ๊ทธ๋ผ์ด๋ ์์ ์ ์ต์ ๊ฐ๊ฒฉ์ ์ค์ ํ๋ค.
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// ๋ฐฑ๊ทธ๋ผ์ด๋ ์์
์ ์ต์ ๊ฐ๊ฒฉ ์ค์ (์: 15๋ถ)
application.setMinimumBackgroundFetchInterval(900) // 900์ด = 15๋ถ
return true
}
func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
// ๋ฐฑ๊ทธ๋ผ์ด๋ ์์
์ํ (๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ ๋ฐ ์
๋ฐ์ดํธ)
// completionHandler๋ฅผ ํธ์ถํ์ฌ ์์
์๋ฃ๋ฅผ ์์คํ
์ ์๋ฆผ
// ์์
๊ฒฐ๊ณผ์ ๋ฐ๋ผ .newData, .noData, .failed ์ค ํ๋๋ฅผ ์ ํ
completionHandler(.newData)
}
}
Android
์๋๋ก์ด๋๋ ๋ง์ฐฌ๊ฐ์ง.
1. ๋ฐฑ๊ทธ๋ผ์ด๋์์ ์คํ๋ ์๋น์ค(๋ฐฑ๊ทธ๋ผ์ด๋ ์์ ์ ์ํํ ์ ์๋ ์ปดํฌ๋ํธ)์ธ Service ํด๋์ค๋ฅผ ์์๋ฐ๋ ํด๋์ค๋ฅผ ์์ฑํ์ฌ ๋ฐฑ๊ทธ๋ผ์ด๋ ์์ ์ ๊ตฌํํด์ผ ํ๋ค.
2. ์๋ ๋งค๋์ ๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐฑ๊ทธ๋ผ์ด๋ ์์ ์ ์ฃผ๊ธฐ์ ์ผ๋ก ์คํํ๋๋ก ์ค์ ํ๋ค. AlarmManager ํด๋์ค๋ฅผ ์ฌ์ฉํ์ฌ ์๋์ ์์ฝํ๊ณ , PendingIntent๋ฅผ ํตํด ๋ฐฑ๊ทธ๋ผ์ด๋ ์๋น์ค๋ฅผ ์คํํ๋ค.
3. ์ฑ์ด ์์๋ ๋ ๋ฐฑ๊ทธ๋ผ์ด๋ ์๋น์ค๋ฅผ ์คํํ๋๋ก ์ค์ ํ๋ค. onCreate() ๋ฉ์๋๋ ๋ค๋ฅธ ์ ์ ํ ์์ ์์ startService()๋ฅผ ํธ์ถํ์ฌ ๋ฐฑ๊ทธ๋ผ์ด๋ ์๋น์ค๋ฅผ ์คํํ๋ค.
// ๋ฐฑ๊ทธ๋ผ์ด๋ ์๋น์ค ์์ฑ
public class MyBackgroundService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// ๋ฐฑ๊ทธ๋ผ์ด๋ ์์
์ํ
// ...
// ๋ฐฑ๊ทธ๋ผ์ด๋ ์์
์ด ์๋ฃ๋๋ฉด ์๋น์ค ์ข
๋ฃ
stopSelf();
return START_NOT_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
// ์๋ ๋งค๋์ ์ค์
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, MyBackgroundService.class);
PendingIntent pendingIntent = PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
long intervalMillis = 15 * 60 * 1000; // 15๋ถ
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), intervalMillis, pendingIntent);
// ๋ฐฑ๊ทธ๋ผ์ด๋ ์๋น์ค ์คํ
Intent serviceIntent = new Intent(this, MyBackgroundService.class);
startService(serviceIntent);
๋ด๊ฐ ๋ง๋ ์๋น์ค์ ์ ์ฉํ๋ ค๋ฉด ์ฌ์ค ์ด๋ป๊ฒ ํด์ผํ ์ง ๊ฐ์ด ์ ์์จ๋ค. api๋ฅผ ํตํด ์ฃผ๊ธฐ์ ์ผ๋ก ๋ฐ์์ค๊ธฐ๋ง ํ๋ฉด ๋ ์ง? ์๋๋ฉด ํ๋ฉด ๊ด๋ จํ ์ธํ ๊น์ง ํด์ผํ ์ง...์ง์ ํด๋ณด๋ค๊ฐ ๋๋ฌด ๋งํ๋ค ์ถ์ผ๋ฉด ์ปค๋ฎค๋ํฐ์ ์ฌ์ญค๋ด์ผ ํ ๊ฒ ๊ฐ๋ค.
๊ฐ๋ก๋ชจ๋ ์ง์ X
ํ๋ฉด์ ๊ฐ๋ก๋ชจ๋, ์ธ๋ก๋ชจ๋๋ฅผ ๋ฏธ์ณ ์๊ฐํ์ง ๋ชปํ๋ค.
๋๋ฌด๋ ๋น์ฐํ๊ฒ ์ธ๋ก๋ชจ๋์ ๋ง๊ฒ ๊ตฌํํ๋ค.
์ธ๋ก๋ชจ๋๋ง ์ง์ํ๋๋ก ์ค์ ํ๊ฑฐ๋, ๊ฐ๋ก๋ชจ๋๊น์ง ์ง์ํ์ฌ ๋ง๋ค์์ด์ผ ํ๋๋ฐ ์ฑ ๊ฐ๋ฐํ๋ฉด์ ์ด ๋ถ๋ถ์ ๊ทธ๋์ ์ ํ ๊ณ ๋ คํ์ง ๋ชปํ๋ ๊ฒ ๊ฐ๋ค.
Android
์๋๋ก์ด๋ ๊ฐ์ ๊ฒฝ์ฐ, ์ธ๋ก ๊ณ ์ ์ ํด์ฃผ๋ ค๋ฉด ๋ ๊ฐ์ง ๋ฐฉ๋ฒ์ด ์๋ค.
1. AndroidManifest.xml ์ค์
android:screenOrientation์ portrait, ๋๋ landscape๋ก ์ค์ ํ๋ค.
<activity
android:screenOrientation="portrait"></activity>
2. Source code ์ค์
SCREEN_ORIENTATION_LANDSCAPE, ํน์ SCREEN_ORIENTATION_PORRAIT๋ก ์ค์ ํ๋ค.
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
setContentView(R.layout.main);
// ์ดํ ์๋ต
}
iOS
iOS๋ ๋ง์ฐฌ๊ฐ์ง๋ก ๋ ๊ฐ์ง ๋ฐฉ๋ฒ์ด ์๋ค.
1. AppDelegate ์ค์
UIInterfaceOrientationMask๋ ๋ทฐ ์ปจํธ๋กค๋ฌ์ ์ง์๋๋ ์ธํฐํ์ด์ค ๋ฐฉํฅ์ ์ง์ ํ๋ ์์์ด๋ค.
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return UIInterfaceOrientationMask.portrait
}
2. ํ๋ก์ ํธ ์ค์ ๋ณ๊ฒฝ
Targets - Info - Supported interface orientations(iPhone)์์ ์ข์ฐ ํ์ ์ ์ญ์ ํ๋๋ก ํ๋ค.
(Xcode์ค๋ฅ๋ก ์ธํด ์ด ๋ฐฉ๋ฒ์ผ๋ก ์งํํด๋ ์๋๋ ์ด์๊ฐ ์๋ค๊ณ ํ๋ 1๋ฒ ๋ฐฉ๋ฒ์ผ๋ก ํ๋ ๊ฒ์ด ๋ ์ข์ ๊ฒ ๊ฐ๋ค.)
Splash(Launch) Screen ๋ฌธ์
์๋๋ก์ด๋ ๊ฐ์ ๊ฒฝ์ฐ, ์๋ ์ฒ๋ผ ์ด์ค ์คํ๋์ ํ๋ฉด์ด ๋ฌ๋ค๊ณ ํ๋๋ฐ ์๋ง ๋ก๋ฉ ํ๋ฉด ์ดํ์ ๊ณ์ ๋น ๋ก๋ฉ ํ๋ฉด์ด ๋จ๊ฑฐ๋ ๋ค๋ฅธ ์คํ๋์ ํ๋ฉด์ด ๋ฌ๋ค๋ ๊ฒ์ ์๋ฏธํ๋ ๊ฒ ๊ฐ๋ค.
์๋๋ก์ด๋ ๋ฟ๋ง ์๋๋ผ, iOS์์๋ ๊ฐ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ ๊ฒ ๊ฐ๋ค.
๐ฌ ๋ง๋ฌด๋ฆฌ
ํ์คํ ์ฑ ๊ฐ๋ฐ์ ์ ํํ๊ฒ ์ดํดํ์ง ๋ชปํ๊ณ ์งํํ ์ , ์ธ๋ฐํ ๋ถ๋ถ์ ์ ๊ฒฝ์ฐ์ง ๋ชปํ๋ ์ ๋ค์ด ๋ค ๋๋ฌ๋ ๊ฒ ๊ฐ๋ค.
์ด๋ฐ ๋ถ๋ถ์ ์ ๋๋ก ๋ฐฐ์ธ ์ ์๋ ๊ธฐํ๊ฐ ์ค๋ฉด ์ข์ ๊ฒ ๊ฐ์๋ฐ...๋๋ฌด ์ด๊ฒ ์ ๊ฒ ๋คํ๊ณ ์ถ์ดํ๋ ๋์ ์์ฌ๋ง ๊ฐ๋ํ๊ฐ ์ถ๊ธฐ๋ ํ๋ค.
๋ ๋์ ์ฌ๋์ด ๋๊ธฐ ์ํด์๋ ๊ณ์ ๋์์์ด ํ๊ตฌํ๊ณ ๊ณต๋ถํ๊ณ ๊ณ ๋ฏผํ๋ ์ฌ๋์ด์ด์ผ ํ๋ค.
์๊ฐ์ ์ฌ์ ๊ฐ ์๊ธฐ๊ฒ ๋๋ค๋ฉด ์ฑ์ ์ ์ฒด์ ์ผ๋ก ์ ๋ฐ์ดํธ ํ๊ณ , ์ฑ ๋ฒ์ ๊ด๋ฆฌ๋ฅผ ํด์ผ๊ฒ ๋ค!
'๊ฐ๋ฐ ์ผ์ง > [๊ตฌ๋ด์๋ฅ]' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
๊ตฌ๋ด์๋น ์๋จํ ์ ํ๋ฆฌ์ผ์ด์ ๊ฐ์ , ์ฑ ์ถ์๊น์ง (1) | 2023.06.11 |
---|---|
AWS Lambda ๋ฐ S3, Naver OCR ๋ก ์๋จํ ์ ํ๋ฆฌ์ผ์ด์ ๋ง๋ค๊ธฐ (0) | 2023.04.01 |