5

Sto provando a prelampare un grafo di oggetti di file in un repository Github utilizzando Octokit che dipende da Reactive Cococa. Sto incontrando un problema che crea un segnale che verrà eseguito il drill down, in modo ricorsivo, fino a quando non ci saranno più directory da recuperare. Ecco un esempio di grafico di directory di un repository of mine (nota: i file sono stati omessi per mantenere il grafico semplice e pulito).Ricorsivo -flattenMap: con Reactive Cocoa + OctoKit (recupero del grafo di oggetti dinamici dal servizio Web)

Directory graph of RNGridMenu

- (RACSignal *)fetchContentTreeForRepository:(OCTRepository *)repository { 
    return [[self fetchContent:Nil forRepository:repository parentContent:nil] doCompleted:^{ 
     // fetching tree finished, persist in database 
    }]; 
} 

- (RACSignal *)fetchContent:(OCTContent *)content forRepository:(OCTRepository *)repository parentContent:(OCTContent *)parentContent { 
    return [[[[self.client fetchContents:content forRepository:repository] collect] deliverOn:RACScheduler.mainThreadScheduler] 
      flattenMap:^RACSignal *(NSArray *fetchedContents) { 
       // set the contents that were fetched 
       id<OCTContentStoreProtocol>store = content ?: repository; 
       store.contents = fetchedContents; 

       // only search for contents of type "dir" (directory) 
       NSArray *directories = [fetchedContents filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"contentType = \"dir\""]]; 
       NSMutableArray *signals; 
       for (OCTContent *fetchedDir in directories) { 
        [signals addObject:[self fetchContent:fetchedDir forRepository:repository parentContent:content]]; 
       } 
       return [RACSignal merge:signals]; 
      }]; 
} 

Come nota: -fetchContents:forRepository: costruisce un percorso di richiesta e restituisce una RACSignal che accoda un'operazione richiesta HTTP (si cerca di seguire la semantica OctoKit does).

Il problema che sto correndo al momento è che questa configurazione esegue solo il recupero per i contenuti del repository (cioè l'oggetto di livello superiore nel grafico). -flattenMap: viene chiamato, la matrice di segnali viene creata in modo appropriato e viene restituito -merge:. L'intenzione è quella di creare una catena ricorsiva che termini quando non ci sono più figli di directory (probabilmente dovrebbe aggiungere uno -filter: per verificarlo).

L'intensione è di recuperare l'intero grafico dei file per un repository Github e ricevere una notifica al termine dell'operazione. Ecco un esempio di come mi piacerebbe gestire chiamare questo:

[[[GHDataStore sharedStore] fetchContentTreeForRepository:self.repository] 
subscribeNext:^(NSArray *contents) { 
    // this would be called each time a new set of contents is received 
    NSLog(@"received %i contents",[contents count]); 
} 
error:^(NSError *error) { 
    NSLog(@"error fetching: %@",error.localizedDescription); 
} 
completed:^{ 
    // this would be called when mapping the graph is finished 
    NSLog(@"finished fetching contents"); 
}]; 

Qualsiasi idea del perché si esegue solo il livello superiore? Avrei pensato che chiamare -subscribeNext: su -fetchContentTreeForRepository: sarebbe ciò che esegue il segnale restituito per -flattenMap:, ma sembra che stia fraintendendo qualcosa. Questa ipotesi viene dal chaining example nel readme Reactive Cocoa.

edit: I am dumb.

risposta

4

Il problema è che non si inizializza la tua NSMutableArray di segnali:

NSMutableArray *signals; 
for (OCTContent *fetchedDir in directories) { 
     [signals addObject:[self fetchContent:fetchedDir forRepository:repository parentContent:content]]; 
} 
return [RACSignal merge:signals]; 

cambiamento che prima linea per NSMutableArray *signals = [NSMutableArray new] e sembra funzionare.

+3

......... dammit – rnystrom

+3

Potrei anche aggiungere che si potrebbe semplicemente usare la proprietà 'rac_sequence' della matrice' directories' per eseguire una mappa di ogni directory sul segnale. Fa la stessa cosa ma è un po 'più dichiarativo. –

Problemi correlati