Search code examples
xamarinxamarin.formsxamarin.iosxamarin-studio

Download path in Xamarin iOS


I am using Xamarin.Forms and written the code to download the file for the iOS platform. It is downloading the file successfully without any error. But after downloading it, I am not able to find the downloaded file in my apple device.

During debugging I found that it is showing

/var/mobile/Containers/Data/Application/1234567A-B8CD-9EF9-C850-9G73587DC7C/Documents/XF_Downloads/hausmann_abcd.jpg

path. So at which location file get saved? below is the image for the same.

enter image description here

I have written below code for this

public class IosDownloader : IDownloader
{
    public event EventHandler<DownloadEventArgs> OnFileDownloaded;

    public void DownloadFile(string url, string folder)
    {
        string pathToNewFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), folder);
        Directory.CreateDirectory(pathToNewFolder);

        try
        {
            WebClient webClient = new WebClient();
            webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);
            string pathToNewFile = Path.Combine(pathToNewFolder, Path.GetFileName(url));
            webClient.DownloadFileAsync(new Uri(url), pathToNewFile);
        }
        catch (Exception ex)
        {
            if (OnFileDownloaded != null)
                OnFileDownloaded.Invoke(this, new DownloadEventArgs(false));
        }
    }

    private void Completed(object sender, AsyncCompletedEventArgs e)
    {
        if (e.Error != null)
        {
            if (OnFileDownloaded != null)
                OnFileDownloaded.Invoke(this, new DownloadEventArgs(false));
        }
        else
        {
            if (OnFileDownloaded != null)
                OnFileDownloaded.Invoke(this, new DownloadEventArgs(true));
        }
    }
}

Solution

  • When a file is saved on an application it is a temporary url within the app's sandbox. To make this image file be publicly accessible through Apple's Photos, You'll have to use native code to do a request to add a new PHImageAsset to the photos library.

    In forms you would need to access the native frameworks and therefore run native code. There are plenty of examples of doing this online if you don't know how to already. But here is an introduction if you want to run native code within a shared code framework. https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/dependency-service/introduction

    Here is a sample of taking that temp file URL and saving it to Photos Framework once you can code w/ native Xamarin.iOS frameworks:

        public void AddImageUrlToPhotosLibrary(string urlToSaveToPhotos)
        {
            PHPhotoLibrary.SharedPhotoLibrary.PerformChanges(() => {
    
                //This is bound to native https://developer.apple.com/documentation/photokit/phassetchangerequest/1624060-creationrequestforasset
                //Parameter is an NSURL of path to image.
                PHAssetChangeRequest.FromImage(new NSUrl(urlToSaveToPhotos));
    
            }, (completed, error) => {
    
                if (completed)
                {
                    if (error != null)
                    {
                        Console.WriteLine($"Failed saving image asset {error.LocalizedDescription}");
                    } else
                    {
                        Console.WriteLine($"Successfully saved image to photos library.");
                    }
                }
            });
        }