Home > front end >  Xamarin iOS post image to Instagram
Xamarin iOS post image to Instagram

Time:01-11

Goal: Using an iOS native method, push a user made picture onto their Instagram feed in C#.

public bool ShareImage(byte[] imageByte)
        {
            bool result = false;

            //string fileName = "xxx.png";
            //string path = Path.Combine(FileSystem.CacheDirectory, fileName);
            //File.WriteAllBytes(path, imageByte);
            NSData data = NSData.FromArray(imageByte);
            UIImage image = UIImage.LoadFromData(data);
            
            //NSUrl url = NSUrl.FromString($"instagram://library?AssetPath={path}"); // Only opens
            NSUrl url = NSUrl.FromString($"instagram://library?LocalIdentifier={1}");
            if (UIApplication.SharedApplication.CanOpenUrl(url))
            {
                UIApplication.SharedApplication.OpenUrl(url);
            }
            return result;
        }

As far as I'm aware the way I have to do this is to save my image to the device and get a Local Identifier for this. I have constructed this from the snippets of objective-c code I have seen. Sharing photos only works with the native app installed, as I have learnt from my trials to get the facebook module working.

Edit: Using PHAssetChangeRequest from the iOS Photos namespace does not work. A collegue has pointed out to me about the possibility of saving then using a photo picker to get the PHAsset for the Local Identifier. But this is an extra step I do not want the users of the App to go through. Better to just remove Instagram support as I just can go through the generic share method as shown below. The disadvantage of this method is that the user has then to pick the medium to share over.

public async void ShareImage(byte[] imageByte)
        {
            string fileName = "xxx.png";
            string path = Path.Combine(FileSystem.CacheDirectory, fileName);
            File.WriteAllBytes(path, imageByte);
            await Share.RequestAsync(
                new ShareFileRequest()
                {
                    File = new ShareFile(path),
                    Title = "xxx"
                }
                );
        }

Edit 2 Tried a different way using UIDocumentInteractionController but it is showing nothing and not posting, it is not throwing any exceptions to give me any clues as to what I'm doing wrong.

public bool ShareImage(byte[] imageByte)
        {
            bool result = false;

            string fileName = "xxx.igo";
            string path = Path.Combine(FileSystem.CacheDirectory, fileName);
            File.WriteAllBytes(path, imageByte);
            //string caption = "xxx";
            string uti = "com.instagram.exclusivegram";
            UIImageView view = new UIImageView();
            //UIDocumentInteractionController controller = UIDocumentInteractionController.FromUrl(NSUrl.FromString(path));
            UIDocumentInteractionController controller = new UIDocumentInteractionController
            {
                //controller.Url = NSUrl.FromString(path);
                Url = NSUrl.FromFilename(path),
                Uti = uti
            };
            //CoreGraphics.CGRect viewDimensions = new CoreGraphics.CGRect(0, 0, 200, 100);
            
            _ = controller.PresentOpenInMenu(CoreGraphics.CGRect.Empty, view, true);
            //_ = controller.PresentOpenInMenu(viewDimensions, view, true);
            return result;
        }

Edit 3 Using

UIView view = new UIImageView();
            if (UIApplication.SharedApplication.KeyWindow.RootViewController is UIViewController uiController && uiController.View != null)
            {
                view = uiController.View;
            }

I was able to get the possible share options to show. I was logged in to Instagram using the native App, but the post did not show.

CodePudding user response:

  1. Change

    Url = NSUrl.FromFilename(path)

    to

    Url = new NSUrl(path,false)

    The second way is pointing to the correct file path not the file name .

  2. Change

    controller.PresentOpenInMenu(CoreGraphics.CGRect.Empty, view, true);

    to

    controller.PresentOptionsMenu(UIScreen.MainScreen.Bounds, (UIApplication.SharedApplication.Delegate as AppDelegate).Window, true);

    Show UIDocumentInteractionController inside current Window and set the proper frame.

  •  Tags:  
  • Related