스트리밍은 대부분의 브라우저와
Developer 앱에서 사용할 수 있습니다.
-
SwiftUI로 문서 기반 앱 구축하기
SwiftUI로 문서 기반 앱을 완전히 구축하는 방법을 알아보세요. DocumentGroup API와 이 API를 앱 및 모드에서 어떻게 활용할 수 있는지 알려 드립니다. DocumentGroup API를 사용하면 번거로움 없이 문서 검색, 표준 명령과 같은 문서 관리를 위한 기본 지원을 추가할 수 있습니다. 범용 유형 식별자를 설정하는 방법과 우수한 문서 기반 앱이 갖춘 특징도 다룹니다. 이 세션을 최대한 활용하려면 먼저 SwiftUI로 앱을 제작하는 방법을 숙지하시는 것이 좋습니다. 자세히 알아보려면 ‘SwiftUI 앱 기초'를 확인하세요.
리소스
관련 비디오
WWDC23
WWDC20
-
다운로드
Hello and welcome to WWDC.
Hi, everyone. My name's Tina. I work on SwiftUI. Today I'm going to talk about building apps supporting documents with SwiftUI. First off, what is a document? People have been managing their files with the Finder and Files app on macOS, iPadOS and iOS. They can use features like tags, cloud file providers and external storage devices to organize their projects as they need. They expect to be able to use apps that allow them to seamlessly open these files in place, view and edit them. This includes being able to make changes on the original document, where the change is accessible to all apps that support opening files in place. This is in contrast to apps that import those files into some database that is then managed by the app. When you edit an imported document, you're editing a copy of the original document, and the original is unchanged. Professional apps like Pixelmator not only allows users to do openInPlace file management, but also enable powerful editing capabilities, including opening multiple files at once. Almost all of the functionality in apps like Pixelmator, Keynote and Final Cut Pro is focused on allowing users to do this management of documents. We often call these "document-based apps" as an indication of that behavior. But opening documents is a feature your app can support without being entirely document-based. Apps like Xcode have additional UI and features outside of its document support. And apps like Mail and Console primarily present a non-document-based appearance, but support opening additional documents, like EML files or crash reports. A SwiftUI application is composed of apps, scenes and views. Adding support for documents is done compositionally using another scene type, called DocumentGroup. A simple text-editing app looks like this. When you use DocumentGroup in your app, you're declaring that your app supports opening and managing this type of document in place. As shown in the "App Essentials in SwiftUI" talk, the structure of our code matches the hierarchy of ownership of an app. In this case, our app contains a single DocumentGroup scene, able to open multiple windows of that document content. And of course, as a compositional element, it could support multiple DocumentGroups for different types, or a WindowGroup and a DocumentGroup. You can compose these scenes into your app, and SwiftUI automatically gives your app the expected platform behaviors for those scenes. That includes standard UI elements specific to document apps. State Tracking and Handoff on Mac, and Document Browser and the Navigation Bar with search field and sharing functionality on iOS. You get all these with very minimal code. Now let's build something using DocumentGroup API. So I was prototyping a drawing app with SwiftUI on my iPad Playground. I currently have a canvas where I can add shapes of different colors and change their shapes. I think it's working quite well, so I want to make it into an app where I can save and manage my drawings. Let's see how to do this. Let's open Xcode and create a document-based app. I want to have it run on both macOS and iOS, so I'm going to choose the multi-platform template.
I'm going to call it "ShapeEdit." This already comes with some templates. Let's try building and running this.
We now have a text-editing app that has all the document-supporting features we mentioned before. Now, before we dive in, let's have a look at the project settings.
I'm going to focus on the macOS target for now, but the configuration we're going to use applies to both the iOS and macOS targets. Let's take a look at the Info.plist.
Xcode adds the "Document Type" section for document-based apps.
The value in this identifier field is a uniform type identifier. The system uses this identifier to associate files with your app, so it knows to open this type of document in your app when it sees one on the system. This identifier is declared as an imported type down here.
It's imported because the plain text type was declared by another party, and we import this type declaration to tell the system that the app knows about it. For our app, we're going to declare a type of our own, so let's come back here...
and create one. Since it's a type we invented, we need to export the type declaration to tell the system that we are the authoritative owner of this type. We do this by filling out the "Exported Type Identifier" section.
Let's give it a description.
We're going to store the drawing app's binary data, so make it conform to public data... and public content.
I'm also going to assign it an extension.
So this is all we need to change here. Let's have a look at the main function.
Our document type ShapeEditDocument is declared for us already. Both the type of document and the base document to use when creating new documents are passed to DocumentGroup. The document property of the closure's argument is a binding that provides us with read-write access to the underlying data model, which is the text in this text-editing app. DocumentGroup supports opening place, and the binding lets SwiftUI know when the text is updated so it takes care of registering undo and dirtying the document state. Let's take a look at ContentView, which is the default view for presenting the document.
It consists of a TextEditor. Since we're going to do a shape-drawing app, we're going to replace it with a canvas where users can draw. But we'll come back to that later. Let's have a look at a ShapeEditDocument.
It is a value type that conforms to the file document protocol, which is the representation of a document on disk. First, we are going to define readableContentTypes. It's an array of UTType, the uniform type identifier. SwiftUI uses this to identify the type of a document that your user wants to open, and only those defined here are allowed. exampleText is defined here.
This should match what we put in the "Document Types" section of the target's Info.plist earlier, so let's change this.
Notice the difference between the two declarations. Here, we're using the exportedAs constructor, while previously we were using the importedAs constructor. The imported type is a computed variable because it's imported. That means its value can change over time as apps are installed or uninstalled. Here, we're using an exported type, so it can be declared a constant. For more information, see the documentation for UTType on the Developer website. Now let's change this...
to our own type.
Next, let's implement initializing our document, giving the FileWrapper and the contentType. We don't need this code, so I'm going to remove them. The contentType argument is always the type supported by the app. And there are a few ways to do this. Here, we're going to use a JSONDecoder.
And to use a JSONDecoder, the type needs to conform to "Codable." We also need to implement writing out the document to a file for our specified type. We don't need these either, so I'm also going to remove them. FileWrapper is the destination of the serialization. It's an inout argument, and we can either create the new FileWrapper or update it. Again, there are a few ways to do this, and we'll use a JSONEncoder.
So that's all we need to do to conform to the file document protocol. Notice that we are working with a value type here.
This means that you get all the benefits of working with this struct, including copy-on-write behavior, and that the app can start saving while the user is still drawing. Now, with document support in place, let's add our prototype canvas code into the project.
We have a graphic type that defines the attributes of the shapes and a Canvas View to display the shapes. Let's change the data type in the document from text to our graphic type.
Let's also add some initial shapes.
Let's also swap out the TextEditor with our canvas.
And we're all set. Let's run it.
We have a drawing app that supports documents. I can save the drawings and revisit them later. So, this is how easy it is to add document support to your app in SwiftUI. Thank you. [chimes]
-
-
2:12 - DocumentGroup TextEditor
@main struct TextEdit: App { var body: some Scene { DocumentGroup(newDocument: TextDocument()) { file in TextEditor(text: file.$document.text) } } }
-
-
찾고 계신 콘텐츠가 있나요? 위에 주제를 입력하고 원하는 내용을 바로 검색해 보세요.
쿼리를 제출하는 중에 오류가 발생했습니다. 인터넷 연결을 확인하고 다시 시도해 주세요.