Nachdem das Ganze prinzipiell funktionierte, tauchte prompt die nächste Hürde auf. Die Spotify Web
API limitiert nämlich die Zugriffe bei einer Playlist auf 100 Einträge. Ist die Liste länger, müssen weitere 'Seiten' des Paging-Objects nachgeladen und eingelesen werden. Die Frage war also, wie die weiteren Tracks dem Playlist-Objekt, soll heißen dem Array TPlaylist.Tracks.Items hinzugefügt werden können. Ich wollte nämlich keine zusätzliche 'externe' Liste für die Einträge anlegen, sondern nach Verlassen der Prozedur 'GetPlaylistTracks' sollte das Objekt 'Playlist' den kompletten Baum des von Spotify gelieferten Playlist-Objekts zur weiteren universellen Verwendung enthalten. Anderenfalls hätte man sich den ganzen Aufwand auch sparen können. Nach vielen Stunden mühsamer Recherche und viel Try & Error habe ich folgende Lösung gefunden:
Delphi-Quellcode:
Function TSpManager.SendRequest(accesspoint:string; offset: Integer = 0; Limit: Integer = 50):TJSONValue;
begin
result:= NIL;
If FAuthorized Then
begin
RESTRequest1.Params.ParameterByName('offset').Value:= offset.ToString;
RESTRequest1.Params.ParameterByName('limit').Value:= limit.ToString;
RESTRequest1.Resource:= AccessPoint;
RestRequest1.Execute;
result:= RestResponse1.JSONValue;
end else If NoSpotifyAccessMsg = mrYes Then AuthorizespotifyAccess;
end;
function TSpManager.GetPlaylistTracks(var Playlist: TPlaylist; PlaylistID: string): Boolean; //komplette Playlist-Daten holen
var
JValue,oitem: TJSONValue;
oItems: TJSONArray;
newitem: TPlaylisttrack;
offs,nextpos,totalItems: Integer;
begin
result := false;
offs:= 0;
JValue:= SendRequest('v1/playlists/' + PlaylistID);
if JValue is TJSONObject then
begin
playlist := TJson.JsonToObject<TPlaylist>(TJSONObject(JValue));
if playlist <> nil then
begin
totalItems:= playlist.Tracks.total;
offs:= length(playlist.Tracks.Items);
while offs < TotalItems do // nächste 'Seite' des Paging-Objects
begin
Jvalue:= SendRequest('v1/playlists/' + PlaylistID + '/tracks',offs,100);
If JValue is TJSONObject Then
begin
oItems := TJSONArray(TJSONObject(JValue).GetValue('items'));
// Erweitert das Array Playlist.Tracks.Items um oItems.count und liefert die bisherige Größe als Offset zurück:
nextpos:= playlist.IncreaseItems(oitems.count);
for oItem in oItems do
begin
newitem:= TJson.JsonToObject<TPlaylisttrack>(TJSONObject(oitem));
playlist.SetItem(newitem,nextpos); // schreibt newitem in das Array
inc(nextpos);
end;
end;
inc(offs, oitems.Count);
end;
end;
end;
result:= playlist <> NIL;
end;
Das funktioniert auch perfekt, und sogar die Performance (incl. Ladevorgang) ist akzeptabel. Aber wie immer, wenn ich so etwas zusammen gefrickelt habe, kommt die Frage auf, ob diese Lösung wirklich 'State of The Art' ist und es nicht womöglich effizienter und/oder eleganter geht
Gruß LP