NSBundleResourceRequest bundlePath [英] NSBundleResourceRequest bundlePath

查看:223
本文介绍了NSBundleResourceRequest bundlePath的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

[问题末尾的更新]

我曾经在应用程序中播放一些音频文件.

I use to play some audio files in my app.

我曾经将文件存储在应用程序中,但是后来我移到了On Demand ResourcesNSBundleResourceRequest.

I used to store the files in the app, but then I moved to On Demand Resourcesand NSBundleResourceRequest.

我有一个IBAction可以播放随机文件,并且由于我移到了ODR,所以无法正常工作.我唯一更改的是NSString *bundleRoot = [[NSBundle mainBundle] bundlePath];(第3行)

I have an IBAction to play a random file, and since I moved to ODR, it is not working. The only thing I changed was NSString *bundleRoot = [[NSBundle mainBundle] bundlePath]; (line 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];
}

dirContents看起来像:

应该包含mp3文件的地方.

when it is supposed to contain the mp3 files.

bundleRoot我怎么了?

我的viewDidload

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

我实际上还有另一种播放选定音频的方法(不是随机的)

I actually have another method to play a selected audio (not a random one)

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

它工作正常.

所以bundleRoot中有问题,不是我的文件所在的地方.

So there is a problem in the bundleRoot, is is not where my files are located.

[UPDATE]

我确实做到了

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

}

它几乎可以正常工作,但始终在播放目录中的第一个音频.

and it is ALMOST working but is is always playing the first audio in the directory.

推荐答案

您是否忘记了beginAccessingResourcesWithCompletionHandler:调用以实际下载资源?

Didn't you forget beginAccessingResourcesWithCompletionHandler: call to actually download resources?

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

NSBundle.h的一些重要说明:

Several important notes from NSBundle.h:

当资源可用或发生错误时,将在非主串行队列上调用完成块.

The completion block will be invoked on a non-main serial queue when the resources are available or an error has occurred.

因此,您可能需要在完成处理程序中使用其他dispatch_async为主队列.但这完全取决于您的代码.

So you will probably need to use additional dispatch_async to main queue in completion handler. But this depends solely on your code.

即使在完成处理程序发生错误的情况下,也要确保始终调用-endAccessingResources方法来平衡对begin方法的调用.

Be sure to always invoke the -endAccessingResources method to balance a call to the begin method, even in the case of an error in the completion handler.

这篇关于NSBundleResourceRequest bundlePath的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆