구글시트를 활용하여 앱 스트링 관리하기

글로벌 서비스를 목표로 한다면 다국어 지원은 필수적으로 고려해야 합니다. 지원하려는 대상 국가가 많아진다던가, 같은 표현이라도 다르게 표시해야 한다던가, 언어 특성 및 길이에 따라 텍스트를 축소하여 번역하는 등 다국어 지원은 다양한 사람들이 함께, 상당한 양의 작업이 필요합니다.

다국어 업무를 수행하는데 있어서 반드시 다음 내용이 고려되어야 한다고 생각합니다.

  • 여러명의 담당자가 한 공간에서 작업을 진행할 수 있어야 한다.
  • 많은 리소스를 손쉽게 제품에 적용할 수 있어야 한다.

일반적으로 안드로이드에서 다국어 지원을 위하여 리소스 관리를 하기 위한 방법은 1)구글시트를 활용한 리소스 관리, 2)리소스 관리 도구을 활용 하는 방법으로 나누어 생각해 볼 수 있을 것 같습니다. 그중 적은 비용으로 리소스를 효율적으로 관리할 수 있는 구글 시트를 활용한 리소스 관리 방법을 정리해보고자 합니다.

번역 업무 수행 환경 구성하기

하나의 문서를 여러명이서 동시에 사용하는 환경은 아무래도 구글 문서만한 것이 없는 것 같습니다. 특히 도큐먼트, 슬라이드, 시트 등의 문서 포멧은 이미 많이 사용하고 있으므로 처음 접근하는데도 어려움이 없다고 생각합니다.

먼저 구글 드라이브에 하나의 시트 문서를 만들어서 Manual, Android 시트 2가지를 만들어 봅니다.

Manual 시트

manual

보통 번역 담당자들이 1~2개정도 언어를 담당하게 되므로 지원하는 언어가 많아질 수록 더 많은 사람들과 하나의 문서로 업무를 진행할 것입니다. 각 담당자들은 어떤 역할을 수행해야 하는지를 잘 공유할 수 있도록 정리해 둡니다. 이를통해 Manual 시트는 번역 담당자들이 업무 프로세스와 실제로 무엇을 해야 하는지를 이해하기 쉽게 작성하는것이 중요합니다.

Android 시트

resources

실제 프로젝트에서 사용중인 리소스를 엑셀로 잘 만들어 줍니다. 1열부터 차례대로 리소스 키, 한국어, 번역대상언어(ex.영어, 중국어 등)를 차례대로 만들어 줍니다. 만약 <–comment–> 와 같은 주석형태가 필요하다면 키 부분에 넣어줍니다. (스크립트에서 추가 판별하여 처리하도록 해둡니다.)

번역을 하는 언어의 기준이 한국어가 아니라면 한국어 위치에 다른 언어가 대체되도 상관 없습니다.

만약 프로젝트 리소스가 사용자 채널마다 다르게 제공되는 경우 (front-end, ios, etc) 해당 문서에서 시트로 한꺼번에 관리하는 것을 추천드립니다. 관리적인 측면에서도 리소스가 분리되지 않아 다른 플랫폼 간의 검색이나 복사 등이 용이하며, 번역가 입장에서는 하나의 작업 공간에서 제품에 대한 모든 업무를 수행하는것이 편리하기 때문입니다.

Android 리소스 생성 도구 구성하기

메뉴 구성하기

먼저 아래와 같이 onOpen() 함수에서 별도 메뉴를 추가해 줍니다.

function onOpen() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet();
  var entries = [
    {
      name : "안드로이드 리소스 생성",
      functionName : "createAndroidStringResource"
    }
  ];
  sheet.addMenu("Wanted", entries);
};

menu

구글 시트에 메뉴를 추가하는 간단한 코드이며, 각 메뉴가 동작할 function 을 선언해 둡니다. 추가적으로 리소스를 하나에 문서에서 다양하게 관리한다면 메뉴를 여러개 추가해서 편리하게 관리할 수 있습니다.

리소스 생성 스크립트 추가

메뉴에서 선언한 createAndroidStringResource라는 함수를 만들어서 구현부를 작성합니다.

var SHEET_NAME = "Android";     // google sheet 의 안드로이드 리소스 시트 이름
var FILE_NAME = "strings.xml";
var LANGUAGE_SET = [
  [1, "values-ko"],           // 한국어
  [2, "values"],              // 영어
  [3, "values-zh-rCN"],       // 중국어(간체)
  [4, "values-zh-rTW"]        // 중국어(번체)
];

// 메뉴 선택시 호출되는 함수
function createAndroidStringResource() {
  var sheet = SpreadsheetApp.getActiveSheet();      // 현재 선택된 시트 문서를 가지고 스크립트 수행
  if( sheet != null && sheet.getName() == SHEET_NAME ) {
    var sheetData = sheet.getSheetValues(1, 1, sheet.getLastRow(), sheet.getLastRow());
    writeAndroidResourceFile(sheetData);
    return true;
  } else {
    SpreadsheetApp.getUi().alert("알림", "파일 생성에 실패하였습니다.", SpreadsheetApp.getUi().ButtonSet.OK);
    return false;
  }
}

// 시트 데이터로 파일 생성
function writeAndroidResourceFile(sheetData) {
  for(var i=0; i<LANGUAGE_SET.length; i++) {
    var folder = LANGUAGE_SET[i][1];
    var xml = convertDataToXmlString(sheetData, LANGUAGE_SET[i][0]);

    if( xml != null ) {
      DriveApp.createFolder(folder).createFile(FILE_NAME, xml);
    }
  }
}

// 각 폴더에 strings.xml 파일 생성
function convertDataToXmlString(sheetData, columnIndex) {
  var result = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<resources>\r\n";
  for(var i=1; i<sheetData.length; i++) {
    var row = sheetData[i];
    var key = row[0];
    var value = row[columnIndex];

    if( value == null || value == '' ) {
      value = "";
    }

    if( key == null || key == '' ) {
      result += "\r\n";
    } else if( key.indexOf("<!--") > -1 ) {
      result += "    " + key + "\r\n";
    } else {
      result += "    " + "<string name=\"" + key + "\">" + value + "</string>\r\n";
    }
  }
  result += "</resources>"
  return result;
}

resources

result

위 스크립트가 정상 동작 완료 이후에는 아래와 같이 현재 로그인된 계정의 드라이브에 각 폴더별 리소스가 생성됩니다.

다른 환경(iOS등)에서 사용하는 리소스의 경우에도 그에 맞춰서 리소스를 생성하는 스크립트를 작성해서 활용하면 더 효과적입니다. 그리고 용도에 맞춰서 .gs 파일을 나누어서 관리하면 스크립트 관리에 도움이 됩니다.

알림 전송하기

리소스가 실제 제품에 빌드 반영될 때, 특정 문구를 번역 요청할 때 등이 담당자들에게 자동적으로 알림이 되면 업무 효율이 더 증가합니다.

이런 유틸리티성 기능은 업무 환경에 맞춰 추가해주면 함께 작업하는 작업자들끼리 더 편리해 지는데요, Slack의 경우 Incoming Webhooks를 이용하여 prompt를 입력받아 업무를 요청한다던가, 기타 알림을 간편하게 연동시킬 수 있습니다.

Webhook 설정에 대한 자세한 내용은 이 페이지를 참조해 주세요


다음 포스트에서는 리소스 관리 도구을 활용 하는 방법과 원티드가 어떤 방법으로 이를 활용하는지를 소개하도록 하겠습니다.