0

I've been struggling with this for a while now and was looking around for some advice from anyone who's worked with CocoaLibSpotify on iOS (iOS 7 to be exact).

I'm trying to load all the (SPTrack) items in a SPPlaylist. I've looked though the example code and the documentation so I know the best way to observe things is with KVO, however I can't see how that's the best way here.

Looking at the "Guess the Into" example and other sources on GitHub and the web in general, the precess I'm doing is as follows:

  1. Get the SPPlaylist (this is either directly from a the users playlists or created from a saved URL),
  2. Load the playlist with SPAsyncLoading,
  3. Loop though the SPPlaylistItems returned in the SPPlaylist and get all the SPTrack objects,
  4. Pass the array of SPTrack objects into another SPAsyncLoading call,
  5. Display all items from the loadedItems array.

Step 5 is where things seem to go wrong. Sometimes it is fine and I get all the tracks in the playlist displaying. However most of the time it doesn't load them, or only load a few (normally very little).

I've noticed that restarting the phone can sometimes make it work. Though after running the app (or changing the playlist) a couple of time, it stops working again.

When I log each step I get something like the following:

-[ViewController sessionDidLoginSuccessfully:]
Load playlist with URL: spotify:user:XXXXX:playlist:XXXXXXXXXXXXXXXXXXXXXX
Created playlist: <SPPlaylist: 0x16775bc0>: (null) (0 items)
Loaded playlist: <SPPlaylist: 0x16775bc0>: Playlist Name (59 items)
Created SPTrack items: 59
Loaded SPTrack items: 1
Failed to load SPTrack items: 58

As you can see, the user is logged on, with a valid session. Each step works according to plan until the end. Sometimes even if it does load a track, it won't allow me to play it anyway as well returning SP_TRACK_AVAILABILITY_UNAVAILABLE.

I've also added a code snippet below if it helps. But any help would be grateful at this point with this.

Thanks.

- (void)loadPlaylist
{
    __weak NSURL *spotifyURL = <URL from saved SPPlaylist>;
    NSLog(@"Load playlist with URL: %@", spotifyURL);
    [SPPlaylist playlistWithPlaylistURL:spotifyURL inSession:[SPSession sharedSession] callback:^(SPPlaylist *playlist) {
        _spotifyPlaylist = playlist;
        NSLog(@"Created playlist: %@", _spotifyPlaylist);
        [SPAsyncLoading waitUntilLoaded: _spotifyPlaylist timeout:kSpotifyTimeout then:^(NSArray *loadedItems, NSArray *notLoadedItems) {
        NSLog(@"Loaded playlist: %@", _spotifyPlaylist);
        if ([loadedItems count] > 0)
            [self loadSpotifyPlaylist];
        }];
    }];
}

- (void)loadSpotifyPlaylist
{
    NSArray *tracksArray = [self tracksFromPlaylistItems:[_spotifyPlaylist items]];
    NSLog(@"Created SPTrack items: %d", [tracksArray count]);

    if (tracksArray && [tracksArray count] > 0)
    {
        [SPAsyncLoading waitUntilLoaded:tracksArray timeout:kSpotifyTimeout then:^(NSArray *loadedItems, NSArray *notLoadedItems) {
            _playlist = loadedItems;
            NSLog(@"Loaded SPTrack items: %d", [loadedItems count]);
            NSLog(@"Failed to load SPTrack items: %d", [notLoadedItems count]);

        [self finishReloadData];
    }];
}

_spotifyPlaylist and _playlist are both strong instances and tracksFromPlaylistItems: is the same method used in the "Guess the Info" sample code.

Edit: The kSpotifyTimeout timeout is set to 10.0.

Baza207
  • 2,123
  • 1
  • 22
  • 40

1 Answers1

0

What's your value of kSpotifyTimeout? I think what you're seeing is simply the fact that metadata can take a long time to load (especially yesterday when the Spotify backend seemed to be having trouble, which can happen from time to time).

Generally, loading the entire contents of a playlist at once is bad practice, and you'll see that Guess the Intro doesn't actually care whether all the tracks loaded or not - it just grabs what happened to load and uses those tracks for the game.

A good approach to take is to paginate loading of playlist tracks to match your UI. That is, to only load the tracks your user can see, plus maybe a "screen" or two's worth up and down. As the user scrolls, you can start loading tracks - UIScrollViewDelegates -scrollViewWillEndDragging:withVelocity:targetContentOffset: is particularly good for this, as it lets you see where the user will "land" and start to load tracks for that point. There's some example code for doing this as well as a helper class called SPSparseArray for partially loading content like playlists on the dev branch of CococaLibSpotify (although be aware that dev branch = beta quality).

iKenndac
  • 18,730
  • 3
  • 35
  • 51
  • `kSpotifyTimeout` is currently `10.0`. What you're saying is what I thought it might be. I did up the timeout to `200.0` once on a small playlist but it didn't help. I'll have a look into paging results and see if that helps though this seemed to be happening even with small playlists. Thanks for the help. – Baza207 Feb 18 '14 at 08:22
  • Sadly I still seam to be having issues. Even when loading 10 items at a time I still only get 1-2/10 items being returned as loaded. I've tried several playlist and I get the same results. Any other suggestions? – Baza207 Feb 18 '14 at 10:23
  • I've seen that the metadata API has been acting up for the past day or so. It's likely a temporary service problem. – iKenndac Feb 18 '14 at 12:24
  • Yeah, just got back from being in town for a couple of hours and it all working fine. Thanks for the help and suggestions. I now have a nice paging class. :) – Baza207 Feb 18 '14 at 13:25