C.W.K.
Stream
Lesson 05 of 05 · published

텍스트만 말고 클립보드 전체를 복원해

~11 min · pasteboard, preservation, fidelity, etiquette

Level 0차가운 부싯돌
0 XP0/34 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"사용자가 갖고 있던 클립보드는 이미지, 파일, 리치 텍스트일 수 있어. 전부 빌리고, 전부 도로 줘."

클립보드는 문자열이 아냐

프로브가 클립보드를 빌리니까, 복원은 그걸 충실히 돌려줘야 해 — 그리고 여기 함정: 클립보드는 그냥 평범한 텍스트가 아냐. 어느 순간이든 이미지, 파일, 리치 텍스트, HTML, 아니면 어떤 앱의 커스텀 타입을 쥘 수 있어, 흔히 같은 것의 여러 표현을 한꺼번에. 복원이 평범한 텍스트 문자열만 저장하고 다시 썼으면, 클립보드에 이미지나 파일 세트를 갖고 있던 사용자는 그걸 네 프로브가 조용히 파괴해. '되돌릴 수 있다' 는 텍스트뿐 아니라 실제로 갖고 있던 뭐든에 대해 되돌릴 수 있다는 뜻이어야 해.

모든 항목, 모든 타입을 스냅샷

완전한 캡처는 페이스트보드의 항목들 — 하나 이상일 수 있어 — 을 걷고, 각 항목마다 그것이 광고하는 모든 타입을 그 타입의 데이터와 함께 기록해. 그 항목-대-타입-대-데이터 맵이 진짜 스냅샷이야. 복원은 그 거울상이야: 페이스트보드를 비우고 그 항목들을 모든 타입 온전히 도로 써. 이렇게 하면 이미지는 이미지로, 파일은 파일로, 리치 텍스트는 형식 그대로 살아남아 — 사용자 클립보드가 문자열로 납작해지지 않고 바이트 단위로 돌아와.

순진함 (텍스트 빼고 다 잃음):
  저장   pb.string(forType: .string)
  ...프로브...
  복원   pb.setString(saved, forType: .string)   // 이미지/파일 사라짐

충실함:
  저장   모든 항목 -> 모든 타입 -> 그 데이터
  ...프로브...
  복원   각 항목을 모든 타입과 재구축, 도로 씀

완전히 캡처 못 할 때

정직 체크: 어떤 클립보드 내용은 완전히 스냅샷 못 해 — 약속되거나 게으르게 제공되는 데이터, 소스 앱이 실제 붙여넣기가 일어날 때만 바이트를 넘기는 것. 그런 건 항상 앞에서 캡처 못 해. 보수적 룰은: 페이스트보드 전체를 충실히 스냅샷 못 하면, 파괴적 프로브를 아예 안 돌려 — 다른 방식으로 읽을 수 있던 걸로 폴백하고, 클립보드를 그냥 둬. 선택을 놓치는 게 사용자가 복사한 파일을 먹는 것보다 나아. 보존은 전부-아니면-전무야: 완전한 충실도, 아니면 안 만짐.

완전한 충실도 아니면 보수적 — 절대 절반만 보존하지 마. 공유 상태를 빌릴 때, 80% 를 복원하는 건 안 빌리는 것보다 나빠, 사용자가 클립보드가 온전하다고 믿고 네가 떨군 20% 를 중요해질 때까지 안 알아채니까. 전부 캡처하고 복원하거나, 손상시킬 연산을 거절하거나야. 부분 복원은 안전의 코스튬을 입은 조용한 데이터 손실이야.
같은 규율이 삽입에서 다시 나타나. 매크로 결과가 클립보드에 써서 붙여넣는 걸로 놓이면, 그 삽입도 클립보드를 빌려 — 그리고 같은 완전한 캡처-복원을 빚져. 페이스트보드 스냅샷을 재사용 조각으로 지어; 읽기 프로브(이 트랙)와 붙여넣기 기반 삽입(Track 6) 둘 다 그것에 기대. 조심스러운 구현 하나, 호출자 둘.

Code

페이스트보드 전체를 캡처·복원, 모든 항목과 타입·swift
struct PasteboardSnapshot {
    let items: [[NSPasteboard.PasteboardType: Data]]
}

func capturePasteboard(_ pb: NSPasteboard) -> PasteboardSnapshot {
    let items = (pb.pasteboardItems ?? []).map { item in
        var byType: [NSPasteboard.PasteboardType: Data] = [:]
        for type in item.types {
            if let data = item.data(forType: type) { byType[type] = data }
        }
        return byType
    }
    return PasteboardSnapshot(items: items)
}

func restorePasteboard(_ pb: NSPasteboard, from snap: PasteboardSnapshot) {
    pb.clearContents()
    let rebuilt = snap.items.map { byType -> NSPasteboardItem in
        let item = NSPasteboardItem()
        for (type, data) in byType { item.setData(data, forType: type) }
        return item
    }
    if !rebuilt.isEmpty { pb.writeObjects(rebuilt) }
}

External links

Exercise

사용자가 클립보드에 파일 셋을 복사해뒀어. 네 매크로가 Electron 앱에서 내려쳐서, Flint 가 복사 프로브를 돌려. 합성 Cmd+C 전에 뭐가 캡처되고 뒤에 뭐가 복원돼야 끝났을 때 파일 셋이 여전히 클립보드에 있는지 정확히 걸어. 그다음 클립보드가 완전히 스냅샷 못 하는 약속된 데이터를 쥐고 있다고 발견하면 Flint 가 뭘 해야 하는지 룰을 말해.
Hint
모든 페이스트보드 항목을, 항목마다 광고된 모든 타입을 그 데이터에 매핑해 — 파일 참조 포함 — 캡처하고, 프로브 결과를 읽은 뒤 그 항목들을 재구축해 도로 써. 클립보드가 충실히 캡처 못 하는 약속된/게으른 데이터를 쥐면, 룰은 전부-아니면-전무야: 파괴적 프로브를 안 돌려, 부분 복원이 사용자 파일을 조용히 떨굴 테니까.

Progress

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

댓글 0

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

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