Stworzyłem nową aplikację w XCode 11.2 na podstawie szablonu aplikacji opartej na dokumencie IOS. Następnie zmodyfikowałem typ dokumentu na typ zwyczaju i wykonałem małą zmianę, aby użyć pliku w pakiecie jako szablon podczas dokonywania nowego dokumentu. Pozostawiłem resztę domyślnej kotła. Próbowałem budować aplikację (zarówno z telefonem iPhone, jak i iPada) i próbowałem utworzyć nową aplikację. Nic się nie dzieje, żadne błędy nie są podniesione, a funkcja delegata didRequestDocumentCreationWithHandler nie zostanie wywołana (dodałem oświadczenie drukowania jako pierwszej linii, aby upewnić się). Dlaczego to? Co zmieniłem, żeby to złamać?

Ciekawej uwagi, przed wprowadzeniem jakichkolwiek zmian, po budynku, panel "Przeglądaj" widoku dokumentu miał ikonę "Utwórz dokument" (pusty kwadrat z plusem w środku), ale po dokonaniu zmian, to i folder Nazwa ma zarówno zniknące (zerwane | oczekiwane):

Broken Example Working example

Podejrzewam błąd, jest coś subtelnego w moich info.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleDevelopmentRegion</key>
    <string>$(DEVELOPMENT_LANGUAGE)</string>
    <key>CFBundleDocumentTypes</key>
    <array>
        <dict>
            <key>CFBundleTypeIconFiles</key>
            <array/>
            <key>CFBundleTypeName</key>
            <string>Lifreyan Layout</string>
            <key>CFBundleTypeRole</key>
            <string>Editor</string>
            <key>LSHandlerRank</key>
            <string>Owner</string>
            <key>LSItemContentTypes</key>
            <array>
                <string>name.cableray.lifreyanlayout</string>
            </array>
        </dict>
    </array>
    <key>CFBundleExecutable</key>
    <string>$(EXECUTABLE_NAME)</string>
    <key>CFBundleIdentifier</key>
    <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
    <string>$(PRODUCT_NAME)</string>
    <key>CFBundlePackageType</key>
    <string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
    <key>CFBundleShortVersionString</key>
    <string>1.0</string>
    <key>CFBundleVersion</key>
    <string>1</string>
    <key>LSRequiresIPhoneOS</key>
    <true/>
    <key>UILaunchStoryboardName</key>
    <string>LaunchScreen</string>
    <key>UIMainStoryboardFile</key>
    <string>Main</string>
    <key>UIRequiredDeviceCapabilities</key>
    <array>
        <string>armv7</string>
    </array>
    <key>UISupportedInterfaceOrientations</key>
    <array>
        <string>UIInterfaceOrientationPortrait</string>
        <string>UIInterfaceOrientationLandscapeLeft</string>
        <string>UIInterfaceOrientationLandscapeRight</string>
    </array>
    <key>UISupportedInterfaceOrientations~ipad</key>
    <array>
        <string>UIInterfaceOrientationPortrait</string>
        <string>UIInterfaceOrientationPortraitUpsideDown</string>
        <string>UIInterfaceOrientationLandscapeLeft</string>
        <string>UIInterfaceOrientationLandscapeRight</string>
    </array>
    <key>UISupportsDocumentBrowser</key>
    <true/>
    <key>UTExportedTypeDeclarations</key>
    <array>
        <dict>
            <key>UTTypeDescription</key>
            <string>Lifreyan Script Layout</string>
            <key>UTTypeIconFiles</key>
            <array/>
            <key>UTTypeIdentifier</key>
            <string>name.cableray.lifreyanlayout</string>
            <key>UTTypeTagSpecification</key>
            <dict>
                <key>public.filename-extension</key>
                <string>lifreyanlayout</string>
                <key>public.mime-type</key>
                <string>name.cableray.lifreyanlayout</string>
            </dict>
        </dict>
    </array>
    <key>UTImportedTypeDeclarations</key>
    <array/>
</dict>
</plist>

Na wszelki wypadek delegata przeglądarki dokumentów:


import UIKit
import SwiftUI

class DocumentBrowserViewController: UIDocumentBrowserViewController, UIDocumentBrowserViewControllerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()

        delegate = self

        allowsDocumentCreation = true
        allowsPickingMultipleItems = false
    }


    // MARK: UIDocumentBrowserViewControllerDelegate

    func documentBrowser(_ controller: UIDocumentBrowserViewController, didRequestDocumentCreationWithHandler importHandler: @escaping (URL?, UIDocumentBrowserViewController.ImportMode) -> Void) {
        print("importing new")
        let newDocumentURL = Bundle.main.url(forResource: "Default", withExtension: "lifreyanlayout")

        // Set the URL for the new document here. Optionally, you can present a template chooser before calling the importHandler.
        // Make sure the importHandler is always called, even if the user cancels the creation request.
        if newDocumentURL != nil {
            importHandler(newDocumentURL, .copy)
        } else {
            importHandler(nil, .none)
        }
    }

    func documentBrowser(_ controller: UIDocumentBrowserViewController, didPickDocumentsAt documentURLs: [URL]) {
        guard let sourceURL = documentURLs.first else { return }

        // Present the Document View Controller for the first document that was picked.
        // If you support picking multiple items, make sure you handle them all.
        presentDocument(at: sourceURL)
    }

    func documentBrowser(_ controller: UIDocumentBrowserViewController, didImportDocumentAt sourceURL: URL, toDestinationURL destinationURL: URL) {
        // Present the Document View Controller for the new newly created document
        presentDocument(at: destinationURL)
    }

    func documentBrowser(_ controller: UIDocumentBrowserViewController, failedToImportDocumentAt documentURL: URL, error: Error?) {
        // Make sure to handle the failed import appropriately, e.g., by presenting an error message to the user.
    }

    // MARK: Document Presentation

    func presentDocument(at documentURL: URL) {
        let document = Document(fileURL: documentURL)

        // Access the document
        document.open(completionHandler: { success in
            if success {
                // Display the content of the document:
                let view = DocumentView(document: document, dismiss: {
                    self.closeDocument(document)
                })

                let documentViewController = UIHostingController(rootView: view)
                self.present(documentViewController, animated: true, completion: nil)
            } else {
                // Make sure to handle the failed import appropriately, e.g., by presenting an error message to the user.
            }
        })
    }

    func closeDocument(_ document: Document) {
        dismiss(animated: true) {
            document.close(completionHandler: nil)
        }
    }
}

Porównałem mój projekt z Przykłady robocze i nie mogą znaleźć żadnych znaczących różnic ...

0
Garrett Motzner 30 grudzień 2019, 23:59

1 odpowiedź

Najlepsza odpowiedź

Zdecydowałem ten problem: niestandardowe UTIS musi (wygląda) określić typ zgodny, który opada z public.data lub com.apple.package.

Więc dodawanie tego do UTI działało:

    <key>UTTypeConformsTo</key>
    <array>
        <string>public.data</string>
    </array>

Bibliografia:

0
Garrett Motzner 30 grudzień 2019, 22:26