본문 바로가기

프로젝트/Universal textEditor

02. 구현

FileDocument


 

Apple Developer Documentation

 

developer.apple.com

파일을 불러올 구조체를 정의한다.

struct TextFile: FileDocument {
	static var readableContentTypes: [UTType]
	
	init(configuration: ReadConfiguration) throws {
		
	}
	
	func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper {
		
	}
}

구조체의 프로토콜은 FileDocument로 필수로 구현해야 하는 메서드와 생성자는 다음과 같다

  • init(configuration: Self.ReadConfiguration) throws
    열기에 해당한다.
  • static var readableContentTypes: [UTType]
    사용 가능한 타입을 열거한다.
  • func fileWrapper(configuration: Self.WriteConfiguration) throws -> FileWrapper
    저장에 해당한다.
  • static var writableContentTypes: [UTType]
    쓰기에 해당된다. 기본 구현돼있어 따로 선언하진 않아도 된다.
struct TextFile: FileDocument {
	static var readableContentTypes = [UTType.plainText]
	
	init(configuration: ReadConfiguration) throws {
		
	}
	
	func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper {
		
	}
}

사용할 파일 형식은 plainText로

struct TextFile: FileDocument {
	static var readableContentTypes = [UTType.plainText]
    
	var text = ""
	
	init(initialText: String = "") {
		text = initialText
	}
    
	init(configuration: ReadConfiguration) throws {
    
	}
	
	func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper {
		
	}
}

생성자를 추가해 파라미터로 전달된 문자열을 저장한다.

struct TextFile: FileDocument {
	static var readableContentTypes = [UTType.plainText]
    
	var text = ""
	
	init(initialText: String = "") {
		text = initialText
	}
    
	init(configuration: ReadConfiguration) throws {
		if let data = configuration.file.regularFileContents {
			text = String(decoding: data, as: UTF8.self)
		} else {
			throw CocoaError(.fileReadCorruptFile)
		}
	}
	
	func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper {
		
	}
}

필수 생성자인 init(configuration:)은 이전에 저장된 파일을 읽어 와 UTF8의 형식으로 디코딩해 데이터를 표시한다.
파일 내용을 바인딩하는 데 실패하면 파일이 손상됐거나 삭제가 된 경우로 판단하고 에러를 표시한다.

struct TextFile: FileDocument {
	static var readableContentTypes = [UTType.plainText]
    
	var text = ""
	
	init(initialText: String = "") {
		text = initialText
	}
    
	init(configuration: ReadConfiguration) throws {
		if let data = configuration.file.regularFileContents {
			text = String(decoding: data, as: UTF8.self)
		} else {
			throw CocoaError(.fileReadCorruptFile)
		}
	}
	
	func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper {
		let data = Data(text.utf8)
		return FileWrapper(regularFileWithContents: data)
	}
}

fileWrapper(configuration:) 메서드는 파일을 저장할 때 사용된다.
어디에 저장되는지에 대한 경로는 FileWrapper가 알아서 처리한다.

 

UI 구성


struct ContentView: View {
	@Binding var document: TextFile
	
    var body: some View {
		TextEditor(text: $document.text)
    }
}

앞서 생성한 TextFile 구조체 형식으로 Binding 변수를 선언한다.
TextEditor의 파라미터로 전달하면 해당 변수의 문자열을 출력하고 변경하고, 저장할 수 있게 된다.

@main
struct ToyEditorApp: App {
    var body: some Scene {
		DocumentGroup(newDocument: TextFile()) { file in
			ContentView(document: file.$document)
		}
    }
}

구성한 인터페이스를 표시하는 WindowGroup과는 다르게 DocumentGroup를 사용하면
파일 탐색기를 기본 인터페이스로 사용할 수 있다.
'~App.swift' 파일에서 WindowGroup을 DocumentGroup으로 변경하고, 위에서 구현한 ContentView를 호출하면 된다.

'프로젝트 > Universal textEditor' 카테고리의 다른 글

04. 동작 검증, 더 나아가기  (0) 2022.10.24
03. 프로젝트 설정 변경  (0) 2022.10.24
01. 배경지식  (0) 2022.10.21
00. 시작하며  (0) 2022.10.21