3

I'm trying to open an image in Instagram's sharing flow without having to download the image into the Photo Library. These two approaches work but they have downsides:

First Approach: This approach saves the image in a temporary location. It then uses UIDocumentInteractionController to open the image in Instagram's sharing flow. The problem here is that multiple apps are shown once the UIDocumentInteractionController is presented, I want to avoid this.

var documentController: UIDocumentInteractionController!
func shareToInstagram(image: UIImage) {
        DispatchQueue.main.async {
            let instagramURL = URL(string: "instagram://app")
            if UIApplication.shared.canOpenURL(instagramURL!) {
                let imageData = UIImageJPEGRepresentation(image, 100)
                let writePath = (NSTemporaryDirectory() as NSString).appendingPathComponent("instagram.igo")

                do {
                    try imageData?.write(to: URL(fileURLWithPath: writePath), options: .atomic)
                } catch {
                    print(error)
                }

                let fileURL = URL(fileURLWithPath: writePath)
                documentController = UIDocumentInteractionController(url: fileURL) 
                documentController.uti = "com.instagram.exlusivegram"
                documentController.presentOpenInMenu(from: self.view.bounds, in: self.view, animated: true)

            } else {
                print(" Instagram is not installed ")
            }
        }
    }

Second Approach: This is a nice approach because it does not use UIDocumentInteractionController, instead it immediately opens the image inside the Instagram sharing flow. The problem with this approach is that you must first save the image into the Photo Library, something I want to avoid.

func shareImage() {
        let fetchOptions = PHFetchOptions()
        fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
        let fetchResult = PHAsset.fetchAssets(with: .image, options: fetchOptions)
        guard let lastAsset = fetchResult.firstObject else { return }
        let localIdentifier = lastAsset.localIdentifier
        let u = "instagram://library?LocalIdentifier=" + localIdentifier
        let url = URL(string: u)!
        if UIApplication.shared.canOpenURL(url) {
            UIApplication.shared.open(url, options: [:], completionHandler: nil)
        } else {
            print("Error")
        }
    }

I'm wondering if there is a way to use the second approach without having to save the image into the Photo Library? The first approach seems to save it into a temporary directory first, would it be possible to do this in the second approach?

Thank you

Jay
  • 43
  • 4
  • 1
    Although Instagram's `LocalIdentifier` hook is fairly undocumented, it seems to rely on an identifier from a `PHAsset`, which can only be acquired if a photo is in the Photo Library. Therefore, I don't think you could use the second method by saving a photo to a temporary location, since then it wouldn't be in the Photo Library and thus would not be assigned a `PHAsset.localIdentifier`. – aaplmath Aug 14 '18 at 01:23
  • @aaplmath that makes a lot of sense, thank you for clearing that up! – Jay Aug 14 '18 at 19:01
  • Hey @Jay just wondering what you ended up going with here? I'm facing a similar issue and I'd like to avoid saving the image locally, especially since Apple's review team doesn't seem to like that. – CristianMoisei Sep 24 '20 at 11:38

0 Answers0