行。我一直致力于一个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'.