문서

라이브러리

라이브러리 추가

라이브러리가 모든 결제 화면을 대신 그립니다. 폴더, 권한 하나, 작은 설정 파일 하나, 코드 한 줄만 추가하세요.

파일

앱의 설치 탭에서 라이브러리를 내려받으세요. 압축을 풀면 wearcheckout 폴더가 나옵니다.

경로하는 일
lib/watch/app/Pay.mc앱: 서버 확인, 서버 응답으로 그리는 구매 화면, 시간 제한, 알림음과 진동이 있는 잠금 해제.
lib/watch/glance/PayScope.mc(:glance) 주석을 단 active(), unlocked(), trialLeft(): 백그라운드 서비스가 없는 앱용.
lib/watch/glance-bg/PayScope.mc같은 것에 (:glance, :background) 주석을 단 버전: 백그라운드 서비스가 있는 앱용. 둘 중 정확히 하나만 쓰세요.
lib/watch/face/PayFace.mc, PayFaceScope.mc워치 페이스와 데이터 필드: 백그라운드 확인, drawQr, 설정 링크. 워치 페이스와 데이터 필드를 참고하세요.
lib/watch/extras/PayExtras.mc리뷰와 답장을 판매하거나 스토어프런트를 쓰는 경우만: 리뷰 요청, 답장, "구매하셨나요?" 화면. 앱의 추가 기능을 참고하세요. Connect IQ 3.1보다 오래된 시계는 건너뜁니다.
lib/watch/export/PayExport.mc휴대폰으로 내보내기를 판매하는 경우만: 앱 데이터를 시계에서 암호화한 스프레드시트로 만들고, 그 링크를 구매자 휴대폰으로 보냅니다.
lib/watch/feeds/PayFeeds.mc앱이 데이터 피드를 쓰는 경우만: 날씨, 해와 달, 기도 시간, 조석 등. 데이터 피드를 참고하세요.
lib/watch/resources/strings/pay.xml서버 없이 구매 화면이 표시하는 4줄(영어).
lib/watch/resources-<lang>/strings/pay.xml같은 4줄을 다른 7개 언어로.

프로젝트에 추가하기

앱 폴더 옆에 라이브러리 압축을 푸세요:

IntervalTimer/
    manifest.xml
    monkey.jungle
    resources/
    source/
        PaywallConfig.mc
wearcheckout/
    lib/watch/...

그다음 폴더를 jungle에 추가하세요:

monkey.jungle
base.sourcePath = source;../wearcheckout/lib/watch/app;../wearcheckout/lib/watch/glance
base.resourcePath = resources;../wearcheckout/lib/watch/resources
  • 상대 경로만 쓰세요. 절대 경로에 공백이 있으면 jungle이 깨집니다.
  • 또는 파일을 복사하세요. 내 source 및 resources 폴더(그리고 각 resources-<lang> 폴더)에 복사하면 jungle 줄이 필요 없습니다.
  • 설정할 주석이 없습니다. 빌드 하나로 모든 시계를 지원합니다. Instinct의 보조 화면은 실행 중에 찾습니다.

백그라운드 서비스가 있을 때

앱에 자체 백그라운드 서비스가 있다면 glance 대신 glance-bg를 쓰고, PaywallConfig에 (:glance, :background) 주석을 달고, Background 권한을 추가하세요. (:background) 코드가 있으면 컴파일러가 그 권한을 요구하므로 버전이 두 개입니다.

monkey.jungle
base.sourcePath = source;../wearcheckout/lib/watch/app;../wearcheckout/lib/watch/glance-bg

네트워크 허용

시계는 휴대폰 연결을 통해, 또는 Wi-Fi가 있는 시계라면 Wi-Fi로 서버에 묻습니다. Communications 권한을 추가하세요:

manifest.xml
<iq:permissions>
    <iq:uses-permission id="Communications"/>
</iq:permissions>

PaywallConfig.mc

앱의 설치 탭에서 내려받으세요. 앱의 실제 주소가 들어 있습니다. 주소는 비밀이 아닌 공개 정보입니다.

source/PaywallConfig.mc
// PaywallConfig.mc: from your dashboard (Interval Timer). Public, not a secret.
import Toybox.Lang;

(:glance)
module PaywallConfig {
    const URL = "https://pay.example/api/K7Q2/c";   // your app's address
    const TRIAL_DAYS = 7;
}
  • URL: 앱의 주소입니다. 모든 확인 요청이 이곳으로 갑니다.
  • TRIAL_DAYS: 체험이 없으면 생략하세요. 대시보드의 체험 기간과 같게 두세요. 시계는 TRIAL_DAYS보다 많은 날을 세지 않습니다.
  • 주석은 사용하는 PayScope.mc에 맞춥니다: (:glance), 또는 glance-bg와 함께 쓰는 (:glance, :background).

한 줄

getInitialView()에서 라이브러리를 거쳐 뷰를 반환하세요:

source/YourApp.mc
return Paywall.gate([new MainView(), new MainDelegate()]);   // the whole app is paid for
return Paywall.start([new MainView(), new MainDelegate()]);  // or: only some features are
  • gate는 체험을 시작하고, 때가 되면 서버에 묻고, 잠겨 있는 동안 앱 대신 구매 화면을 보여 줍니다. BACK는 앱을 나갑니다. 결제가 끝나면 BACK 또는 START가 앱의 뷰를 엽니다.
  • start는 평소처럼 앱을 열고, 체험이 끝나면 구매 화면을 한 번 보여 줍니다. 그 후 각 유료 기능이 먼저 확인합니다:
source/HistoryDelegate.mc
if (Paywall.unlocked()) { showHistory(); } else { Paywall.open(); }

어느 쪽이든, 구매 화면이 닫혀 있는 동안 휴대폰에서 한 구매는 시계가 알게 되면 잠금 해제 화면을 저절로 엽니다. 모든 호출은 유료 기능 잠그기에 있습니다.

설정의 Premium 항목

설정 메뉴의 "Premium" 항목은 구매 화면을 엽니다. 이미 떠 있으면 그 화면이 나오며, 두 번째 화면은 생기지 않습니다.

source/SettingsDelegate.mc
Paywall.open();

데이터 삭제

앱에 "데이터 삭제" 옵션이 있다면 Paywall.keys()가 반환하는 키는 남겨 두세요. 나머지는 다음 시작 때 서버에서 다시 받습니다.

source/SettingsDelegate.mc
// Delete data: everything except the payment keys
var st = Application.Storage;
var keep = Paywall.keys();
var saved = [];
for (var i = 0; i < keep.size(); i++) {
    saved.add(st.getValue(keep[i]));
}
st.clearValues();
for (var j = 0; j < keep.size(); j++) {
    if (saved[j] != null) {
        st.setValue(keep[j], saved[j]);
    }
}

앱의 추가 기능

유료 추가 기능 중 세 가지는 전용 폴더가 필요하므로, 이를 쓰지 않는 앱은 작게 유지됩니다. 시계 통계는 폴더가 필요 없습니다.

리뷰와 답장, 그리고 "구매하셨나요?"

extras 폴더를 추가한 뒤, 그 한 줄 앞에서 켜세요:

monkey.jungle
base.sourcePath = source;../wearcheckout/lib/watch/app;../wearcheckout/lib/watch/glance;../wearcheckout/lib/watch/extras
source/YourApp.mc
PayExtras.on();
return Paywall.gate([new MainView(), new MainDelegate()]);
  • 리뷰 요청은 3일, 7일 또는 14일째에 표시됩니다. 별점, 그다음 스토어 페이지를 여는 QR 코드와 개발자에게 남기는 메모가 나옵니다.
  • 답장은 앱 위에 한 번 표시됩니다. 작은 시계에서는 긴 답장이 두 화면에 걸치며, START로 나머지를 봅니다.
  • "구매하셨나요?"는 구매자가 스토어프런트 페이지에서 먼저 결제했을 때 새 시계의 코드를 한 번 보여 줍니다.
  • 폴더가 없으면 그 앱의 시계에는 요청이 뜨지 않고, 답장은 서버에서 대기하며, 스토어프런트 구매자는 일반 구매 화면을 스캔합니다. Connect IQ 3.1보다 오래된 시계도 폴더를 건너뜁니다.

휴대폰으로 내보내기

export 폴더를 추가하고, PayExport.ready()가 true인 동안 내보내기를 제공하고, 한 번에 한 행씩 반환하는 메서드로 시작하세요:

monkey.jungle
base.sourcePath = source;../wearcheckout/lib/watch/app;../wearcheckout/lib/watch/glance;../wearcheckout/lib/watch/export
source/ExportDelegate.mc
// Row 0 is the header; rows 1 to n are your data.
function row(i as Number) as Array {
    if (i == 0) { return ["Date", "Minutes"]; }
    var s = sessions[i - 1];
    return [s[:date], s[:minutes]];
}

if (PayExport.ready()) {
    PayExport.start(method(:row), sessions.size());
}
  • 값은 텍스트, 숫자, true나 false, 또는 null일 수 있습니다.
  • 나머지는 라이브러리가 합니다: 암호화된 데이터를 보낸 뒤 Garmin Connect 알림으로 구매자 휴대폰에 링크를 보냅니다. 구매자가 탭하면 휴대폰에서 스프레드시트가 열립니다. START는 링크를 다시 보냅니다. 링크를 받으려면 구매자 휴대폰이 시계에 연결되어 있어야 합니다.
  • 수식은 실행되지 않습니다. =, +, -, @로 시작하는 텍스트 앞에는 '가 붙습니다.

데이터 피드

feeds 폴더를 추가한 뒤, 앱에서 필요한 곳에서 피드를 요청하세요. 메서드는 HTTP 코드와 응답을 받습니다:

monkey.jungle
base.sourcePath = source;../wearcheckout/lib/watch/app;../wearcheckout/lib/watch/glance;../wearcheckout/lib/watch/feeds
source/MainView.mc
PayFeeds.get("weather", {
    "lat" => lat, "lon" => lon,
    "tz" => System.getClockTime().timeZoneOffset
}, method(:onWeather));

function onWeather(code as Number, data as Dictionary or Null) as Void {
    if (code == 200) {
        temp = data["now"]["temp"];
        WatchUi.requestUpdate();
    }
}
  • 피드: 해, 달, 기도 시간, 세계 시계, 환율, 날씨, 기상 특보(미국), 지진, 오로라, 조석(미국), 공휴일. 각 피드의 매개변수와 필드는 대시보드의 데이터 피드 페이지에 있으며, 그곳에서 직접 사용해 볼 수 있습니다.
  • 시계에 보관됩니다. 각 응답은 ttl에 적힌 초만큼 유효합니다. 그 전에 같은 피드를 거의 같은 위치로 다시 요청하면, 서버에 묻지 않고 보관된 응답이 즉시 돌아옵니다.
  • 위치는 도 단위입니다. 시간은 Unix 초, 단위는 미터법입니다.
  • 피드 카드에서 요구하면 출처 문구를 표시하세요. 예: "Weather: MET Norway".
  • 다른 코드에는 null이 옵니다. 403은 이 앱의 추가 기능이 꺼져 있다는 뜻이고, 429 또는 503는 나중에 다시 시도하라는 뜻이며, 음수 코드는 Garmin의 코드입니다(휴대폰 없음, 네트워크 없음). 테스트 시계는 모든 피드가 무료입니다.
  • 비용: 실제 판매 중인 시계의 요청 100만 건당 US$2이며, 월별 청구서에 포함됩니다. 시계에 보관된 응답은 비용이 들지 않습니다.

시계 통계

코드가 필요 없습니다. 시계 모델은 매번 확인할 때 함께 옵니다. 앱 버전도 보려면 PaywallConfig에 버전을 추가하세요:

source/PaywallConfig.mc
const VERSION = "1.3";

언어

라이브러리는 영어, 독일어, 프랑스어, 스페인어, 포르투갈어, 한국어, 중국어(간체, 번체)를 지원합니다. 시계의 언어에 따라 정해집니다. 그 밖의 언어는 영어로 나옵니다.

  • 화면은 서버에서 시계의 언어로 내려옵니다. 그래서 문구를 고쳐도 앱을 업데이트할 필요가 없습니다.
  • 서버 응답이 아직 없을 때를 위해 시계에는 4줄만 저장됩니다.
문자열영어표시 시점
PwWait불러오는 중…첫 응답 전
PwPhone오프라인휴대폰, 블루투스, 인터넷 연결 없음
PwBusy나중에 다시 시도서버가 제대로 응답하지 않음
PwBackBACK으로 닫기보여 줄 응답이 전혀 없을 때

언어마다 jungle 줄을 하나씩 추가하세요. 내 폴더를 먼저 두고, 앱에 폴더가 없는 언어는 그 부분을 빼세요.

monkey.jungle
base.lang.deu = resources-deu;../wearcheckout/lib/watch/resources-deu
base.lang.fre = resources-fre;../wearcheckout/lib/watch/resources-fre
base.lang.spa = resources-spa;../wearcheckout/lib/watch/resources-spa
base.lang.por = resources-por;../wearcheckout/lib/watch/resources-por
base.lang.kor = resources-kor;../wearcheckout/lib/watch/resources-kor
base.lang.zhs = resources-zhs;../wearcheckout/lib/watch/resources-zhs
base.lang.zht = resources-zht;../wearcheckout/lib/watch/resources-zht

확인할 것

  • 앱 이름 문자열. 보여 줄 응답이 없으면 구매 화면은 AppName 문자열을 표시합니다. 이 문자열을 리소스에 두세요.
  • 타이머. 구매 화면이 타이머 하나를, PayExtras가 하나를 더 씁니다. 시계는 몇 개만 허용하며 "Too Many Timers"가 나면 앱이 종료됩니다. 앱이 이미 두 개 이상 쓴다면 한도를 넘지 않는지 확인하세요.
  • 버튼 길게 누르기. 버튼을 너무 오래 누르면 시계 자체 메뉴가 열립니다. 구매 화면은 짧게 누르는 것에만 반응합니다.
  • 이전 호출도 여전히 작동합니다. getInitialView()의 Paywall.startTrial(); Paywall.launch();와 첫 화면 onShow()의 Paywall.showOver()는 gate와 start가 한 줄로 하는 일을 합니다.
Esc