#ios #spotify
#iOS #spotify
Вопрос:
Я запускаю цикл for вокруг блока, который запрашивает данные с серверов Spotify. При вызове tracksLoaded иногда все выполняется внутри блока, а в других случаях пропускается один или несколько запросов. Переход в спящий режим улучшает ситуацию, но я почти уверен, что должен быть лучший способ справиться с этим.
//From each given array of countryURLs, generate a playlist of songs
- (void)generatePlaylistFromURL:(NSMutableArray *)countryURLS {
NSMutableArray *regionPlaylist = [[NSMutableArray alloc] init];
//loop through all the Countries in one Region
for (int k=0; k<[countryURLS count]; k ) {
sleep(.2);
//request playlist from Country URI
[SPTRequest requestItemAtURI:[NSURL URLWithString:[@"spotify:user:funkytrumpet:playlist:" stringByAppendingString:[[countryURLS objectAtIndex:k] componentsSeparatedByString:@"/"][6]]]
withSession:session
callback:^(NSError *error, id object) {
if (error != nil) {
NSLog(@"*** Playlist lookup got error %@", error);
NSLog(@"id of playlist error:%@", [[countryURLS objectAtIndex:k] componentsSeparatedByString:@"/"][6]);
return;
}
//loop through all tracks in one Country and create array of track URIs
for (int i = 0; i < [[[object firstTrackPage] items] count]; i ) {
//NSLog(@"playlist: %@", [[[object firstTrackPage] items] objectAtIndex:(i)]);
[regionPlaylist addObject:[[[object firstTrackPage] items] objectAtIndex:(i)]];
}
//only play next track if this is the last album to load
if (k == ([countryURLS count]-1)) {
[self tracksLoaded:(regionPlaylist)];
}
}];
}
}
Ответ №1:
Да, спать ужасно. На ум приходят два решения.
Во-первых, необходимо последовательно загружать URL-адреса, используя то, что можно в некотором роде описать как асинхронный рекурсивный цикл. Псевдокод (не ожидайте, что он будет компилироваться, но вы должны уловить идею):
@property (nonatomic, readwrite) NSMutableArray *urisToLoad;
@property (nonatomic, readwrite) NSMutableArray *loadedObjects;
-(void)viewDidLoad {
self.loadedObjects = [NSMutableArray new];
self.urisToLoad = …;
[self recursivelyLoadObjects];
}
-(void)recursivelyLoadObjects {
if (self.urisToLoad.count == 0) {
[self objectsDone];
return;
}
id nextURI = self.urisToLoad[0];
[self.urisToLoad removeObjectAtIndex:0];
[SPTRequest requestItemAtURI:nextURI
withSession:session
callback:^(NSError *error, id object) {
// You should probably error check and stuff here.
[self.loadedObjects addObject:object];
[self recursivelyLoadObjects];
}];
}
-(void)objectsDone {
// All of the objects are now loaded (or failed to load)
NSLog(@"%@", self.loadedObjects);
}
Второе решение — изучить реактивное программирование с использованием библиотеки, подобной ReactiveCocoa. Вы можете настроить цепочку сигналов, которые загружают каждый URI, а затем получать уведомления, когда все сигналы сработают.
Комментарии:
1. Спасибо, я внедрил рекурсивную опцию, и она работает хорошо.
2. Круто, приятно знать. Пожалуйста, поддержите / примите этот ответ как правильный!