2016-03-12 304 views
-3

我使用Spotify的API連續3個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-sequentially) – CouchDeveloper

+0

如果您想調用異步函數_sequentially_ - 即調用#1,等到完成然後檢索結果,調用#2(可能以結果#1作爲參數),等到結束,結果爲#2等 - - 必須有一個完成處理程序或其他方式通知調用者異步函數完成。 SO上已經有很多這樣的問題,也是很好的答案。 – CouchDeveloper

+0

您的問題_may_還可能包含一些特殊的「子問題:有一個_N_輸入數組(例如URL)會得到一個_N_對象數組。獲取每個對象需要調用一個異步函數。在SO上已經被回答了很多次 – CouchDeveloper

回答

0

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); return; } –

+0

我想我沒有提及,這是一個我很快做的項目,現在我在做目標c。但兩次都遇到同樣的問題。 @蔡志偉 –

+0

@SeanCalkins查看我更新的答案。 –

-4

首先,你怎麼做三個API調用,同時? 或者用戶首先選擇藝術家,然後撥打電話獲取相冊,然後顯示相冊,然後用戶選擇一個相冊併發出第三個請求?無論哪種方式,我建議您在Activity類中編寫AsyncTask類,然後您可以使用計數器等待三次調用完成,然後在onPostExecute()方法中可以構建一個Parcelable對象並傳遞它在束(intent.putExtra(authorObject)以接收它在第二活動的onCreate方法。

然後顯示請求的信息(我想你正在將其存儲在DB中的高速緩存)

+4

這個問題被標記爲iOS和Swift,而不是Android或Java –