2

I've taken over development of an app that is complete minus a bug requiring an internet connection to load images as it doesn't access them from the cache despite an attempt to do so.

Can anyone help me figure out what is going wrong in the following?

public class SpriteCache : Singleton<SpriteCache>
{
    Dictionary<string, Sprite> _cache = new Dictionary<string, Sprite>();

    public void LoadSprite(string url, Action<Sprite> callback)
    {
        StartCoroutine(LoadSpriteCoroutine(url, callback));
    }

    public IEnumerator LoadSpriteCoroutine(string url, Action<Sprite> callback)
    {
    if (_cache.ContainsKey(url))
    {
        callback(_cache[url]);
        yield break;
    }

    var www = new WWW(url);

    while (!www.isDone)
    {
        yield return www;
    }

    if (!string.IsNullOrEmpty(www.error))
    {
        Debug.LogErrorFormat("Tried to obtain texture at '{0}' but received error '{1}'", url, www.error);
        yield break;
    }

    var texture = www.texture;
    if (texture == null)
    {
        Debug.LogErrorFormat("No texture found at '{0}'!", url);
        yield break;
    }

    var sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(texture.width / 2, texture.height / 2));
    _cache[url] = sprite;
    callback(sprite);
}

edit:

A further explanation to clarify

var www = new WWW(url)

This grabs the images stored on a server which works, as far as I'm aware after one instance of grabbing the image this should place the item in cache for use later.

I've tried using the following updated method to see if that would fix it.

var www = WWW.LoadFromCacheOrDownload(url, 1)

This resulted in it not working in any capacity and never changing the images from the placeholders.

The first if statement in the "LoadSpriteCoroutine" is supposed to catch if the sprite already exists in the "_cache" Dictionary by checking if there is a key for the url, which there should be after the first running instance with and internet connection

Load image from _cache if its in there:

if (_cache.ContainsKey(url))
{
    callback(_cache[url]);
    yield break;
}

Add image to _cache if it wasn't previously in there:

var sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(texture.width / 2, texture.height / 2));
_cache[url] = sprite;
FMobius
  • 21
  • 5

1 Answers1

0

So I figured out a solution,

all the other methods of saving images to the cache seemed to fail for iOS, I removed all of the previous "_cache" stuff.

this function for saving worked for me:

//if file doesn't exist then save it for fututre reference
    if (!File.Exists(_FileLocation + texName))
    {
        byte[] bytes;

        if (Path.GetExtension(texName) == ".png")
        {
            bytes = texture.EncodeToPNG();
        }
        else
        {
            bytes = texture.EncodeToJPG();
        }
        File.WriteAllBytes(Application.persistentDataPath + texName, bytes);
    }

that section is placed after the "callback(sprite)".

The check for saved items is placed where the old "if(_cache.ContainsKey(url))" section was

 texName = Path.GetFileName(texName);

    if (File.Exists( _FileLocation + texName))
    {
        url = _FileLocation + "/"+ texName;
    }

please note that the "LoadSpriteCoroutine" now take a extra string argument 'texName' in its calls which is just the a shortened instance of the url which it then cuts to just the file name and extension. If it finds a match then it replaces url with a the persistent file path + the fileName to grab it locally opposed to over the network as normal.

_FileLocation is defined as follows

string _FileLocation;

public void Start()
{
    _FileLocation = Application.persistentDataPath;
}

The reason behind referencing it in that method is to save performance from calling the address though application AND if you were working on a cross platform solution then the data path for saving may need to be changed as such you could put a detection if or case statement to change _FileLocation to suit your needs.

FMobius
  • 21
  • 5