NSBundleResourceRequest bundlePath [英] NSBundleResourceRequest bundlePath
问题描述
[问题末尾的更新]
我曾经在应用程序中播放一些音频文件.
I use to play some audio files in my app.
我曾经将文件存储在应用程序中,但是后来我移到了On Demand Resources
和NSBundleResourceRequest
.
I used to store the files in the app, but then I moved to On Demand Resources
and 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屋!