<!--
{
  "availability" : [
    "iOS: 17.4.0 -",
    "iPadOS: 17.4.0 -",
    "macCatalyst: 17.4.0 -",
    "visionOS: -"
  ],
  "documentType" : "symbol",
  "framework" : "Assignables",
  "identifier" : "/documentation/Assignables/AssignableDocument",
  "metadataVersion" : "0.1.0",
  "role" : "Structure",
  "symbol" : {
    "kind" : "Structure",
    "modules" : [
      "Assignables"
    ],
    "preciseIdentifier" : "s:11Assignables18AssignableDocumentV"
  },
  "title" : "AssignableDocument"
}
-->

# AssignableDocument

An assignable document is an augmented PDF that allows teachers to mark up
the PDF with the intention of students taking the assessment.

```
struct AssignableDocument
```

## Overview

The document has several parts, which includes the ability to modify the PDF,
annotate the PDF, and define question regions in the PDF.

To add a question to this assignable, you can use [`appendQuestion(pageID:rect:maxScore:)`](/documentation/Assignables/AssignableDocument/appendQuestion(pageID:rect:maxScore:))
which will take care of associating a box to a page and adding a question connected
to that box to the document.

This document is fully mergeable, which means that any copies of this document
that are independently mutated can be merged into a determinisitic resulting
document. You can merge copies of this document into this one using
[`merge(_:)`](/documentation/Assignables/AssignableDocument/merge(_:)).
You can also merge individual parts of copies of this
document into this one with [`merge(partData:into:)`](/documentation/Assignables/AssignableDocument/merge(partData:into:)).
For example, if deviceA has documentA and
deviceB has documentB, which is a copy of documentA. When a user changes a
question in documentB on deviceB, deviceB can export that part’s data
and send it to deviceA to be merged back into documentA.

You can create as many of these objects as you have memory for.
This type assumes single-threaded access.

## Topics

### Creating an assignable document

[`init(pdfURL: URL, id: String?) throws`](/documentation/Assignables/AssignableDocument/init(pdfURL:id:))

Initializes a new assessment document that is based on the
PDF located at the provided URL.
If the file located at the URL provided cannot be accessed, this initializer throws.

[`init(id: AssignableDocument.ID, partData: [AssignableDocument.PartID : MergeablePartData]) async throws`](/documentation/Assignables/AssignableDocument/init(id:partData:)-8gf6g)

Construct an instance of this object with the parts data passed in.

[`enum MergeablePartData`](/documentation/Assignables/MergeablePartData)

[`init(id: AssignableDocument.ID, partData: [AssignableDocument.PartID : URL]) throws`](/documentation/Assignables/AssignableDocument/init(id:partData:)-4am19)

Construct an instance of this object with the parts data passed in.

[`init(pdfURL: URL, authors: [some UserIdentity], id: String?) throws`](/documentation/Assignables/AssignableDocument/init(pdfURL:authors:id:))

Initializes a new assessment document that is based on the
PDF located at the provided URL.
If the file located at the URL provided cannot be accessed, this initializer throws.

### Inspecting an assignable document

[`typealias ID`](/documentation/Assignables/AssignableDocument/ID-swift.typealias)

A type representing the stable identity of this document.

[`var id: AssignableDocument.ID`](/documentation/Assignables/AssignableDocument/id-swift.property)

The stable identity of this document.

[`var isMultiPageDocument: Bool`](/documentation/Assignables/AssignableDocument/isMultiPageDocument)

`true`, if this document has more than one page; `false`, otherwise.

[`var isPartial: Bool`](/documentation/Assignables/AssignableDocument/isPartial)

Denotes whether or not this document is a partial one.

[`enum PartIDs`](/documentation/Assignables/AssignableDocument/PartIDs-swift.enum)

An enumeration containing the identities of parts managed by this view.

[`var partIDs: [AssignableDocument.PartID]`](/documentation/Assignables/AssignableDocument/partIDs-swift.property)

Returns a collection of identifiers reflecting the manifest of parts available in the document.

[`struct Question`](/documentation/Assignables/AssignableDocument/Question)

A question in the assignable document.

[`struct QuestionBox`](/documentation/Assignables/AssignableDocument/QuestionBox)

A box on a page for a question.

[`var questions: [AssignableDocument.Question]`](/documentation/Assignables/AssignableDocument/questions)

A collection of questions defined for this assignable.

[`typealias Element`](/documentation/Assignables/AssignableDocument/Element)

The type for elements of this document. An element is a component
of the document such as a page or question.

[`var pagesDebugDescription: String`](/documentation/Assignables/AssignableDocument/pagesDebugDescription)

[`enum Error`](/documentation/Assignables/AssignableDocument/Error)

Errors for this document type.

### Getting and setting the questions

[`func appendQuestion(pageID: AssignableDocument.Page.ID, rect: CGRect, maxScore: Double?) -> AssignableDocument.Question.ID`](/documentation/Assignables/AssignableDocument/appendQuestion(pageID:rect:maxScore:))

Creates a new question and appends it to the document.

[`func questions(on: AssignableDocument.Page.ID) -> [AssignableDocument.Question]`](/documentation/Assignables/AssignableDocument/questions(on:))

Find questions that exist on the specified page.

[`func removeQuestion(AssignableDocument.Question.ID) -> AssignableDocument.Question?`](/documentation/Assignables/AssignableDocument/removeQuestion(_:))

Removes a question and its boxes from the document.

### Computing the max score

[`func computeMaxScore(defaultQuestionMaxScore: Double?) -> Double?`](/documentation/Assignables/AssignableDocument/computeMaxScore(defaultQuestionMaxScore:))

Computes the maximum possible score for this `AssignableDocument` as defined
by each individual question’s `maxScore`.

### Getting the authors

[`var authors: [AnyUserIdentity]`](/documentation/Assignables/AssignableDocument/authors)

The set of identities of users that created or modified this assignable.
Treated as a set.

### Getting the configuration

[`typealias Configuration`](/documentation/Assignables/AssignableDocument/Configuration-swift.typealias)

The configuration for an assessment which contains options
for display of marks and their point values.

[`var configuration: some AssignableDocumentConfiguration`](/documentation/Assignables/AssignableDocument/configuration-swift.property)

The configuration of this assessment which contains options
for display of marks and their point values.

[`enum CorrectMarkType`](/documentation/Assignables/AssignableDocument/CorrectMarkType)

The glyph to use that represents a correct mark.

### Merging the parts

[`func merge(AssignableDocument) async throws -> Bool`](/documentation/Assignables/AssignableDocument/merge(_:))

Merge another object of this type into this object.

[`func merge(partData: MergeablePartData, into: AssignableDocument.PartID) async throws -> Bool`](/documentation/Assignables/AssignableDocument/merge(partData:into:))

Merges an individual part into the specified part of this object.

[`func merge(other: AssignableDocument) throws -> Bool`](/documentation/Assignables/AssignableDocument/merge(other:))

Merge another object of this type into this object.

[`func merge(partID: AssignableDocument.PartID, partDataURL: URL) throws -> Bool`](/documentation/Assignables/AssignableDocument/merge(partID:partDataURL:))

Merges an individual part’s data into the specified part of this object.

### Producing thumbnails

[`func questionThumbnails(visibleParts: [AssignableDocument.PartID]) async -> [AssignableDocument.Question.ID : [AssignableDocument.Question.Thumbnail]]`](/documentation/Assignables/AssignableDocument/questionThumbnails(visibleParts:))

Produces thumbnails of question regions within the document.

### Making the parts

[`func makePart(for: AssignableDocument.PartID) throws -> MergeablePartData?`](/documentation/Assignables/AssignableDocument/makePart(for:))

Creates data for the part with the given identifier.

### Exporting the parts

[`func exportBaseAsPDF() async -> PDFDocument`](/documentation/Assignables/AssignableDocument/exportBaseAsPDF())

Exports the base part of this document to a `PDFDocument`.

[`func exportParts(identifiedBy: [AssignableDocument.PartID]) async throws -> [AssignableDocument.PartID : MergeablePartData]`](/documentation/Assignables/AssignableDocument/exportParts(identifiedBy:))

Given a set of part identifiers, return a dictionary
of part ID to part data.

[`func export(partIDs: [AssignableDocument.PartID]) async throws -> [AssignableDocument.PartID : URL]`](/documentation/Assignables/AssignableDocument/export(partIDs:))

Given a set of part identifiers, return a dictionary
of part ID to data objects for the requested layers.

### Accessing documents

[`subscript(AssignableDocument.Page.ID) -> AssignableDocument.Page?`](/documentation/Assignables/AssignableDocument/subscript(_:)-8ou91)

Access the page that the identifier denotes, if any.

[`subscript(AssignableDocument.QuestionBox.ID) -> AssignableDocument.QuestionBox?`](/documentation/Assignables/AssignableDocument/subscript(_:)-68enn)

Access the question box that the identifier denotes, if any.

[`subscript(AssignableDocument.Question.ID) -> AssignableDocument.Question?`](/documentation/Assignables/AssignableDocument/subscript(_:)-7fijz)

Access the question that the identifier denotes, if any.

### Comparing assignable documents

[`static func == (AssignableDocument, AssignableDocument) -> Bool`](/documentation/Assignables/AssignableDocument/==(_:_:))

Returns a Boolean value indicating whether two values are equal.

### Hashing the assignable document

[`func hash(into: inout Hasher)`](/documentation/Assignables/AssignableDocument/hash(into:))

Hashes the essential components of this value by feeding them into the given hasher.

### Default Implementations

[Assignable Implementations](/documentation/Assignables/AssignableDocument/Assignable-Implementations)

[MergeableDocument Implementations](/documentation/Assignables/AssignableDocument/MergeableDocument-Implementations)

## Relationships

### Conforms To

[`Identifiable`](/documentation/Swift/Identifiable)

[`Escapable`](/documentation/Swift/Escapable)

[`Copyable`](/documentation/Swift/Copyable)

[`Assignable`](/documentation/Assignables/Assignable)

[`MergeablePartsContainer`](/documentation/Assignables/MergeablePartsContainer)

[`Hashable`](/documentation/Swift/Hashable)

[`MergeableDocument`](/documentation/Assignables/MergeableDocument)

[`Equatable`](/documentation/Swift/Equatable)

---

Copyright &copy; 2026 Apple Inc. All rights reserved. | [Terms of Use](https://www.apple.com/legal/internet-services/terms/site.html) | [Privacy Policy](https://www.apple.com/privacy/privacy-policy)