I have an issue I’m trying to figure out with my APIs.
So, I have all my APIs downloading on the main menu. I noticed if the player leaves the menu when there are still APIs that haven’t finished, while unlikely, there CAN be minor issues, it’s being used to populate soccer games and if the games haven’t downloaded there might be an issue on the main page… So, I need to check if the APIs have finished before you can load the main game, if they haven’t I’ll display a loading screen and an error if it takes too long…
There’s another reason I want to check, what if one of the APIs fails because of a connection issue? I’d like to check which ones have failed and call them again.
I have one issue, I have 9 different lists being populated with the API calls, most are custom classes. So I was going to put them in a list and check their lengths, but I can’t because they are all different variables. I tried using generics but couldn’t really get it working…
For the record, here is the script, I know it’s kinda a sloppy way to populate lists with APIs lol(if you have any better ideas, I’m all ears )
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
public class APICaller : MonoBehaviour
{
public List<Texture> flagSprites;
public List<League> leagues;
public List<Country> countries;
public List<Team> teams;
public List<LiveScores> scores;
public List<Season> seasons;
public List<Continent> continents;
public List<Fixture> fixtures;
public List<MatchStats> stats;
public Dictionary<int, Team> teamDictionary;
static APICaller _api;
public static APICaller api
{
get
{
return _api;
}
}
private void Awake()
{
_api = this;
DontDestroyOnLoad(gameObject);
}
private void Start()
{
RequestAPI("Leagues",leagues);
RequestAPI("Countries",countries);
RequestAPI("Teams",teams);
RequestAPI("Scores",scores);
RequestAPI("Seasons",seasons);
RequestAPI("Continents", continents);
RequestAPI("Fixtures", fixtures);
teamDictionary = new Dictionary<int, Team>();
for (int i = 0; i < teams.Count; i++)
{
teamDictionary.Add(teams[i].id,teams[i]);
}
}
public void RequestAPI<T>(string name,List<T> list)
{
StartCoroutine(WaitForServerResponse(name,list));
}
IEnumerator WaitForServerResponse<T>(string name,List<T> list)
{
using (UnityWebRequest req = UnityWebRequest.Get(URLRefs.url.GetURL(name)))
{
yield return req.SendWebRequest();
string[] pages = req.url.Split('/');
int page = pages.Length - 1;
switch (req.result)
{
case UnityWebRequest.Result.ConnectionError:
break;
case UnityWebRequest.Result.DataProcessingError:
Debug.LogError(pages[page] + ": Error: " + req.error);
break;
case UnityWebRequest.Result.ProtocolError:
Debug.LogError(pages[page] + ": HTTP Error: " + req.error + " " + name);
break;
case UnityWebRequest.Result.Success:
ApiResponse<T> response = JsonUtility.FromJson<ApiResponse<T>>(req.downloadHandler.text);
for (int i = 0; i < response.data.Count; i++)
{
list.Add(response.data[i]);
}
if (name == "Countries") PopulateFlags();
break;
}
}
}
void PopulateFlags()
{
for (int i = 0; i < countries.Count; i++)
{
StartCoroutine(GetSprites(countries[i].image_path, i));
}
}
IEnumerator GetSprites(string name, int index)
{
UnityWebRequest req = UnityWebRequestTexture.GetTexture(name);
{
yield return req.SendWebRequest();
string[] pages = req.url.Split('/');
int page = pages.Length - 1;
switch (req.result)
{
case UnityWebRequest.Result.ConnectionError:
break;
case UnityWebRequest.Result.DataProcessingError:
Debug.LogError(pages[page] + ": Error: " + req.error);
break;
case UnityWebRequest.Result.ProtocolError:
Debug.LogError(pages[page] + ": HTTP Error: " + req.error + " " + name);
break;
case UnityWebRequest.Result.Success:
flagSprites.Add(((DownloadHandlerTexture)req.downloadHandler).texture);
break;
}
}
}
}
Ideally I could have an array/list of bools and set it to true when the API is finished, then I could check this when you press the login button?
Thanks