Можно ли поделиться историей в instagram и одновременно скопировать текст (iOS, swift)

Пробовал сделать так, но не получается, текст не копируется

       if let urlScheme = URL(string: "instagram-stories://share") {

 if UIApplication.shared.canOpenURL(urlScheme) {
                
 let imageData: Data = UIImage(systemName:"pencil.circle.fill")!.pngData()!
 let items:[String: Any] = ["public.utf8-plain-text": "text","com.instagram.sharedSticker.backgroundImage": imageData]
    
 UIPasteboard.general.setItems([items])
    
 UIApplication.shared.open(urlScheme, options: [:], completionHandler: nil)
 }}

Буду очень признателен за любой совет

2 ответа

2 вещи, о которых я могу думать:

Во-первых, я не уверен, что приведённые ниже данные в вашем массиве могут быть правильно обработаны pastebin.

      let items:[String: Any] = ["public.utf8-plain-text": "text","com.instagram.sharedSticker.backgroundImage": imageData]

Затем кажется, что действие обмена приводит к потере данных в PasteBoard, поэтому я могу предложить решение для помещения действительных данных в PasteBoard (например, я использую строку, вы можете использовать что-то еще "из обработчика завершения вашего обмена действие, что-то вроде этого может решить это:

      UIApplication.shared.open(urlScheme, options: [:]) { (_) in
    UIPasteboard.general.string =
        "click on the screen until the paste button appears: https://google.com"
}

РЕДАКТИРОВАТЬ

Кажется, ваша настройка была правильной, и при чтении документов истории IG должны автоматически обрабатывать вставку, поскольку кажется, что она проверяет монтажный стол при выполнении этой схемы URL: instagram-stories://share- так что кажется, что IG проверяет монтажный стол и программно выполняет вставку, поэтому монтажный стол очищается.

Возможно, из-за того, что изображение, которое вы выбираете, черное на черном фоне Instagram, кажется, что ничего не передается, но с каким-то правильным изображением результат кажется хорошим.

Еще одна вещь, которую я заметил после прочтения их документов , они больше не позволяют вам устанавливать подписи, я больше не могу найти этот ключ. public.utf8-plain-text

Еще одна идея, которую я могу предложить для обмена текстом, состоит в том, чтобы преобразовать текст в изображение и добавить его как stickerтак как слой наклейки находится поверх слоя фонового изображения.

Вы можете найти несколько способов преобразования текста в изображение, и это не имеет отношения к вашему решению, вот один из способов, который я использовал

Итак, объединив код, у меня есть это:

      // Just an example to convert text to UIImage 
// from https://stackoverflow.com/a/54991797/1619193
extension String {
    
    /// Generates a `UIImage` instance from this string using a specified
    /// attributes and size.
    ///
    /// - Parameters:
    ///     - attributes: to draw this string with. Default is `nil`.
    ///     - size: of the image to return.
    /// - Returns: a `UIImage` instance from this string using a specified
    /// attributes and size, or `nil` if the operation fails.
    func image(withAttributes attributes: [NSAttributedString.Key: Any]? = nil, size: CGSize? = nil) -> UIImage? {
        let size = size ?? (self as NSString).size(withAttributes: attributes)
        return UIGraphicsImageRenderer(size: size).image { _ in
            (self as NSString).draw(in: CGRect(origin: .zero, size: size),
                                    withAttributes: attributes)
        }
    }
}

// Then inside some function of yours
func someFunction() {
    if let urlScheme = URL(string: "instagram-stories://share") {
        
        if UIApplication.shared.canOpenURL(urlScheme) {
            
            let imageData: Data = UIImage(named: "bg")!.pngData()!
            
            let textImage: Data = "Shawn Test".image(withAttributes: [.foregroundColor: UIColor.red,
                                                                      .font: UIFont.systemFont(ofSize: 30.0)],
                                                     size: CGSize(width: 300.0, height: 80.0))!.pngData()!
            
            let items = ["com.instagram.sharedSticker.stickerImage": textImage,
                         "com.instagram.sharedSticker.backgroundImage": imageData]
            
            UIPasteboard.general.setItems([items])
            
            UIApplication.shared.open(urlScheme, options: [:], completionHandler: nil)
        }
    }
}

Затем я вижу это в историях IG с правильным фоном и текстом в виде наклейки, которую можно перемещать.

Единственным недостатком использования стикера является то, что вы не можете редактировать текст в Instagram.

Что касается исследования, то похоже, что единственный обходной путь для копирования текста/ссылки в монтажный стол при открытии IG Story — это использование:

      UIPasteboard.general.string = "your link here"

но делать это нужно с задержкой - например:

      UIApplication.shared.open(instagramStoryURL, options: [:]) { success in
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
        UIPasteboard.general.string = "your link here"
    }
}

чтобы попытаться убедиться, что он не переопределит:

      UIPasteboard.general.items

который содержит, например, "com.instagram.sharedSticker.stickerImage"

Кроме того, будьте осторожны с задержкой — поскольку в iOS есть некоторые ограничения конфиденциальности, позволяющие копировать данные в UIPasteboard , когда приложение находится в фоновом режиме (исходя из тестов, у нас есть менее 1 секунды, чтобы сделать это.

Это означает, что вы можете попробовать скопировать ссылку таким образом:

      override func viewDidLoad() {
    super.viewDidLoad()

    NotificationCenter.default.addObserver(self, selector: #selector(appMovedToBackground), name: UIApplication.willResignActiveNotification, object: nil)
}

@objc func appMovedToBackground() {
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.75) {
        UIPasteboard.general.string = "your link here"
    }
}

Так или иначе, есть одно явное неудобство.

Каждый раз, когда вы пытаетесь вызвать API «instagram-stories://share» в первый раз, вы сталкиваетесь с системным всплывающим окном, которое запрашивает разрешение на открытие Instagram, а также на вставку данных.

В этом случае мы потеряем, например, данные «com.instagram.sharedSticker.stickerImage» , так как по задержке они будут переопределены UIPasteboard.general.string.

Но мы могли бы сделать это ожидаемым для пользователей любым UI/UX решением с инструкциями/руководством.

Другие вопросы по тегам