├── generate.py └── README.md /generate.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import urllib 4 | import importlib 5 | import csv 6 | 7 | 8 | reload(sys) 9 | 10 | gdoc_id = "1WMnHk1brX7CR34hCN88cDnTDc4UgTAKh-qegwnPIqCU/edit#gid=0" 11 | 12 | 13 | def get_gdoc_information(): 14 | download_path = sys.argv[1] 15 | try: 16 | csv_file = export_xlsx_from_sheet(gdoc_id) 17 | string_list = get_strings_from_csv(download_path, csv_file) 18 | for string in string_list.items(): 19 | write_strings(string[0], string[1]) 20 | 21 | except Exception as e: 22 | print(":::::::::::::ERROR:::::::::::::") 23 | print(e) 24 | 25 | 26 | def export_xlsx_from_sheet(gdoc_id, download_path=None, ): 27 | print("Downloading the XLSX file with id %s" % gdoc_id) 28 | 29 | resource = gdoc_id.split('/')[0] 30 | resource_id = 'spreadsheet:' + resource 31 | 32 | if download_path is None: 33 | download_path = os.path.abspath(os.path.dirname(__file__)) 34 | 35 | file_name = os.path.join(download_path, '%s.csv' % (resource)) 36 | 37 | print('download_path : %s' % download_path) 38 | print('Downloading spreadsheet to %s' % file_name) 39 | 40 | url = 'https://docs.google.com/spreadsheet/ccc?key=%s&output=csv' % ( 41 | resource) 42 | urllib.urlretrieve(url, file_name) 43 | 44 | print("Download Completed!") 45 | 46 | return file_name 47 | 48 | def get_strings_from_csv(savepath, file_name): 49 | print("read CSV file : %s" % file_name) 50 | 51 | source_csv = open(file_name, "r") 52 | csv_reader = csv.reader(source_csv) 53 | header = next(csv_reader) 54 | categories = ["Text", "Color", "Image", "Storyboard", "Xib"] 55 | categoryIndex = [] 56 | string_list = {} 57 | next(csv_reader) 58 | 59 | for category in categories: 60 | string_list[category] = [] 61 | categoryIndex.append(header.index(category)) 62 | 63 | 64 | for row in csv_reader: 65 | for index in categoryIndex: 66 | key = row[index] 67 | value = row[index + 1] 68 | 69 | dict_string = { 70 | "key": key, 71 | "value": value 72 | } 73 | 74 | if dict_string["key"] != "" and dict_string["value"] != "": 75 | string_list[categories[index//2]].append(dict_string) 76 | 77 | source_csv.close() 78 | os.remove(file_name) 79 | 80 | return string_list 81 | 82 | 83 | def write_strings(filename, string_list): 84 | swift_file = open(filename+".swift", "w") 85 | 86 | swift_file.write("import UIKit\n\n") 87 | swift_file.write("enum "+ filename + " {\n") 88 | 89 | for item in string_list: 90 | if filename == "Image": 91 | swift_file.write("\tstatic let " + item["key"] + " = " + "UIImage(named: \"" + item["value"] + "\")\n") 92 | elif filename == "Color": 93 | swift_file.write("\tstatic let " + item["key"] + " = " + "UIColor(named: \"" + item["value"] + "\")\n") 94 | else: 95 | swift_file.write("\tstatic let " + item["key"] + " = " + "\"" + item["value"] + "\"\n") 96 | 97 | swift_file.write("}") 98 | swift_file.close() 99 | 100 | 101 | 102 | if __name__ == '__main__': 103 | get_gdoc_information() 104 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AutoGenerationSwiftNameSpace 2 | 🐮 내 맘대로 만드는 네임스페이스 자동 생성기(feat. python) 3 | 4 | > 👉 왜 이렇게 까지 해야해? 라는 의문이 들 수 있을 것 같습니다. 5 | > 저도 처음에는 그렇게 생각했거든요. 6 | 7 | > 협업을 하다보니 서로 파일 · 에셋 · 변수명에 대한 부분을 논의하는 것이 생각보다 까다로운 작업이라는 것을 느꼈고, 8 | > 개발 파트 내에서도 더 나아가 디자이너, 기획자와의 협업에 있어서도 어느 정도 네이밍이 통일되어 사용되는 것이 중요하다는 생각이 들었습니다. 9 | 10 | > 👉 그러면 또 문서를 작성하면 되는 거 아니야?, 피그마나 노션 가이드라인 있잖아! 라고 생각이 들 수 있는데 11 | > 1. 해당 작업은 매 빌드 시 스프레드시트를 가져와 스크립트를 돌리기 때문에 스프레드시트 상에서 업데이트가 이루어지면 12 | > Xcode 프로젝트내에서도 값이 바로 반영이 되는 장점이 있습니다. 13 | > 개발자가 직접 프로젝트 내에서 일일이 변경하는 번거로움을 덜어줄 수 있죠. 14 | 15 | > 2. 또 하나 좋다고 생각하는 부분이 파트 내에서 네이밍에 대한 부분을 좀 더 효율적으로 정할 수 있다는 것 같습니다. 16 | > 스프레드시트를 보면서 같이 얘기해서 뷰컨, 스토리보드, 에셋 등의 네이밍을 하고 정리를 하면 17 | > 서로 정리가 되고 또, 프로젝트에도 바로 반영이 된다는 장점이 있는 것 같습니다. 18 | 19 | > 위에서 언급한 장점 때문에 다음 프로젝트에 한 번 사용해보려고 생각 중이구요..🙄 20 | > 🚨 근데 그냥 SwiftGen, R.swift 쓰는게 더 나을 것 같아요 ㅎㅎ (저는 1,2번 장점 때문에 쓰려고 합니다!!) 21 | 22 |
23 | 24 | ## Usage 25 | 26 | #### 1. 구글 스프레드시트 27 | > 네임스페이스, 상수라고 불리우는 값들을 작성합니다. 28 | 29 | > ⛔️ 현재 이미지에서 보이는 것처럼 Text, Color, Image, Storyboard, Xib를 기준으로 스크립트가 작성되어 있습니다. 30 | > ⛔️ 그래서 이미지처럼 내용을 스프레드시트를 작성하시거나, 파이썬 스크립트를 일부 수정해서 사용하시기 바랍니다. 31 | 32 | ![스크린샷 2021-12-25 오전 3 28 56](https://user-images.githubusercontent.com/61109660/147368969-e98f7914-3f29-419d-9e0d-bb7f36a92364.png) 33 | 34 | #### 2-1. 파이썬 파일 추가 35 | > 저 같은 경우는 script라는 폴더를 만들고 하위 항목으로 파이썬 파일을 넣어주었습니다. 36 | 37 | ![스크린샷 2021-12-25 오전 3 44 44](https://user-images.githubusercontent.com/61109660/147369203-27521d2e-f450-4313-86b6-18bdbfc6ca67.png) 38 | 39 | #### 2-2. 스프레드시트 아이디 추가 40 | 41 | 본인이 구글 드라이브에 생성한 스프레드시트의 아이디를 추가하는 작업이 필요합니다. 42 | 43 | generate.py 파일의 gdoc_id로 선언된 부분에 url의 ~/d/ 뒷부분의 값을 넣어주시면 됩니다. 44 | 45 | 스크린샷 2021-12-26 오전 1 25 14 46 | 47 | ```python 48 | gdoc_id = "1WMnHk1brX7CR34hCN88cDnTDc4UgTAKh-qegwnPIqCU/edit#gid=0" 49 | ``` 50 | 51 | #### 2-3. Xcode 파이썬 실행 스크립트 추가 52 | > [Build Phase] - [Run Script] 부분에 스크립트를 추가합니다. 53 | 54 | `ex` 55 | ``` 56 | python ${TARGET_NAME}/script/generate.py ${TARGET_NAME} 57 | ``` 58 | 59 | #### 3. 생성된 파일과 폴더를 Xcode 프로젝트 내에 추가합니다. 60 | 61 | ![스크린샷 2021-12-25 오전 3 40 24](https://user-images.githubusercontent.com/61109660/147369080-2ff105ed-1d1b-49f5-8b77-754621aab36b.png) 62 | 63 | > 생성된 폴더를 프로젝트 내로 드래그 하면 됩니다. 64 | 스크린샷 2021-12-25 오전 3 41 41 65 | 66 | #### 4. 그럼 예쁘게 생성된 네임스페이스(상수) 파일을 볼 수 있습니다. 67 | 스크린샷 2021-12-25 오전 3 43 06 68 | 스크린샷 2021-12-25 오전 3 43 21 69 | 스크린샷 2021-12-25 오전 3 43 26스크린샷 2021-12-25 오전 3 43 16 70 | 스크린샷 2021-12-25 오전 3 43 12 71 | 72 | #### 5. 구글 스프레드시트에 값을 업데이트하면 자동으로 프로젝트 내의 파일에도 반영이 됩니다. 73 | 74 |
75 | 76 | ## Trouble 77 | 78 | > python 파일에 외부에서 설치하는 모듈이 있으면 Xcode 상에서 정상 동작하지 않는 문제가 있습니다. 79 | > openpyxl 라이브러리를 써서 xlsx 파일로 관리하려 했으나 그게 되지 않아, 내장 모듈인 csv 모듈을 이용해서 작업했습니다. 80 | 81 |
82 | 83 | ## Reference 84 | 85 | https://macgongmon.club/m/26 86 | 87 | > 다음 블로그에서 영감을 받아 작업했습니다. 88 | > 파이썬 스크립트의 대부분의 코드를 가져왔으며, 일부분만 수정했습니다. 89 | --------------------------------------------------------------------------------