1

[UPDATE AM ENDE DER FRAGE]NSBundleResourceRequest bundlePath

Ich benutze Audio-Dateien in meiner Anwendung zu spielen.

Ich verwendete, um die Dateien in der App zu speichern, aber dann wechselte ich zu On Demand Resources und NSBundleResourceRequest.

Ich habe eine IBAction, um eine zufällige Datei zu spielen, und seit ich zu ODR bewegt, funktioniert es nicht. Das einzige, was ich verändert war NSString *bundleRoot = [[NSBundle mainBundle] bundlePath]; (Linie 3)

NSBundleResourceRequest *request1; 

- (IBAction)randomPlay { 
    NSString *bundleRoot = [[request1 bundle] bundlePath]; 
    NSFileManager *fm = [NSFileManager defaultManager]; 
    NSArray *dirContents = [fm contentsOfDirectoryAtPath:bundleRoot error:nil]; 
    NSPredicate *fltr = [NSPredicate predicateWithFormat:@"self ENDSWITH '.mp3'"]; 
    NSArray *onlyMP3s = [dirContents filteredArrayUsingPredicate:fltr]; 
    . 
    . 
    . 
    audio = [onlyMP3s[arc4random_uniform((uint32_t)onlyMP3s.count)] 
      stringByReplacingOccurrencesOfString:@".mp3" withString:@""]; 
    [self playSelectedAudio:audio]; 
} 

Die dirContents wie folgt aussieht:

enter image description here

, wenn man annimmt, die MP3-Dateien enthalten.

Was mache ich falsch mit bundleRoot?

Mein viewDidload ist

- (void)viewDidLoad { 
[super viewDidLoad]; 

tagsSet = [NSSet setWithObjects:@"sounds", nil]; 
request1 = [[NSBundleResourceRequest alloc] initWithTags:tagsSet]; 
[request1 conditionallyBeginAccessingResourcesWithCompletionHandler:^ 
           (BOOL resourcesAvailable) { 
    if (resourcesAvailable) { 
     //don't do nothing. just use the file slater 
    } else { 
     [request1 beginAccessingResourcesWithCompletionHandler:^ 
           (NSError * _Nullable error) { 
      if (error == nil) { 
       //download the files 
      } else { 
      } 
     }]; 
    } 
}]; 

ich eigentlich ein andere Methode hat ein ausgewähltes Audio (keine gelegentlichen)

-(void)playSelectedAudio:(id)audioToPlay { 
NSURL *url = [NSURL fileURLWithPath:[[request1 bundle] 
       pathForResource:audioToPlay ofType:@"mp3"]]; 

und es funktioniert gut zu spielen.

So gibt es ein Problem in der bundleRoot, ist nicht, wo meine Dateien befinden.

[UPDATE]

Ich habe tatsächlich

- (IBAction)randomPlay { 
     NSURL *bundleRoot = [NSURL fileURLWithPath:[[request1 bundle] 
          pathForResource:@"" ofType:@"mp3"]]; 
     NSFileManager *fm = [NSFileManager defaultManager]; 
     NSArray *dirContents = [fm contentsOfDirectoryAtURL:bundleRoot 
           includingPropertiesForKeys:[NSArray array] 
           options:0 error:nil]; 
     NSPredicate *fltr = [NSPredicate predicateWithFormat: 
          @"self ENDSWITH '.mp3'"]; 
     NSArray *onlyMP3s = [dirContents 
          filteredArrayUsingPredicate:fltr]; 
     . 
     . 
     . 
     audio = [onlyMP3s[arc4random_uniform((uint32_t)onlyMP3s.count)] 
         stringByReplacingOccurrencesOfString:@".mp3" 
         withString:@""]; 
     [self playSelectedAudio:audio]; 
    }]; 

} 

und es ist fast funktioniert, aber ist immer das erste Audio im Verzeichnis zu spielen.

+0

Überprüfen Sie Ihre Zufallszahl und Array-Anzahl. – bbum

+0

hey @bbum danke für die Antwort.Diese Methode funktionierte korrekt, als ich '[NSBundle mainBundle]' benutzte, also ein zufälliges Audio von allen Audios im Verzeichnis richtig auswählte. Welchen Teil soll ich prüfen? – fabersky

+0

* aber es spielt immer das erste Audio im Verzeichnis. * Sie haben entweder nur eine Audiodatei oder die generierte Zufallszahl ist konstant. Überprüfen Sie also den Inhalt von 'onlyMP3s'. – bbum

Antwort

0

Haben Sie nicht vergessen, beginAccessingResourcesWithCompletionHandler: Aufruf tatsächlich Ressourcen herunterladen?

- (IBAction)randomPlay { 
    NSBundleResourceRequest *request1; // I hope you properly initialize this request :) 
    [request1 beginAccessingResourcesWithCompletionHandler:^(NSError * _Nullable error) { 
     if (error != nil) { 
      // Probably, add here dispatch_async(dispatch_get_main_queue(), ^{ 
      NSString *bundleRoot = [[request1 bundle] bundlePath]; 
      NSFileManager *fm = [NSFileManager defaultManager]; 
      NSArray *dirContents = [fm contentsOfDirectoryAtPath:bundleRoot error:nil]; 
      NSPredicate *fltr = [NSPredicate predicateWithFormat:@"self ENDSWITH '.mp3'"]; 
      NSArray *onlyMP3s = [dirContents filteredArrayUsingPredicate:fltr]; 
      . 
      . 
      . 
      [self playSelectedAudio:audio]; 
      // You will probably need to invoke [request1 endAccessingResources] later, when you finish accessing your audio. 
     } 
     else { 
      // handle error 
      [request1 endAccessingResources]; 
     } 
    } 
} 

Mehrere wichtige Hinweise von NSBundle.h:

Der Abschluss Block wird auf einer nicht-seriellen Haupt Warteschlange aufgerufen werden, wenn die Ressourcen verfügbar sind oder ein Fehler aufgetreten ist.

So müssen Sie wahrscheinlich zusätzliche dispatch_async zur Hauptwarteschlange im Abschluss-Handler verwenden. Dies hängt jedoch ausschließlich von Ihrem Code ab.

Seien Sie sicher, dass die -endAccessingResources Methode immer aufrufen, um einen Aufruf an die beginnen Methode zum Ausgleich, auch im Falle eines Fehlers in der Prozedur der Fertigstellung.

+0

hey! Danke für die Antwort! Ich habe es schon in meinem viedDidLoad angerufen. Ich habe die Frage mit dem Code aktualisiert. – fabersky

+0

Frage erneut aktualisiert – fabersky

Verwandte Themen