GN⁺: 애플 텍스트 에디터의 기술적 내부 구조
(papereditor.app)Apple 텍스트 편집기의 기술적 내부
-
TextView
기반의 텍스트 편집기로서 Paper의 작동 방식에 대한 세부 사항을 다룸. - Paper는 현재 TextKit 1 프레임워크를 기반으로 구축되어 있으며, TextKit 2에서도 개념, 추상화 및 원칙이 유지되거나 더 나은 API로 변경됨.
텍스트 뷰
-
TextView
클래스는 Apple 텍스트 편집기에서 텍스트 편집 작업의 핵심. -
NSTextView
와UITextView
는 차이가 있지만, API가 유사하여 하나의TextView
클래스로 취급. -
TextView
는 복잡성이 매 OS 릴리스마다 증가하는 대규모 컴포넌트. - Apple은
TextView
를 여러 계층으로 세분화하여 텍스트 편집 경험을 제공.
NSTextStorage
- 원시 텍스트 문자열을 저장.
- 텍스트 범위에 할당된 속성(문자열-값 쌍)을 저장.
- 텍스트와 속성 변경에 대한 이벤트를 발생시킴.
NSTextContainer
- 텍스트 기호(글리프)를 호스팅하는 영역의 모양과 크기를 정의.
NSLayoutManager
-
NSTextStorage
의 텍스트 문자열에 적용된 속성 범위를 보고 글리프의 크기와 간격을 계산. - 글리프를 레이아웃하고, 텍스트의 각 줄이 시작하고 끝나는 위치, 전체 텍스트의 높이를 계산.
TextView
-
NSLayoutManager
에 의해 생성된 글리프 레이아웃을 그림. - 뷰의 높이를 레이아웃된 텍스트의 현재 높이와 동기화.
- 텍스트 선택, 캐럿, 새로 삽입된 텍스트에 적용되는 타이핑 속성을 관리.
ScrollView
-
TextView
의 보이는 부분을 표시. - 스크롤, 스크롤 바, 확대/축소를 관리.
속성
-
NSAttributedString
은 Apple 프레임워크에서 리치 텍스트 편집의 기초. - 일반 텍스트 문자열과 텍스트 범위에 첨부된 속성(문자열-값 쌍)으로 구성.
- 속성은 주로 스타일링 목적으로 사용되지만, 사용자 정의 문자열-값 쌍을 할당하는 데 제한이 없음.
스타일링
- 스타일링은 텍스트 범위에 특별한 프레임워크 정의 속성을 적용하는 것을 의미.
- Paper는 메타 속성을 사용하여 텍스트 구조를 식별한 후 스타일링을 적용.
- 속성은 사용자 입력으로 인해 변경되는
NSTextStorage
의 Markdown 텍스트와 사용자가 메뉴 항목, 슬라이더, 제스처에서 조정하는 텍스트 영향 설정과 동기화됨.
성능
- 메타, 레이아웃, 장식 속성의 분리는 특정 편집기 변경 사항을 빠르게 유지하는 데 도움.
- 타이핑 속도는 텍스트 편집기에서 가장 중요한 성능 요소.
- Markdown의 작동 방식으로 인해 텍스트 변경은 전체 단락의 스타일링에 영향을 줄 수 있음.
메타 속성
- 하이라이팅 논리 외에도 메타 속성은 텍스트 구조에 대해 알아야 하는 다양한 기능에서 중요한 역할을 함.
포맷팅 단축키
- 선택된 Markdown 텍스트의 스타일을 토글하는 데 필요한 상세한 정보 제공.
장(chapter) 간 이동
- 캐럿 위치에 상대적인 제목을 찾는 데 도움.
개요(Outline)
- 모든 제목을 순회하는 기능에 의존.
장(chapter) 재배열
- 개요에서 장을 재배열하는 기능 제공.
포맷 변환
- Markdown 내용을 RTF, HTML, DOCX로 변환하는 데 구조를 알아야 함.
텍스트 컨테이너 수학
- 텍스트 컨테이너는 선호하는 줄 길이를 유지하는 것이 가장 중요한 규칙.
- 제목 태그가 일반 텍스트 흐름 밖에 배치될 때와 같이 대칭을 가장해야 하는 경우가 있음.
선택 앵커링
- 텍스트 선택은 항상 앵커 포인트를 가짐.
- Mac에서는 클릭하고 드래그하여 텍스트를 선택하고, iOS에서는 선택의 한쪽 끝을 드래그할 수 있음.
선택 친화도
- 텍스트 편집에서 _선택 친화도_라는 흥미로운 개념이 있음.
- 캐럿을 화살표 키로 이동할 때 줄을 간단히 바꾸지만, 단축키로 줄 끝으로 이동하면 같은 줄에 머물면서 오른쪽에 붙음.
Uniform Type Identifiers (UTIs)
- 앱 간 데이터 교환의 기반 시스템인 UTIs에 대해 논의.
- 데이터 타입이 부모 데이터 타입에 conform to (상속)하는 계층적 시스템.
클립보드(Pasteboard)
- 클립보드는 UTIs가 직렬화된 데이터에 매핑된 사전.
- 단일 복사 작업은 동일한 데이터의 여러 표현을 한 번에 작성.
- 공개 UTIs와 개인 UTIs를 다루는 것은 상대적으로 간단하지만, Apple에 의해 정의되지 않은 널리 허용되는 형식을 다루는 것은 더 복잡.
마무리
- 첫 번째 기사를 확인하면 앱과 개발 과정에 대한 더 많은 정보를 얻을 수 있음.
GN⁺의 의견
- 이 기사는 Apple 플랫폼에서
TextView
기반 텍스트 편집기의 복잡한 내부 작동을 상세히 설명하고 있어, 소프트웨어 개발자나 관심 있는 사용자에게 흥미로운 정보를 제공함. - 텍스트 편집기의 성능 최적화를 위한 알고리즘과 속성 관리 방법은 개발자들이 자신의 애플리케이션을 설계할 때 참고할 수 있는 좋은 사례임.
- 텍스트 편집기의 성능을 높이기 위해 사용된 기술적 접근 방식은 다른 개발자들이 유사한 문제를 해결할 때 참고할 수 있는 유용한 지침을 제공함.
- Markdown과 같은 텍스트 포맷을 다루는 애플리케이션을 개발할 때 UTIs의 이해는 데이터 교환과 호환성을 위해 중요함.
- 이 기사는 텍스트 편집기의 내부 구조에 대한 이해를 높이는 데 도움이 되지만, 실제로 이러한 복잡성을 관리하는 것은 개발자에게 상당한 도전이 될 수 있음.
Hacker News 의견
-
이 글은 정말 좋다. TextKit에 대한 나의 기본 소개 자료로 <a href="https://:///www.objc.io&/…;" rel="nofollow">https://www.objc.io</a>를 대체할 것 같다.
- 이 댓글은 해당 글이 TextKit에 대한 기본적인 소개로 매우 유용하다고 평가함.
-
편집 트랜잭션 외부에서 수행되는 장식적 속성에 대해 약간 혼란스럽다. "그리고 트랜잭션을 인지하지 못하는데, 이는 NSLayoutManager 자체에 존재하기 때문이지 NSTextStorage에 있는 것이 아니다"라고 했다. 색상과 같은 장식적 속성은 보통 NSTextStorage에 존재하는데! 저자는 마크다운 문자에 적용된 색상이 NSLayoutManager의 임시 속성 지원(일반적으로 철자가 틀린 단어를 색칠하는 데 사용됨)을 통해 이루어지고 있다는 것을 암시하는 건가? 그렇다면 그 목적은 무엇일까?
- 댓글 작성자는 텍스트 편집과 관련된 기술적인 세부사항에 대해 혼란을 느끼며, 장식적 속성이 NSLayoutManager와 NSTextStorage 사이에서 어떻게 다루어지는지에 대한 저자의 설명에 의문을 제기함.
-
정말 훌륭한 기사다(그리고 개인적으로도 시기적절하다. 현재 NSTextViews를 다루고 있음). 이 정보를 어떻게 얻었나? 다른 사람의 코드? 고통스러운 경험? developer.apple.com?
- 댓글 작성자는 기사가 매우 유용하다고 평가하며, 저자가 이러한 지식을 어떻게 얻었는지 궁금해함.
-
DOM 문서의 시대에(예: notion, gitbook), 나는 종종 텍스트 파싱과 조작에 마법 같은 일을 하기 위해 속성 문자열을 사용한다. 이것은 매우 우아한 구조이고 왜 이렇게 알려지지 않았는지 이해할 수 없다. 참고로 기사는 놀랍다
- 댓글 작성자는 속성 문자열을 사용하는 것이 우아한 방법이라고 생각하며, 이 기술이 더 널리 알려지지 않은 이유를 이해할 수 없다고 언급함. 기사에 대한 칭찬도 함께함.
-
나는 과거에 스크래치부터 자체 텍스트 에디터를 작성하려고 시도한 적이 있는데, 이런 자원이 있었다면 정말 대단했을 것이다.
- 댓글 작성자는 자신이 텍스트 에디터를 처음부터 만들려고 시도했던 경험을 언급하며, 이 기사가 그 당시에 있었다면 매우 도움이 되었을 것이라고 말함.
-
나는 오랫동안 안드로이드 앱 개발자였기 때문에, 애플이 사물을 다소 다르고 더 신중하게 접근하는 방식을 보는 것이 흥미로웠다. 안드로이드에서는 Layout 클래스(및 그 서브클래스)가 레이아웃과 렌더링과 관련된 모든 것을 처리하고, TextView는 편집/선택 논리의 일부를 구현한다. EditText와 TextView의 유일한 차이점은 EditText가 TextView에 이미 존재하는 편집 기능을 '활성화'한다는 것이다. 이러한 다소 일체형 접근 방식(그리고 불량한 API)의 문제점은 앱이 텍스트를 렌더링하는 방식에 대해 더 많은 제어가 필요할 경우 운이 없다는 것이다. 예를 들어, 레이아웃된 후 개별 글리프에 접근하고 싶다면? 아니, 미안하다.
- 댓글 작성자는 안드로이드와 애플의 텍스트 렌더링 및 편집 접근 방식의 차이점에 대해 설명하며, 안드로이드의 경우 더 세밀한 제어가 필요할 때 제한적이라는 점을 지적함.
-
TextEdit 앱은 거의 전적으로 단일 TextView로 구성되어 있다. 나는 WordPad가 Windows의 대응물이라고 생각한다. 이는 RichEdit 컨트롤을 기반으로 한다. 또 다른 재미있는 사실은 RTF가 기본적으로 NSAttributedString의 직렬화된 형태라는 것이다. Windows의 RichEdit 컨트롤에도 동일하게 적용된다. 실제로, Windows의 구현이 먼저 나온 것 같다: <a href="https://en.wikipedia.org/wiki/Rich_Text_Format" rel="nofollow">https://en.wikipedia.org/wiki/Rich_Text_Format</a>
- 댓글 작성자는 TextEdit 앱이 TextView를 기반으로 하고 있으며, RTF(Rich Text Format)가 NSAttributedString의 직렬화된 형태라는 점을 언급함. 또한, Windows에서 비슷한 기능을 하는 RichEdit 컨트롤이 먼저 나왔을 수도 있다고 함.
-
이 앱을 정말 좋아한다. obsidian과 ia Writer를 포함한 다른 모든 마크다운 앱을 대체했다!
- 댓글 작성자는 해당 앱이 마크다운 작업을 위한 자신의 모든 기존 앱을 대체했다고 매우 만족해함.
-
다행히도 적어도 누군가는 2024년에도 Cocoa를 사용하고 있다.
- 댓글 작성자는 여전히 Cocoa 프레임워크를 사용하는 개발자가 있다는 사실에 안도감을 표현함.
-
iOS 컴포넌트에 대해 이런 문서가 더 많았으면 좋겠다!
- 댓글 작성자는 iOS 컴포넌트에 대한 이러한 유형의 문서가 더 많이 있었으면 좋겠다는 바람을 나타냄.