일반적으로 iOS에서 문자열 관리는 .strings 파일을 통해 관리를 하고 있다고 생각하고 있습니다. 하지만 프로젝트 디렉토리 안에 파일로 존재한다면 앱 내부의 문자열 수정은 반드시 개발자의 손을 타게 되는 것 같습니다. 문자열을 프로젝트 내부가 아닌 Google Spread sheet로 추출해서 관리할 수 있다면 기획자, 디자이너 혹은 프로젝트에 참여중인 다른 멤버들의 문자열 접근이 손쉬워지고 개발자는 잔 작업을 줄일 수 있습니다. 사실 개발 중간 들어오는 간단한 문자열 수정이 들어오면 물론 손쉽게 변경할 순 있겠지만.. 개발 흐름을 깰 경우도 많이 있는 것 같아요.. 흐름 깨는 일이 없다면 개발자는 개발에 좀 더 집중을 할 수도 있을 것 같다는 생각이 들어서 문자열 파일을 Google Sheet로 빼서 관리하도록 하겠습니다.
프로젝트 설정
1. Google Sheet 생성
드라이브에 Spread sheet를 하나 생성하고 아래와같은 형태로 셀을 구성합니다.
저는 시트를 하나 생성하고 총 3개의 컬럼 screen, key, kr을 만들었습니다.
screen: 어떤 화면에서 쓰이는 문구인지를 직관적으로 파악하기 위해 화면 이름을 적는 필드
key: .strings파일에서 사용되는 key값
kr: .strings파일에서 사용되는 value값
사실 .strings파일을 만드는데에는 key, kr필드만 필요합니다. screen필드는 옵션으로 생성한 필드라 반드시 필요한 필드는 아닙니다!
위와 같은 형태로 시트를 만들었으면 시트는 완성입니다! (나중에 시트 URL이 필요합니다.)
2. 스크립트 작성
스크립트는 Python으로 되어있어서 코드로 그냥 올려버리겠습니다 ㅋㅋ
아래 파일을 만들어서 프로젝트 안에 script라는 디렉토리를 만들고 그 안에 저장하였습니다.
스크립프 파일 안에 gdoc_id변수 안에는 본인이 생성한 google sheet URL의 뒷부분을 복사해서 넣어주시면 됩니다.
https://docs.google.com/spreadsheets/d/1H9mj8a4U5mzdn7n_bXy_jxzMOTeRfu41Piwkl6B2mIY/edit#gid=0
빨간색으로 칠해진 부분만 넣어주시면 됩니다.
문자열 다운로드 python 스크립트 보기
string_resource.py
import os
import sys
import urllib
import csv
reload(sys)
sys.setdefaultencoding('utf-8')
gdoc_id = "google_spread_sheet_id"
def get_gdoc_information():
download_path = sys.argv[1]
try:
csv_file = export_csv_from_sheet(gdoc_id)
string_list = get_strings_from_csv(download_path, csv_file)
write_strings(string_list, download_path)
except Exception as e:
print(":::::::::::::ERROR:::::::::::::")
print(e)
def export_csv_from_sheet(gdoc_id, download_path=None, ):
print("Downloading the CVS file with id %s" % gdoc_id)
resource = gdoc_id.split('/')[0]
tab = gdoc_id.split('#')[1].split('=')[1]
resource_id = 'spreadsheet:' + resource
if download_path is None:
download_path = os.path.abspath(os.path.dirname(__file__))
file_name = os.path.join(download_path, '%s.csv' % (resource))
print('download_path : %s' % download_path)
print('Downloading spreadsheet to %s' % file_name)
url = 'https://docs.google.com/spreadsheet/ccc?key=%s&output=csv&gid=%s' % (resource, tab)
urllib.urlretrieve(url, file_name)
print("Download Completed!")
return file_name
def get_strings_from_csv(savepath, file_name):
print("read CSV file : %s" % file_name)
source_csv = open(file_name, "r")
csv_reader = csv.reader(source_csv)
header = csv_reader.next()
index_key = header.index("key")
index_kr = header.index("kr")
string_list = []
# Loop through the lines in the file and get each coordinate
for row in csv_reader:
key = row[index_key]
kr = row[index_kr]
dict_string = {
"key": key,
"kr": kr
}
string_list.append(dict_string)
source_csv.close()
os.remove(file_name)
return string_list
def write_strings(string_list, save_path):
if not os.path.exists(save_path + "/en.lproj/"):
os.makedirs(save_path + "/en.lproj/")
string_file = open(save_path + "/en.lproj/Localization.strings", "w")
for item in string_list:
string_file.write("\"" + item["key"] + "\" = \"" + item["kr"] + "\";\n")
string_file.close()
if __name__ == '__main__':
get_gdoc_information()
3. Xcode 스크립트 설정하기
Xcode에서 빌드할 때마다 위에서 작성한 Python스크립트를 실행하도록 설정해줍시다.
설정을 하게되면 빌드할 때마다 Google Sheet에서 문자열을 가져와서 업데이트를 해주는 방식이 되겠죠?
Navigator > 프로젝트 선택 > 타겟 프로젝트 선택 > Build Phases > + 버튼 > New Run Script Phase를 눌러 스크립트 만들기를 하고 쉘명어로 아래와 같이 입력해주세요. 파이썬 파일을 실행하겠다는 의미입니다.
python $TARGET_NAME/script/string_resource.py $TARGET_NAME
설정이 완료되었으면 빌드를 한번 해주세요! 빌드하게되면 프로젝트 폴더에 en.lproj폴더와 그안에 Localizations.strings파일이 생겼을 겁니다. 정상적으로 파일이 생성되었다면 설정이 제대로 되었다는 뜻 입니다!
4. Localized 설정
프로젝트 디렉토리에 en.lproj/Localizations.strings파일이 생겼으면 해당 파일을 Xcode에서도 보기위해 드래그앤드랍으로 XCode에 끌어다 놓아줍시다.
Xcode에 끌어다 놓고 프로젝트 > Info > Localization에 들어가면 English - 1 File Localized로 변경되어있을 겁니다. 우리가 영어버전의 .strings파일을 만들어놓았기 때문에 1File로 보여집니다.
스크립트를 통해서 생성된 Localizations.strings파일도 확인해보면 시트에 있는 형태 그대로 생성된 것을 확인할 수 있습니다!!
결론
간단한 Python 스크립트를 사용해 빌드할 때 Google Spread Sheet에 있는 문자열들을 .strings파일로 변경하게 하였습니다. 이를 통해 Xcode에서 사용되는 문자열관리를 Google Spread Sheet를 통해 할 수 있게 되었습니다. 덕분에 다른 개발자 뿐만 아니라 기획자, 디자이너들에게도 접근성이 좋아졌습니다! 또한 다국어를 지원할 경우에도 유용하게 사용될 수 있을거라 생각이됩니다.
'iOS' 카테고리의 다른 글
📱[RxSwift + Alamofire] API Mocking 하기 (0) | 2021.02.10 |
---|---|
📱Swift Struct vs Class : Class 안에 Struct가 있으면 어떻게 복사될까 (0) | 2020.08.28 |
📱RxSwift + MVVM 패턴 iOS에 적용해보기 (간단한 로그인 화면) (0) | 2020.08.02 |
📱Github action을 사용해서 iOS프로젝트 자동으로 테스트시키기 (0) | 2020.07.30 |
📱iOS 인스타그램 API로 내 포스트 가져오기 (Alamofire API) (0) | 2020.07.29 |