2016-03-12 1 views
-3

Я бег три API вызовов с использованием Spotify API, для того, чтобы получить следующие данные и хранить их в мой Artist объекта:Как ждать асинхронных звонки закончить

  1. художника.
  2. Это альбомы исполнителя.
  3. Треки каждого альбома художника.

Как только все будет готово, я хотел бы передать объект другому контроллеру. Это выглядит примерно так: (Если можно было опубликовать все NSURLSession код там, если это необходимо)

func getArtist(artistName) { 
getAlbums(artistIdString)} 

func getAlbums(artistIdString) { 
a = Album 
Artist.albumsArray.append(a) 
for album in Artist.albumsArray { 
getTracks(albumIdString) 
} 
} 

func getTracks (albumIdString) { 
t = Track 
for album in Artist.albumsArray { 
    if idString == albumIdString { 
    album.append(t) 
    } 
} 
} 

func passArtist { 
DataStore.sharedInstance().Artist = Artist 
} 
+1

Возможный дубликат [Как выполнить две асинхронные функции последовательно] (http://stackoverflow.com/questions/35551771/how-to-execute-two-asynchronous-functions-sequential) – CouchDeveloper

+0

Если вы хотите вызвать асинхронный функции _sequential_ - то есть вызов # 1, дождитесь окончания, затем получите результат, вызовите # 2 (возможно, с результатом # 1 как параметр), дождитесь окончания, возьмите результат # 2 и т. д. - вы должны иметь обработчик завершения или другие средства для уведомления вызывающего абонента о завершении функции асинхронизации. Таких вопросов уже много, а также хороших ответов на SO. – CouchDeveloper

+0

Ваша проблема _may_ также содержит некоторую специальную «субарему»: наличие массива входов _N_ (например, URL-адресов) получает массив объектов _N_. Получение каждого объекта требует вызова асинхронной функции. Существуют также решения для этой проблемы, которые имеют ответил много раз на SO. – CouchDeveloper

ответ

0

В функции обратного вызова/блок (или обработчик завершения в терминах Apple) NSURLSession (или NSURLSessionDataTask), выполните проверку функционала на текущий объект Artist и посмотреть, были ли все 3 требуемые элементы (и если да, сделайте звонок passArtist).

Независимо от того, как выполняется окончательный заказ, он в конечном итоге назовет passArtist после того, как он выполнит выбор из 3 элементов, если вы это сделаете.

Вот простой пример, чтобы продемонстрировать идею в Objective-C (по запросу OP):

- (void)getArtistDataWithRequest:(NSURLRequest *)request 
{ 
    NSURLSession   *session = [NSURLSession sharedSession]; 
    NSURLSessionDataTask *task = [session dataTaskWithRequest:request 
               completionHandler:^(NSData  *data, 
                    NSURLResponse *response, 
                    NSError  *error) 
            { 
             if (error) 
             { 
              // Something went wrong, fallback. 
              NSLog(@"An error occurred: %@", error.localizedDescription); 

              // You could use some error handler e.g.: 
              // [self connectionDidFailWithError:error]; 

              return; 
             } 
             else if (response) 
             { 
              // Seems working, moving forward. 
              [self connectionDidReceiveSpotifyServerResponse:response 
                        andData:data]; 
             } 

            }]; 
    [task resume]; 
} 

- (void)connectionDidReceiveSpotifyServerResponse:(NSURLResponse *)aResponse 
              andData:(NSData *)aResponseData 
{ 
    // Do what you want here with the data you get, either it's album, track, 
    // or whatever. 

    // Assuming your "Artist" property is named "myArtist", and the "Artist" 
    // class has a method to process the data you get from Spotify API: 
    [_myArtist handleArtistData:aResponseData]; 

    // Now check your Artist object's element with another method. e.g.: 
    if ([_myArtist isLoadingComplete]) 
    { 
     // Done loading the object, pass it to view controller. 
    } 

    // Not yet done, do nothing for now. 
} 

Это только одно решение. Есть много способов добиться того, что вы хотели, как только получите идею.

+0

Мне очень жаль, что бы синтаксис был для этого?[Сессия dataTaskWithURL: [NSURL URLWithString: urlString] completionHandler:^(NSData * данные, NSURLResponse * ответ, NSError * ошибка) { если (ошибка = ноль!) { NSLog (@ "Произошла ошибка:% @ ", error.localizedDescription); возвращение; } –

+0

Думаю, я не упомянул, что это был проект, который я сделал быстро, и теперь делаю в объективе c. но я столкнулся с одной и той же проблемой одновременно. @ Zhi-Wei Cai –

+0

@SeanCalkins См. Мой обновленный ответ. –

-4

Во-первых, как вы делаете три API вызовов одновременно? Или пользователь выбирает сначала исполнителя, затем вы делаете звонок, чтобы получить альбомы, затем вы показываете альбомы, затем пользователь выбирает альбом и вы делаете третий запрос?

В любом случае, я предлагаю вам написать класс AsyncTask внутри класса Activity, тогда вы можете использовать счетчик, чтобы дождаться завершения трех вызовов, а затем по методу onPostExecute() вы можете построить объект Parcelable и передать это в комплекте (intent.putExtra (authorObject), чтобы получить его в OnCreate метод второй активности.

Затем отобразить информацию о запросе (я предполагаю, что вы храните его в БД для кэширования)

+4

вопрос отмечен iOS и Swift, а не Android или Java –

Смежные вопросы