What is the proper way of retrieving all SPTracks of an playlist in Cocoalibspotify?

StackOverflow https://stackoverflow.com/questions/16184996

  •  11-04-2022
  •  | 
  •  

質問

I'm writing an iPhone app that uses cocoalibspotify. In one of my views I want to be able to display all the SPTracks of a playlist in a table view. Each cell should display the Artist, the Album and the Name of the track. I have implemented a method which retrieves the playlist content asynchronously but I haven't figured out the proper way to perform the "converting" of SPPlaylistItems into SPTrack objects on the background thread. As a result, my UI lags everytime I retrieve playlist tracks. Granted, the lag is very minor but it's still annoying. Here is my method that retrieves playlist content.

-(void)getPlaylistContentAsynchronouslyOfPlaylist:(NSString *)playlistName callback:(void (^)(NSArray *playlistTracks))block{
    NSLog(@"Getting content ansynchronously...");
    NSMutableArray *mutableArray = [[NSMutableArray alloc] init];
    SPPlaylist *playlist = [self getPlaylistWithName:playlistName];
    __block BOOL addedAllTracks = mutableArray.count == playlist.items.count;
    for (SPPlaylistItem *item in playlist.items){
        NSLog(@"----Checking Track with url %@", item.itemURL.absoluteString);
        NSURL *trackURL = [item.item spotifyURL];
        [[SPSession sharedSession]trackForURL:trackURL callback:^(SPTrack * spotifyTrack){
            if(spotifyTrack){
                //NSLog(@"---->>>Adding Track with url %@", item.itemURL.absoluteString);
                [mutableArray addObject:spotifyTrack];
            }

            if (mutableArray.count == playlist.items.count){
                //NSLog(@"!!!!!!!Added all songs!");
                addedAllTracks = YES;
            }
        }];
    }

    dispatch_async(self.backgroundQueue, ^{
        NSLog(@"Retrieving playlist content asynchronously...");
        while (!addedAllTracks){
            NSLog(@"<><><><>BG Queue is waiting....");
            [NSThread sleepForTimeInterval:0.25];
        }

        if (block){
            NSLog(@"Done retrieving playlist content asynchronously");
            NSLog(@"*******Passing %d tracks to the caller", mutableArray.count);
            dispatch_async(dispatch_get_main_queue(), ^() { block(mutableArray); });
        }
    });
}

To retrieve the SPTrack from the SPPlaylistItem I use the SPSession's trackForURL method. In this method's callback I add the track to an array. This is where the problem is: adding these objects in the main thread is causing a bit of a lag. So my question is:

  1. Is this the proper way of retrieving all the SPTrack objects inside an SPPlaylist? If not, what is the correct way to do this on a background thread so that my UI isn't blocked?

Any help is appreciated thank you!

役に立ちましたか?

解決

Creating a new track via the URL is incredibly inefficient — the SPPlaylistItem contains the track itself.

Replace the part where you get the track by URL with something like this and you should be fine:

for (SPPlaylistItem *item in playlist.items) {
    if (item.itemClass == [SPTrack class])
        [mutableArray addObject:item.item];
}

Also, it's worth noting that fetching all of the tracks from a playlist at once is a fairly bad idea — playlists get very large, and holding onto 10,000 tracks when you've only got 20 or so onscreen at once is going to make you run out of memory fairly quickly.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top