5

Próbuję pobrać wstępnie wykres obiektów z repozytorium Github za pomocą Octokit, który zależy od Reactive Cococa. Występuje problem, który tworzy sygnał, który będzie drążał, rekursywnie, dopóki nie będzie już żadnych katalogów do pobrania. Oto przykładowy wykres katalogu z repository of mine (uwaga: pliki zostały pominięte, aby wykres był prosty i czysty).Rekursywna -flattenMap: z Reaktywnym kakao + OctoKit (pobieranie dynamicznego wykresu obiektów z usługi WWW)

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]; 
      }]; 
} 

Jako notatkę: -fetchContents:forRepository: buduje ścieżkę żądania i zwraca RACSignal że kolejkuje operację żądania HTTP (stara się podążać semantykę OctoKit does).

Problem, który napotykam obecnie, polega na tym, że ta konfiguracja wykonuje tylko pobieranie zawartości repozytorium (tj. Obiektu najwyższego poziomu na wykresie). -flattenMap: nazywa się, tablica sygnałów jest odpowiednio utworzona i zwracana jest -merge:. Intencją jest utworzenie łańcucha rekursywnego, który kończy się, gdy nie ma już dzieci typu katalogowego (prawdopodobnie należy dodać -filter:, aby to sprawdzić).

Intencją jest pobranie całego wykresu plików dla repozytorium Github i otrzymanie powiadomienia o zakończeniu operacji. Oto przykład tego, jak chciałbym obsłużyć wywoływanie tego:

[[[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"); 
}]; 

Czy masz pomysł, dlaczego wykonuje on tylko najwyższy poziom? Myślałem, że wywołanie -subscribeNext: na -fetchContentTreeForRepository: jest tym, co wykonuje zwracany sygnał dla -flattenMap:, ale wydaje mi się, że coś nie rozumiem. To założenie pochodzi z chaining example w readme Reactive Cocoa.

edit: I am dumb.

Odpowiedz

4

Kwestia jest taka, że ​​nigdy nie zainicjować NSMutableArray sygnałów:

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

to zmienić pierwszą linię do NSMutableArray *signals = [NSMutableArray new] i wydaje się działać.

+3

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

+3

Mogę również dodać, że możesz po prostu użyć właściwości 'rac_sequence' z tablicy' directories', aby wykonać mapę każdego katalogu na sygnał. Czy to samo, ale jest nieco bardziej deklaratywny. –

Powiązane problemy