강제 업데이트
프로젝트의 iOS 앱과 Android 앱은 각각 자기 버전 정책을 가집니다. 프로젝트를 열고 Force update 페이지를 선택한 뒤, 위쪽에서 앱을 고르세요.
앱이 받는 응답
앱은 실행할 때 설치된 버전을 Mocco에 보내고 세 가지 응답 중 하나를 받습니다.
| 상태 | 조건 | 앱이 해야 할 일 |
|---|---|---|
hard | 버전이 최소 지원 버전보다 낮거나 차단된 경우 | 닫을 수 없는 화면을 표시하고, 스토어로 이동하는 버튼을 제공합니다 |
soft | 버전이 권장 버전보다 낮은 경우 | 사용자가 닫을 수 있는 안내를 표시합니다. 안내 간격이 지나면 다시 확인합니다 |
ok | 그 밖의 모든 경우 | 아무것도 하지 않습니다 |
Mocco가 모르는 앱이나 정책이 없는 앱은 항상 ok를 받습니다. 설정을 잘못해도 사용자가 앱을 쓰지 못하게 되는 일은 없습니다.
In force 상자에는 앱이 지금 받는 정책, 그 리비전, 이 앱의 버전 확인 URL이 표시됩니다.

정책 설정과 변경
아래 양식은 정책 전체를 편집합니다. 최소 지원 버전, 권장 버전, 차단 버전, 영어 안내 문구(모든 언어의 기본값), 스토어 링크, 닫은 안내가 다시 나타나는 간격입니다. 스토어 링크를 비워 두면 앱의 스토어 ID로 만든 기본 링크를 사용합니다.
제출하기 전에 양식이 변경의 종류를 알려 줍니다. Tightens는 더 많은 사용자가 업데이트 안내를 받거나 강제로 업데이트해야 한다는 뜻입니다. 버전을 올리거나, 버전을 차단하거나, 스토어 링크를 바꾸는 경우입니다. Relaxes는 그 수가 줄어든다는 뜻입니다. 버전을 낮추거나 차단을 해제하는 경우입니다. 문구나 안내 간격만 고치면 둘 중 어느 쪽도 아닙니다.
버전을 올릴 때는 새 버전이 이미 스토어에 올라와 있는지도 확인하도록 요구합니다. 스토어에 아직 없는 버전으로 업데이트하라는 안내를 받은 사용자는 막히기 때문에, 이 확인은 변경 내용과 함께 기록됩니다.

승인 요구하기
Require approval for tightening changes를 선택한 다음, 어떤 역할의 몇 명이 승인해야 하는지, 요청자가 자기 변경을 승인하지 못하게 할지, 승인자에게 사유를 요구할지 정합니다. 처음 설정할 때는 바로 적용됩니다. 그 뒤에 이 설정을 바꾸거나 제거하는 일은 그 자체가 제한을 강화하는 변경이며, 현재 적용 중인 정책에 따라 승인받습니다.
승인을 켜면 제한을 강화하는 변경은 Open requests 아래에서 대기하고, 충분한 승인자가 승인할 때까지 현재 정책이 그대로 유지됩니다. 더 새로운 요청이 오면 아직 대기 중인 이전 요청을 대체합니다. 필요한 역할에 속한 사람은 누구나 카드에서 승인하거나 거절할 수 있습니다. 자기 승인을 막아 둔 경우 요청자에게는 버튼이 보이지 않습니다.

제한을 완화하는 변경은 승인을 켜 두어도 즉시 적용됩니다. 롤백이 승인자를 기다려서는 안 되기 때문입니다. 대신 사후 검토(post-hoc review) 가 열립니다. 필요한 역할의 누군가가 검토 완료로 표시하기 전까지 이 변경은 이력에 Unreviewed로 표시됩니다.
이력
적용된 모든 변경이 무엇이 바뀌었는지, 누가 바꿨는지, 사유, 승인으로 적용되었는지와 함께 나열됩니다. 각 변경은 워크스페이스의 Audit 로그에도 남습니다.

앱에서 버전 확인 호출하기
버전 확인은 공개 GET 요청입니다. In force 상자에서 URL을 복사하고, 설치된 버전과 선택 사항으로 사용자의 언어를 덧붙입니다.
GET https://<your Mocco domain>/api/ext/v1/apps/<appId>/version-check?version=2.3.1&locale=ko-KR{
"status": "soft",
"minSupportedVersion": "2.0.0",
"recommendedVersion": "2.4.0",
"message": { "title": "Update available", "body": "…", "action": "Update" },
"storeUrl": "https://play.google.com/store/apps/details?id=com.acme.mobile",
"promptIntervalHours": 72,
"revision": 5
}상태가 ok이면 message는 null입니다. 문구는 정확히 일치하는 언어 태그를 먼저 찾고, 그다음 언어(ko-KR, 이어서 ko), 마지막으로 영어 순으로 고릅니다. 응답은 약 1분 동안 캐시되므로 변경은 1분 안팎에 기기에 반영됩니다. URL에는 키가 필요 없습니다. 어차피 정책은 앱의 모든 사용자에게 보이기 때문입니다.
Mocco의 React Native 패키지가 공개되기 전까지는 직접 호출하세요.
import { Alert, Linking } from 'react-native';
import DeviceInfo from 'react-native-device-info';
const CHECK_URL = 'https://<your Mocco domain>/api/ext/v1/apps/<appId>/version-check';
export async function checkForUpdate(locale: string) {
const version = DeviceInfo.getVersion();
const response = await fetch(`${CHECK_URL}?version=${encodeURIComponent(version)}&locale=${encodeURIComponent(locale)}`);
if (!response.ok) {
return; // Never block the app because the check failed.
}
const answer = await response.json();
if (answer.status === 'ok' || answer.message === null) {
return;
}
const open = { text: answer.message.action, onPress: () => Linking.openURL(answer.storeUrl) };
Alert.alert(answer.message.title, answer.message.body, answer.status === 'hard' ? [open] : [{ text: 'Later' }, open], {
cancelable: answer.status !== 'hard',
});
}soft일 때는 사용자가 안내를 닫은 시점을 기억해 두고(예: AsyncStorage), promptIntervalHours가 지난 뒤에 다시 물어보세요. hard일 때는 앱이 포그라운드로 돌아올 때마다 안내를 다시 표시하세요.