UIPickerView选择了音频文件 - 应用程序崩溃

时间:2014-09-30 04:27:43

标签: ios objective-c iphone uipickerview

行。我一直致力于一个iOS项目,我正在努力推动更高级的开发阶段。这是一款简单的录音笔应用程序,具有录制,播放和停止功能。 因此,为了更好地理解构建这样的程序的基础知识,我正在构建几个版本的过程,这些版本成功地使应用程序的各个功能工作。 我的基本录音机应用程序包含一个包含View控制器的故事板,并且连接了一个UIPickerview,还有3个按钮:Record,Stop和Play。 我有一个工作版本,可以录制一段音频,并在录制完成后播放。 然后,所有后续记录(如.caf文件)将作为audio.caf对象文件的数组显示在UIPickerview中。 但是,当时我只能播放刚制作的录音,我最终需要能够播放可在Pickerview中选择的任何音频文件。 这是因为每次启动应用程序时都会创建一个新文件,因为此时所有代码都驻留在UIViewcontroller的viewDidLoad中,而不是作为单独的类调用。 我必须在以后建立这个 所以,现在我正在构建一个aditional测试版本,它将播放Pickerview中任何选定的音频文件。 此测试版本不包括记录操作,仅包括播放选择。

到目前为止,我已经相当成功地找出了构建这个项目的一些编程问题,但当时我遇到了一些障碍,我确信很大程度上是由于我的编程知识限制。 所以,在这个测试版本中,我有3个audio.caf文件,目前驻留在我的iOS项目文档路径中的一个文件夹中。 这些都成功地在UIPicker中显示为一个数组。 我还构建了一个带有音频文件的版本作为我的MainBundle的一部分(在一个名为'sounds'的文件夹中)并令人沮丧,我无法让它们显示在UIPicker中。 无论如何,如果音频文件将方法调用为名为selectedAudioFile的字符串,我有一个名为-(void)playAudioFile:(NSString*)selectAudioFile的类具有url路径。 这也被委托使用AVAudioPlayer的MyPlayer委托作为音频播放。 因此,当在UIPicker中选择文件时,将调用PlayAudioFile。 它没有播放,而是因为错误而崩溃:

  

“因未捕获的异常而终止应用   'NSInvalidArgumentException',原因:' * - [NSURL   initFileURLWithPath:]:nil字符串参数'。

nil字符串参数是在选择字符串时没有找到任何内容!?!我不确定。 另外,我有足够的日志来检查我的音频和文件路径对象是否确实存在(似乎在构建时称为ok) 日志说明这里正在创建所有内容。

还有一些我还没有涉及的问题仍然需要修复,但这是我此时需要解决的线程问题。 我的.m和.h文件发布在下面。欢迎任何建议。 richG

![录音机应用程序屏幕] http://sd.uploads.im/2rsk0.png

ViewController.h

#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>

@interface ViewController : UIViewController<AVAudioPlayerDelegate,UIPickerViewDataSource, UIPickerViewDelegate>
{
UIPickerView *AudioPicker;
NSArray *audioFiles;
AVAudioPlayer *myPlayer;


}
@property (strong, nonatomic) IBOutlet UIPickerView *AudioPicker;
@property (strong,nonatomic) NSArray *audioFiles;
@property (strong, nonatomic) NSString *dirPath;
@property (strong, nonatomic) NSString *selectedSound;
@property (strong, nonatomic) NSArray *PathComponents;
@property (strong, nonatomic) NSString *docDir;
@property (strong, nonatomic) NSString *filePath;
@property (strong, nonatomic) NSString *fileName;
@property (strong, nonatomic) AVAudioPlayer *myPlayer;

-(void)playAudioFile:(NSString*)selectAudioFile;
@end

ViewController.m

#import "ViewController.h"

@interface ViewController (){

}

@end

@implementation ViewController

@synthesize AudioPicker;
@synthesize myPlayer;
@synthesize audioFiles;
@synthesize selectedSound;
@synthesize PathComponents;
@synthesize docDir;
@synthesize filePath;
@synthesize fileName;


- (void)viewDidLoad
{
[super viewDidLoad];
// Testing with literal array list <---
//audio = [[NSArray alloc] initWithObjects:@"audio1.caf",@"audio1.caf", nil];


NSFileManager *filemanager = [NSFileManager defaultManager];
audioFiles = [[NSMutableArray alloc] init];

NSArray *pathComponents = NSSearchPathForDirectoriesInDomains(
                                                              NSDocumentDirectory,           NSUserDomainMask, YES);

if([pathComponents count] > 0) {
    NSString *docDir = [pathComponents objectAtIndex:0];

    NSError *error = nil;
    audioFiles = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:docDir error:&error];
    if(error){
        NSLog(@"Failed getting files with error: %@",[error description]);
    }
    NSLog(@"Files are in fact being created...");

    NSInteger count = [audioFiles count];

    NSString *filename = [NSString stringWithFormat:@"%@.caf",[NSNumber numberWithFloat:count]];
    NSLog(@"------> CCCCCCCCCCCounting here , %d",[pathComponents count]);

    NSString *filePath = [docDir stringByAppendingPathComponent:filename];

    if ([filemanager fileExistsAtPath:docDir isDirectory:nil])
        NSLog(@"File does exist<--!!, %@", filename);
    else
        NSLog(@"File not found");

    NSLog(@"----> recorderFileName: %@",filename);
    NSLog(@"----> recorderFilePath <------: %@",filePath);



    }
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
}

#pragma pickerview
// sets up the pickerView with number of components to display
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 1;
}


// sets up the number of rows for the pickerView
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:            (NSInteger)component {
return [self.audioFiles count];
}

// sets up the pickerView with titles from Parse
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row    forComponent:(NSInteger)component {

return [self.audioFiles objectAtIndex:row];
NSLog(@"audio row %@", [self.audioFiles objectAtIndex:row]);
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
selectedSound = [self.audioFiles objectAtIndex:row];
NSLog(@"selected sound %@",selectedSound);

NSLog(@"testing player %@",[self.audioFiles objectAtIndex:row]);
[self playAudioFile:selectedSound]; //<-- CAUSING CRASH WHEN A STRING IS SELECTED

}

-(void)playAudioFile:(NSString*)selectAudioFile{
//** --> UPDATE EDIT <---------------------------------------------------------------- **
/* --> This piece a code was used from working with a another tutorial 
// on getting an array for a UIPickerView.
// This method was using the Mainbundle to store the files, 
// but did not seem to work either with
// this approach or my project version that 
// is storing the files in the directory.
// This seems to be my problem here, in getting 
// a reliable way of creating a URL for the
// files in the ObjectAtIndex to be retrieved.
*/

// ADDED CODE HERE
NSRange range = [_selectedSound rangeOfString:@"."];
NSString *filename = [_selectedSound substringToIndex:NSMaxRange(range)-1];
NSString *fileExtension = [_selectedSound substringFromIndex:NSMaxRange(range)];


NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle]
                                     pathForResource:filename
                                     ofType:fileExtension]];
// ADDED CODE CONCLUDED! <---
//** END OF EDIT ***********************************************************************

NSURL *url = [[NSURL alloc] initFileURLWithPath: filePath];
NSLog(@"URL is here <---- %@", url);
NSError *error;

myPlayer = [[AVAudioPlayer alloc]
            initWithContentsOfURL:url
            error:&error];
//myPlayer =  [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:_filePath] error:&error];
if (error)
{
    NSLog(@"Error in audioPlayer: %@",
          [error localizedDescription]);
} else {

    myPlayer.delegate = self;
    [myPlayer prepareToPlay];
    [myPlayer play];
}
}
@end

在选择UIPicker之前打印出在控制台中显示的NSLog,然后使应用程序崩溃。

2014-09-29 18:50:19.912 PickerWithDocumentsTest[1826:70b] Files are in fact being created...
2014-09-29 18:50:19.914 PickerWithDocumentsTest[1826:70b] ------> CCCCCCCCCCCounting here , 1
2014-09-29 18:50:19.916 PickerWithDocumentsTest[1826:70b] File does exist<--!!, 4.caf
2014-09-29 18:50:19.916 PickerWithDocumentsTest[1826:70b] ----> recorderFileName: 4.caf
2014-09-29 18:50:19.917 PickerWithDocumentsTest[1826:70b] ----> recorderFilePath <------: /Users/macbook/Library/Application Support/iPhone Simulator/7.0.3/Applications/1A55457F-9D74-4E25-A546-2622C11EB7DB/Documents/4.caf
2014-09-29 18:50:22.359 PickerWithDocumentsTest[1826:70b] selected sound 1f.caf
2014-09-29 18:50:22.360 PickerWithDocumentsTest[1826:70b] testing player 1f.caf
Program ended with exit code: 0

同样,当应用程序崩溃时,错误是:

'Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '* -[NSURL initFileURLWithPath:]: nil string parameter'.

0 个答案:

没有答案