2013-03-30 72 views
1

我正在開發用於播放音樂的跨源解決方案(請參閱project on Github)。每個所謂的「內容源」都有通過搜索查詢獲取曲目,專輯和藝術家的方法(在SMKContentSource protocol中定義)。這些方法異步工作,並要求傳遞一個完成處理程序,它接受一個結果或一個NSError。SPSearch鍵值觀察和塊

目前我正在實施Spotify的內容源。下面的代碼行已經工作得很好,但在我看來,這是一個有點冒險的解決方案:

SPSession *strongSelf = weakSelf; 
    dispatch_async([SMKSpotifyContentSource spotifyLocalQueue], ^{ 
     __block SPSearch *search = [[SPSearch alloc] initWithSearchQuery:predicate inSession:strongSelf]; 
     [search addObservationKeyPath:@"loaded" options:0 block:^(MAKVONotification *notification) { 
      handler(search.albums, nil, nil); 
      [search removeAllObservers]; 
      search = nil; 
     }]; 
     dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(SMKSpotifyDefaultLoadingTimeout * NSEC_PER_SEC)); 
     dispatch_after(popTime, [SMKSpotifyContentSource spotifyLocalQueue], ^{ 
      if (search) { 
       handler(nil, nil, [NSError errorWithDomain:SMKSpotifyErrorDomain code:SMKSpotifyLoadingTimeoutErrorCode userInfo:nil]); 
       [search removeAllObservers]; 
       search = nil; 
      } 
     }); 
    }); 

這是一個遺憾,但SPSearch不提供那麼任何其他方式來觀察loaded值。 現在我正在問別人怎麼看這個實現或者提供更好的解決方案。


編輯:我也在CocoaLibSpotify所造成的問題已經,因爲我覺得SPSearch接口接觸不良設計:https://github.com/spotify/cocoalibspotify/issues/148

+1

我不明白的'目的search'被註釋'__block',這樣就可以在的最終它設置成'nil'塊。另外 - 這段代碼是否包含另一個未顯示的塊?編輯:我看到你現在想把'search'設置爲'nil'。這看起來有點危險。 –

+0

@CarlVeazey:是的,我知道。這就是爲什麼我要求更好的解決方案。 – miho

回答

0

發行,爲CocoaLibSpotify後,他們告訴我,我監督一些幫手在他們的文檔中就是專門爲這類問題設計的。

正確的解決辦法是使用SPAsyncLoading

NSArray *someTracks = …; // Some tracks. 

[SPAsyncLoading waitUntilLoaded:someTracks timeout:10.0 then:^(NSArray *loadedTracks, NSArray *notLoadedTracks) { 
    NSLog(@"The following tracks are loaded: %@", loadedTracks); 
}]; 
+1

如果您正在尋找示例,那麼帶有部分實施的Spotify內容源的原始回購使用'SPAsyncLoading'。 https://github.com/indragiek/SNRMusicKit/blob/master/Content%20Sources/Spotify/SMKSpotifyContentSource.m#L42-L47 – indragie