UIActivityViewController для добавления дополнительных типов в UIPasteboard для действия «copyToPasteboard» - PullRequest
0 голосов
/ 10 апреля 2020

Основная структура данных моего приложения соответствует протоколу Codable и может использовать его для сериализации своих данных в / из JSON. Я хотел бы иметь возможность включить эти данные в общий монтажный щит (UIPasteboard.general), когда пользователь выбирает «Копировать» в UIActivityViewController.

Однако я не могу понять, как это сделать. Добавление JSON к элементам контроллера активности, в виде данных, строки или словаря, не помогает. Печать типов элемента монтажного стола просто показывает, что вы ожидаете от приписанной строки:

["com.apple.uikit.attributedstring", "com.apple.rtfd", "com.apple.flat-rtfd", "public.utf8-plain-text"]

В соответствии с документацией для UIActivity.ActivityType.copyToPasteboard :

При использовании этого сервиса вы можете предоставлять объекты NSString, UIImage, NSURL, UIColor и NSDictionary в качестве данных для элементов действия.

Так что я ожидал, что включение словаря в «элементы» автоматически добавит элементы словаря в монтажную панель (с ключами словаря в качестве типов элементов монтажной панели). Но, похоже, в этом случае это не работает, даже если я использую простой словарь [String: String].

Код, который я пробую, приведен ниже.

    func shareStuff() {
        let attrString = someThing.attrString()
        let printer = CustomPrintPageRenderer(someThing)

        var pasteboardDict: [String:Any] = [:]
        let jsonEncoder = JSONEncoder()
        jsonEncoder.outputFormatting = .prettyPrinted
        let jsonData = try? jsonEncoder.encode(someThing)
        let jsonString = String(data: jsonData!, encoding: .utf8)
        print(jsonString!)
        if jsonData != nil {
            pasteboardDict["jsonData"] = jsonData
            if jsonString != nil {
                pasteboardDict["jsonString"] = jsonString
            }
        }

        let items = [printer, attrString, pasteboardDict] as [Any]
        let activity = UIActivityViewController(activityItems: items, applicationActivities: nil)
        present(activity, animated: true)
    }

I Я также пытался включить «себя» в «элементы» и использовать протокол «UIActivityItemSource», но это, похоже, не имеет никакого значения для того, что находится на монтажной панели (и я подтвердил, что строка, возвращающая словарь, получает call):

    func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {
        if activityType == .copyToPasteboard {
            return ["blah": "some stuff"]
        } else {
            return nil
        }
    }

Есть ли способ использовать операцию UIActivityViewController «Копировать» для добавления дополнительных типов в монтажную панель?

Или мне нужно создать собственную отдельную «Копию» действие вне контроллера представления активности (и исключить «copyToPasteboard» из контроллера активности, чтобы избежать путаницы)?

1 Ответ

0 голосов
/ 11 апреля 2020

Я нашел решение, и мой процесс «вставки» теперь распознает, что на монтажном столе теперь есть и «jsonData», и «jsonString», а также приписанная строка и простой текст.

Вместо добавив «я» к «пунктам», я должен был иметь «Я» в качестве единственного элемента. Затем я могу определить, какие элементы возвращаются функцией протокола:

    func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {
        guard let recipe = recipe else { return nil }
        let attrString = someThing.attrString()
        switch activityType {
        case UIActivity.ActivityType.print:
            return SomePrintPageRenderer(someThing)
        case UIActivity.ActivityType.copyToPasteboard:
            var pasteboardDict: [String:Any] = attrString.pasteables()
            let jsonEncoder = JSONEncoder()
            jsonEncoder.outputFormatting = .prettyPrinted
            let jsonData = try? jsonEncoder.encode(someThing)
            let jsonString = String(data: jsonData!, encoding: .utf8)
            print(jsonString!)
            if jsonData != nil {
                pasteboardDict["jsonData"] = jsonData
                if jsonString != nil {
                    pasteboardDict["jsonString"] = jsonString
                }
            }
            return pasteboardDict
        default:
            return attrString
        }
    }

Обратите внимание, что мне также пришлось явно обрабатывать включение различных типов монтажных карт в виде простых и приписанных строк, которые мне все еще требуются. (Это было сделано с помощью специального расширения NSAttributedString с функцией 'pasteables ()', которая возвращает словарь вставляемых версий приписанной строки.)

...