1. Anuncie Aqui ! Entre em contato fdantas@4each.com.br

[Flutter] receive_sharing_intent_plus flutter not working, only when sharing from a screenshot...

Discussão em 'Mobile' iniciado por Stack, Outubro 10, 2024 às 11:22.

  1. Stack

    Stack Membro Participativo

    I am using flutter receive_sharing_intent_plus i tested it in android and it works perfect, also in IOS, the only problem is when taking a screenshot with IOS and sharing it directly from the pop up the app don't open and a small pop up that have post and cancel appears, then it disappears and nothing happens in the console.

    I tried changing the redirect to app function and changed the way it handles the files, yet nothing any help

    This is the ShareViewController.swift

    import UIKit
    import Social
    import MobileCoreServices
    import Photos

    class ShareViewController: SLComposeServiceViewController {
    var hostAppBundleIdentifier = ""
    var appGroupId = ""
    let sharedKey = "ShareKey"
    var sharedMedia: [SharedMediaFile] = []
    var sharedText: [String] = []
    let imageContentType = kUTTypeImage as String
    let videoContentType = kUTTypeMovie as String
    let textContentType = kUTTypeText as String
    let urlContentType = kUTTypeURL as String
    let fileURLType = kUTTypeFileURL as String

    override func isContentValid() -> Bool {
    return true
    }

    private func loadIds() {
    let shareExtensionAppBundleIdentifier = Bundle.main.bundleIdentifier!
    if let lastIndexOfPoint = shareExtensionAppBundleIdentifier.lastIndex(of: ".") {
    hostAppBundleIdentifier = String(shareExtensionAppBundleIdentifier[..<lastIndexOfPoint])
    }
    appGroupId = (Bundle.main.object(forInfoDictionaryKey: "AppGroupId") as? String) ?? "group.\(hostAppBundleIdentifier)"
    }

    override func viewDidLoad() {
    super.viewDidLoad()
    loadIds()
    }

    override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    if let content = extensionContext?.inputItems[0] as? NSExtensionItem {
    if let contents = content.attachments {
    for (index, attachment) in contents.enumerated() {
    print("Processing attachment at index \(index) with type identifiers: \(attachment.registeredTypeIdentifiers)")

    if attachment.hasItemConformingToTypeIdentifier(imageContentType) {
    handleImages(content: content, attachment: attachment, index: index)
    } else if attachment.hasItemConformingToTypeIdentifier(textContentType) {
    handleText(content: content, attachment: attachment, index: index)
    } else if attachment.hasItemConformingToTypeIdentifier(fileURLType) {
    handleFiles(content: content, attachment: attachment, index: index)
    } else if attachment.hasItemConformingToTypeIdentifier(urlContentType) {
    handleUrl(content: content, attachment: attachment, index: index)
    } else if attachment.hasItemConformingToTypeIdentifier(videoContentType) {
    handleVideos(content: content, attachment: attachment, index: index)
    }
    }
    }
    }
    }

    override func didSelectPost() {
    print("didSelectPost")
    }

    override func configurationItems() -> [Any]! {
    return []
    }

    private func handleText(content: NSExtensionItem, attachment: NSItemProvider, index: Int) {
    attachment.loadItem(forTypeIdentifier: textContentType, options: nil) { [weak self] data, error in
    if error == nil, let item = data as? String, let this = self {
    this.sharedText.append(item)
    this.redirectToHostApp(type: .text)
    } else {
    self?.dismissWithError()
    }
    }
    }

    private func handleUrl(content: NSExtensionItem, attachment: NSItemProvider, index: Int) {
    attachment.loadItem(forTypeIdentifier: urlContentType, options: nil) { [weak self] data, error in
    if error == nil, let item = data as? URL, let this = self {
    this.sharedText.append(item.absoluteString)
    this.redirectToHostApp(type: .text)
    } else {
    self?.dismissWithError()
    }
    }
    }

    private func handleImages(content: NSExtensionItem, attachment: NSItemProvider, index: Int) {
    attachment.loadItem(forTypeIdentifier: imageContentType, options: nil) { [weak self] data, error in
    if error == nil, let url = data as? URL, let this = self {

    // Log the URL of the image (whether from the gallery or screenshot)
    print("Handling image from URL: \(url)")

    let fileName = this.getFileName(from: url, type: .image)
    let newPath = FileManager.default
    .containerURL(forSecurityApplicationGroupIdentifier: this.appGroupId)!
    .appendingPathComponent(fileName)
    let copied = this.copyFile(at: url, to: newPath)

    if copied {
    this.sharedMedia.append(SharedMediaFile(path: newPath.absoluteString, thumbnail: nil, duration: nil, type: .image))

    // Redirect after processing the image
    DispatchQueue.main.async {
    this.redirectToHostApp(type: .media)
    }
    } else {
    self?.dismissWithError()
    }
    } else {
    self?.dismissWithError()
    }
    }
    }

    private func handleVideos(content: NSExtensionItem, attachment: NSItemProvider, index: Int) {
    attachment.loadItem(forTypeIdentifier: videoContentType, options: nil) { [weak self] data, error in
    if error == nil, let url = data as? URL, let this = self {
    let fileName = this.getFileName(from: url, type: .video)
    let newPath = FileManager.default
    .containerURL(forSecurityApplicationGroupIdentifier: this.appGroupId)!
    .appendingPathComponent(fileName)
    let copied = this.copyFile(at: url, to: newPath)
    if copied {
    guard let sharedFile = this.getSharedMediaFile(forVideo: newPath) else { return }
    this.sharedMedia.append(sharedFile)
    this.redirectToHostApp(type: .media)
    } else {
    self?.dismissWithError()
    }
    } else {
    self?.dismissWithError()
    }
    }
    }

    private func handleFiles(content: NSExtensionItem, attachment: NSItemProvider, index: Int) {
    attachment.loadItem(forTypeIdentifier: fileURLType, options: nil) { [weak self] data, error in
    if error == nil, let url = data as? URL, let this = self {
    let fileName = this.getFileName(from: url, type: .file)
    let newPath = FileManager.default
    .containerURL(forSecurityApplicationGroupIdentifier: this.appGroupId)!
    .appendingPathComponent(fileName)
    let copied = this.copyFile(at: url, to: newPath)
    if copied {
    this.sharedMedia.append(SharedMediaFile(path: newPath.absoluteString, thumbnail: nil, duration: nil, type: .file))
    }
    if index == (content.attachments?.count)! - 1 {
    let userDefaults = UserDefaults(suiteName: this.appGroupId)
    userDefaults?.set(this.toData(data: this.sharedMedia), forKey: this.sharedKey)
    userDefaults?.synchronize()
    this.redirectToHostApp(type: .file)
    }
    } else {
    self?.dismissWithError()
    }
    }
    }

    private func dismissWithError() {
    print("[ERROR] Error loading data!")
    let alert = UIAlertController(title: "Error", message: "Error loading data", preferredStyle: .alert)
    let action = UIAlertAction(title: "Error", style: .cancel) { _ in
    self.dismiss(animated: true, completion: nil)
    }
    alert.addAction(action)
    present(alert, animated: true, completion: nil)
    extensionContext?.completeRequest(returningItems: [], completionHandler: nil)
    }

    private func redirectToHostApp(type: RedirectType) {
    loadIds()
    let url = URL(string: "ShareMedia-\(hostAppBundleIdentifier)://dataUrl=\(sharedKey)#\(type)")
    var responder = self as UIResponder?
    let selectorOpenURL = sel_registerName("openURL:")
    while responder != nil {
    if responder?.responds(to: selectorOpenURL) == true {
    let _ = responder?.perform(selectorOpenURL, with: url)
    }
    responder = responder?.next
    }
    extensionContext?.completeRequest(returningItems: nil, completionHandler: nil)
    }

    enum RedirectType {
    case media
    case text
    case file
    }

    func getExtension(from url: URL, type: SharedMediaType) -> String {
    let parts = url.lastPathComponent.components(separatedBy: ".")
    var ex: String? = nil
    if parts.count > 1 {
    ex = parts.last
    }
    if ex == nil {
    switch type {
    case .image:
    ex = "PNG"
    case .video:
    ex = "MP4"
    case .file:
    ex = "TXT"
    }
    }
    return ex ?? "Unknown"
    }

    func getFileName(from url: URL, type: SharedMediaType) -> String {
    var name = url.lastPathComponent
    if name.isEmpty {
    name = UUID().uuidString + "." + getExtension(from: url, type: type)
    }
    return name
    }

    private func copyFile(at sourceURL: URL, to destinationURL: URL) -> Bool {
    do {
    if FileManager.default.fileExists(atPath: destinationURL.path) {
    try FileManager.default.removeItem(at: destinationURL)
    }
    try FileManager.default.copyItem(at: sourceURL, to: destinationURL)
    return true
    } catch {
    print("Error copying file: \(error)")
    return false
    }
    }

    func getSharedMediaFile(forVideo: URL) -> SharedMediaFile? {
    let asset = AVURLAsset(url: forVideo)
    let duration = asset.duration
    let durationTime = CMTimeGetSeconds(duration)
    return SharedMediaFile(path: forVideo.absoluteString, thumbnail: nil, duration: durationTime, type: .video)
    }

    private func toData<T: Codable>(data: T) -> Data? {
    do {
    let jsonData = try JSONEncoder().encode(data)
    return jsonData
    } catch {
    print(error.[text](`https://stackoverflow.com`)localizedDescription)
    }
    return nil
    }
    }```

    Continue reading...

Compartilhe esta Página