본문 바로가기
C.W.K.
Stream
Lesson 02 of 05 · published

발판 넷, 각각 우아하게 실패

~12 min · ladder, insertion-methods, graceful-degradation, cgevent

Level 0불씨 없음
0 XP0/36 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"모든 앱에 텍스트를 넣는 한 방법은 없어. 네 방법이 있고, 각각이 포기할 때의 계획이 있어."

왜 방법이 아니라 사다리

macOS 엔 '이 텍스트를 포커스된 필드에 넣어라' 를 어디서나 안정적으로 해 주는 호출이 없어. 앱마다 내미는 표면이 다르거든. 그래서 삽입은 사다리 가 돼. 쓸 수 있는 최선의 방법을 시도하고, 안 되면 다음 발판으로 내려가. 발판마다 깨끗함을 넓이랑 맞바꾸는 거야.

네 발판

1. AX 교체            제일 깨끗, 클립보드 안 건드림
   |  (앱이 안정적 편집 가능 값 + 범위를 노출하는 곳만)
   v  실패 -> 
2. 클립보드 + Cmd+V    대부분 앱과 큰 텍스트의 넓은 기본
   |  (클립보드 건드림; 저장/복원 예의 필요)
   v  실패 / 적대적 ->
3. Unicode 키 이벤트   키 입력 합성, 클립보드 부작용 없음
   |  (느림; 짧은 텍스트나 붙여넣기-적대 타깃에 좋음)
   v  실패 ->
4. 클립보드 전용       최후 수단: 복사 + "수동 붙여넣기" 알림

발판 1, AX 교체. 포커스된 요소가 편집 가능한 값이랑 선택 범위를 안정적으로 내주면, 접근성으로 바로 갈아끼워. 클립보드도 안 건드리고 제일 깨끗해. 대신 검증된 앱에서만 써. 발판 2, 클립보드에 쓰고 Cmd+V 합성. 큰 텍스트랑 대부분의 앱을 넓게 커버하는 기본값이야. 거의 어디서나 되는 대신 클립보드를 건드리니까, 그만큼 클립보드 예의를 빚지게 되고. 발판 3, Unicode 키 이벤트. CGEvent 로 문자를 하나씩 만들어 넣어. 클립보드는 안 건드리는 대신 느려서, 짧은 텍스트나 붙여넣기를 싫어하는 타깃에 어울려. 발판 4, 클립보드만 쓰기. 아무것도 안 되면 텍스트를 복사해 두고 붙여넣으라고 알려줘.

실패 말고 격하해

사다리의 핵심은 삽입이 그냥 실패 하지 않는다는 거야. 내려갈 뿐이지. 제일 나쁜 경우인 클립보드 + 알림조차 유저를 자기 텍스트에서 키 하나 거리에 세워 두고, 무슨 일이 있었는지 분명히 알려줘. 방법 하나로만 가는 설계랑 비교해 봐. AX 만 쓰면 AX 를 안 내주는 앱에서 전부 깨져. 붙여넣기만 쓰면 타깃이 붙여넣기를 거부하는 순간 막히고. 사다리가 있다는 건 늘 되는 발판이 하나는 있다는 뜻이야. 유저는 어떻게든 자기 단어를 손에 넣게 되고.

어디서나 되는 방법이 없는 일엔, 바닥이 보장된 사다리를 지어. 이상적인 방법이 가끔만 될 때 기능 전체를 거기에 걸지 마. 방법을 제일 깨끗한 것부터 제일 넓은 것 순으로 세우고, 마지막 발판은 절대 실패하지 않는 폴백으로 만들어. 여기선 클립보드 + 알림이 그거고. 그러면 누구든 발판 하나에는 닿고, 막다른 길에 걸리는 사람은 없어.
맹목적으로 시도하지 말고 타깃 종류를 보고 발판을 골라. 스냅샷에 담긴 분류가, 그러니까 브라우저인지 에디터인지 터미널인지 모르는 앱인지가, 어느 발판이 먹힐지 이미 알려줘. 그러니 매번 맨 위에서 실패하며 내려오는 대신 맞는 높이에서 시작할 수 있어. 믿을 만한 에디터면 AX 부터, 모르는 앱이면 붙여넣기부터. 터미널은 아예 자기 프로파일을 따로 받고.

Code

사다리, 발판을 하나씩 시도하고 바닥은 보장·swift
func insert(_ text: String, into t: TargetSnapshot) async -> InsertOutcome {
    // 발판 1 — 제일 깨끗, AX 가 검증된 곳만.
    if t.category.axReliable, await axReplace(text, in: t.focusedElement) { return .inserted(.ax) }

    // 발판 2 — 넓은 기본; 클립보드 건드림(예의 빚짐).
    if await pasteInsert(text, into: t) { return .inserted(.paste) }

    // 발판 3 — 키 입력 합성; 클립보드 부작용 없음, 느림.
    if await keyEventInsert(text, into: t) { return .inserted(.keyEvents) }

    // 발판 4 — 실패-불가 바닥: 복사 + 유저한테 알림.
    clipboard.copy(text)
    notify("삽입 못 함 — 텍스트 복사됨. Cmd+V 로 붙여넣어.")
    return .clipboardOnly
}

External links

Exercise

네 작업에서 어디서나 되는 방법이 하나도 없는 일을 골라봐. 파일 타입 렌더링이나 포맷 내보내기, 기기 연결 같은 거. 가진 방법을 제일 깨끗한 것부터 제일 넓은 것 순으로 세우고, 절대 실패하지 않는 바닥을 정해. 유저가 그 바닥에서 뭘 겪게 되고, 그게 받아들일 만해?
Hint
좋은 바닥은 화려하진 않아도 안정적이고 솔직해. 삽입이라면 '클립보드에 복사됐어, 직접 붙여넣어' 가 그거고. 시험해 볼 건 이거야. 그 바닥에서도 유저가 최소한의 수고와 분명한 설명으로 원하는 걸 이룰 수 있나? 바닥이 '에러, 아무 일도 안 일어남' 이면 아직 사다리가 아냐. 가끔 실패하는 방법 하나일 뿐이지.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.