4

I have an Mvx base iOS project which is having problems with image downloads.

I have a couple of screens which contain UICollectionViews and the UICollectionViewCells use MvxDynamicImageHelpers to set the Image of their UIImageViews to images hosted on the internet (Azure blob storage via Azure CDN in actual fact). I have noticed that the images sometimes do not appear and that this is more common on a slow connection and if I scroll through the whole UICollectionView while the images are loading - presumably as it initiates a large number of simultaneous downloads. Restarting the app causes some, but not all, of the images to be shown.

Looking in the Caches/Pictures.MvvmCross folder I see there are a number of files with .tmp extensions and some without .tmp extensions but a 0 byte file size. I presume that the .tmp files are the ones that are re-downloaded following an app restart and that an invalid in-memory cache entry is causing them not to be re-downloaded until this happens.

I have implemented my versions of MvxDownloadRequest and MvxHttpFileDownloader and registered my IMvxHttpFileDownloader. The only modification in MvxHttpFileDownloader is to use my MvxDownloadRequest instead of the standard Mvx one.

As far as I can see, there are no exceptions being thrown in MvxDownloadRequest.Start or MvxDownloadRequest.ProcessResponse and MvxDownloadRequest.FileDownloadFailed is not being called. Having replaced MvxDownloadRequest.Start with the following, all images are always downloaded and displayed successfully:

        try
        {
            ThreadPool.QueueUserWorkItem((state) => {
                try
                {
                    var fileService = this.GetService<IMvxSimpleFileStoreService>();
                    var tempFilePath = DownloadPath + ".tmp";

                    var imageData = NSData.FromUrl(NSUrl.FromString(Url));

                    var image = UIImage.LoadFromData(imageData);

                    NSError nsError;
                    image.AsPNG().Save(tempFilePath, true, out nsError);

                    fileService.TryMove(tempFilePath, DownloadPath, true);
                }
                catch (Exception exception)
                {
                    FireDownloadFailed(exception);
                    return;
                }

                FireDownloadComplete();
            });
        }
        catch (Exception e)
        {
            FireDownloadFailed(e);
        }

So, what could be causing the problems with the standard WebRequest which is not affecting the above version? I'm guessing it's something to with GC and will do further debugging when I get time, but this won't be fore a while unfortunately. Would be very much appreciated if someone can answer this or provide pointers for when I do look at it.

Thanks,

J

1 Answers1

1

From the description of your investigations so far, it sounds like you have isolated the problem down to the level that httpwebrequest sometimes fails, but that the NSData methods are 100% reliable.

If this is the case, then it would suggest that the problem is somewhere in the xamarin.ios network stack or in the use of it.

It might be worth checking the xamarin bugzilla repository and also asking their support team if they are aware of any issues in this area. I believe they did make some announcements about changes to the iOS networking at evolve - see the CFNetworkHandler part late in the video and slides at http://xamarin.com/evolve/2013#session-b3mx6e6rmb - and there are worrying questions on here like iPhone app gets into a state where network requests never complete

Beyond that, I'd guess the first step in any debugging would be to isolate the issue in a simple test app - eg a simple app which just downloads one image at a time and which demonstrates a simple pass/fail for each technique. If you can replicate the issue in a small test app, then it'll be much quicker to work out what the issue is.

Community
  • 1
  • 1
Stuart
  • 66,722
  • 7
  • 114
  • 165