2014-11-18 16:33:01.840 Record-Upload[2077:112380] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<ViewController 0x7f84b3076400> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key PauseButtonTapped.'
*** First throw call stack:
(
0 CoreFoundation 0x00000001049cbf35 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x00000001042bbbb7 objc_exception_throw + 45
2 CoreFoundation 0x00000001049cbb79 -[NSException raise] + 9
3 Foundation 0x0000000103a4a7b3 -[NSObject(NSKeyValueCoding) setValue:forKey:] + 259
4 CoreFoundation 0x0000000104915e80 -[NSArray makeObjectsPerformSelector:] + 224
5 UIKit 0x000000010507dc7d -[UINib instantiateWithOwner:options:] + 1506
6 UIKit 0x0000000104edcf98 -[UIViewController _loadViewFromNibNamed:bundle:] + 242
7 UIKit 0x0000000104edd588 -[UIViewController loadView] + 109
8 UIKit 0x0000000104edd7f9 -[UIViewController loadViewIfRequired] + 75
9 UIKit 0x0000000104eddc8e -[UIViewController view] + 27
10 UIKit 0x0000000104dfcca9 -[UIWindow addRootViewControllerViewIfPossible] + 58
11 UIKit 0x0000000104dfd041 -[UIWindow _setHidden:forced:] + 247
12 UIKit 0x0000000104e0972c -[UIWindow makeKeyAndVisible] + 42
13 UIKit 0x0000000104db4061 -[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 2628
14 UIKit 0x0000000104db6d2c -[UIApplication _runWithMainScene:transitionContext:completion:] + 1350
15 UIKit 0x0000000104db5bf2 -[UIApplication workspaceDidEndTransaction:] + 179
16 FrontBoardServices 0x000000010a9dc2a3 __31-[FBSSerialQueue performAsync:]_block_invoke + 16
17 CoreFoundation 0x000000010490153c __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 12
18 CoreFoundation 0x00000001048f7285 __CFRunLoopDoBlocks + 341
19 CoreFoundation 0x00000001048f7045 __CFRunLoopRun + 2389
20 CoreFoundation 0x00000001048f6486 CFRunLoopRunSpecific + 470
21 UIKit 0x0000000104db5669 -[UIApplication _run] + 413
22 UIKit 0x0000000104db8420 UIApplicationMain + 1282
23 Record-Upload 0x0000000103622883 main + 115
24 libdyld.dylib 0x000000010817b145 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
我不明白它在哪里说reason: '[<ViewController 0x7f9f5304ba00> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key PauseButtonTapped
代码中没有可以尝试的行 (我讨厌把代码转储到这里,但我觉得有必要)
代码程序记录音频,然后使用FTP发送到服务器
#import "NetworkManager.h"
#include <CFNetwork/CFNetwork.h>
#import "ViewController.h"
enum {
kSendBufferSize = 32768
};
@interface ViewController () <NSStreamDelegate>{
AVAudioRecorder *recorder;
AVAudioPlayer *player;
}
@property (strong, nonatomic) NSTimer *timer;
@property (strong, nonatomic) NSDate *startDate;
- (IBAction)sendButtonPush:(id)sender;
@property (weak, nonatomic) IBOutlet UILabel *status;
@property (weak, nonatomic) IBOutlet UILabel *time;
@property (weak, nonatomic) IBOutlet UIButton *sendButton;
@property (nonatomic, assign, readonly ) BOOL isSending;
@property (nonatomic, strong, readwrite) NSOutputStream * networkStream;
@property (nonatomic, strong, readwrite) NSInputStream * fileStream;
@property (nonatomic, assign, readonly ) uint8_t * buffer;
@property (nonatomic, assign, readwrite) size_t bufferOffset;
@property (nonatomic, assign, readwrite) size_t bufferLimit;
@end
@implementation ViewController
{
uint8_t _buffer[kSendBufferSize];
}
- (void)viewDidLoad {
[super viewDidLoad];
[self.sendButton setEnabled:YES];
[self.PauseButton setEnabled:NO];
[self.PlayButton setEnabled: NO];
//define file path, then file pointer/url
// NSArray *pathComponents = [NSArray arrayWithObjects:[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject], @"MyAudio.m4a", nil];
// NSURL *outputFileURL = [NSURL fileURLWithPathComponents:pathComponents];
NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentPath_ = [searchPaths objectAtIndex:0];
NSString *pathToSave = [documentPath_ stringByAppendingPathComponent: @"MyAudio2.m4a"];
NSURL *outputFileURL = [NSURL fileURLWithPath: pathToSave];
//setup Audio session
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
//define record settings
NSMutableDictionary *recordSetting = [[NSMutableDictionary alloc] init];
//codec/format
[recordSetting setValue:[NSNumber numberWithInt:kAudioFormatMPEG4AAC] forKey:AVFormatIDKey];
//bit rate
[recordSetting setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey]; //8000
//number of channels - stero -2 mono -1?
[recordSetting setValue:[NSNumber numberWithInt: 2] forKey:AVNumberOfChannelsKey];
//initiate and prepare the recorder
recorder = [[AVAudioRecorder alloc] initWithURL:outputFileURL settings:recordSetting error:NULL];
recorder.delegate = self;
recorder.meteringEnabled = YES;
[recorder prepareToRecord];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)sendButtonPush:(id)sender {
self.status.text = @"...";
[self.sendButton setEnabled:NO];
NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentPath_ = [searchPaths objectAtIndex:0];
NSString *pathToSave = [documentPath_ stringByAppendingPathComponent: @"MyAudio2.m4a"];
//NSURL *outputFileURL = [NSURL fileURLWithPath: pathToSave];
NSLog(@"Path: %@", pathToSave);
[self startSend: pathToSave];
}
/*
* Imported From SimpleFTPSample - dev.apple.com
*/
- (void)sendDidStart
{
self.status.text = @"Sending";
//self.cancelButton.enabled = YES;
//[self.activityIndicator startAnimating];
[[NetworkManager sharedInstance] didStartNetworkOperation];
}
- (void)updateStatus:(NSString *)statusString
{
assert(statusString != nil);
self.status.text = statusString;
}
- (void)sendDidStopWithStatus:(NSString *)statusString
{
if (statusString == nil) {
statusString = @"Put succeeded";
}
self.status.text = statusString;
//self.cancelButton.enabled = NO;
//[self.activityIndicator stopAnimating];
[[NetworkManager sharedInstance] didStopNetworkOperation];
}
#pragma mark * Core transfer code
// This is the code that actually does the networking.
// Because buffer is declared as an array, you have to use a custom getter.
// A synthesised getter doesn't compile.
- (uint8_t *)buffer
{
return self->_buffer;
}
- (BOOL)isSending
{
return (self.networkStream != nil);
}
- (void)startSend:(NSString *)filePath
{
BOOL success;
NSURL * url;
//check path is not empty
assert(filePath != nil);
//check path exists
assert([[NSFileManager defaultManager] fileExistsAtPath:filePath]);
//check file is either png or jpg
NSLog(@"FilePath: %@", filePath);
//assert( [filePath.pathExtension isEqual:@"png"] || [filePath.pathExtension isEqual:@"jpg"] );
assert(self.networkStream == nil); // don't tap send twice in a row!
assert(self.fileStream == nil); // ditto
// First get and check the URL - insert our custom url here!
url = [[NetworkManager sharedInstance] smartURLForString:@"ftp://www.example.co.uk"];
//check
success = (url != nil);
if (success) {
// Add the last part of the file name to the end of the URL to form the final
// URL that we're going to put to.
url = CFBridgingRelease(
CFURLCreateCopyAppendingPathComponent(NULL, (__bridge CFURLRef) url, (__bridge CFStringRef) [filePath lastPathComponent], false)
);
success = (url != nil);
}
// If the URL is bogus, let the user know. Otherwise kick off the connection.
NSLog(@"URL %@", url);
if ( ! success) {
self.status.text = @"Invalid URL";
} else {
// Open a stream for the file we're going to send. We do not open this stream;
// NSURLConnection will do it for us.
self.fileStream = [NSInputStream inputStreamWithFileAtPath:filePath];
assert(self.fileStream != nil);
//open file stream for input
[self.fileStream open];
// Open a CFFTPStream for the URL.
self.networkStream = CFBridgingRelease(
CFWriteStreamCreateWithFTPURL(NULL, (__bridge CFURLRef) url)
);
assert(self.networkStream != nil);
//
//User & Password
//
success = [self.networkStream setProperty:@"USERNAME" forKey:(id)kCFStreamPropertyFTPUserName];
assert(success);
success = [self.networkStream setProperty:@"PASSWORD" forKey:(id)kCFStreamPropertyFTPPassword];
assert(success);
self.networkStream.delegate = self;
[self.networkStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[self.networkStream open];
// Tell the UI we're sending.
[self sendDidStart];
}
}
- (void)stopSendWithStatus:(NSString *)statusString
{
if (self.networkStream != nil) {
[self.networkStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
self.networkStream.delegate = nil;
[self.networkStream close];
self.networkStream = nil;
}
if (self.fileStream != nil) {
[self.fileStream close];
self.fileStream = nil;
}
[self sendDidStopWithStatus:statusString];
}
- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
// An NSStream delegate callback that's called when events happen on our
// network stream.
{
#pragma unused(aStream)
assert(aStream == self.networkStream);
switch (eventCode) {
case NSStreamEventOpenCompleted: {
[self updateStatus:@"Opened connection"];
} break;
case NSStreamEventHasBytesAvailable: {
assert(NO); // should never happen for the output stream
} break;
case NSStreamEventHasSpaceAvailable: {
[self updateStatus:@"Sending"];
// If we don't have any data buffered, go read the next chunk of data.
if (self.bufferOffset == self.bufferLimit) {
NSInteger bytesRead;
bytesRead = [self.fileStream read:self.buffer maxLength:kSendBufferSize];
if (bytesRead == -1) {
[self stopSendWithStatus:@"File read error"];
} else if (bytesRead == 0) {
[self stopSendWithStatus:nil];
} else {
self.bufferOffset = 0;
self.bufferLimit = bytesRead;
}
}
// If we're not out of data completely, send the next chunk.
if (self.bufferOffset != self.bufferLimit) {
NSInteger bytesWritten;
bytesWritten = [self.networkStream write:&self.buffer[self.bufferOffset] maxLength:self.bufferLimit - self.bufferOffset];
assert(bytesWritten != 0);
if (bytesWritten == -1) {
[self stopSendWithStatus:@"Network write error"];
} else {
self.bufferOffset += bytesWritten;
}
}
} break;
case NSStreamEventErrorOccurred: {
[self stopSendWithStatus:@"Stream open error"];
} break;
case NSStreamEventEndEncountered: {
// ignore
} break;
default: {
assert(NO);
} break;
}
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (void)dealloc
{
[self stopSendWithStatus:@"Stopped"];
}
- (IBAction)RecordButtonTapped:(id)sender {
if(player.playing){
[player stop];
}
if(!recorder.recording){
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setActive: YES error: nil];
//start recording
self.startDate = [NSDate date];
self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0/100.0
target:self
selector:@selector(updateTimer)
userInfo:nil
repeats:YES];
[recorder record];
[self.RecordButton setTitle: @"Pause" forState:UIControlStateNormal];
} else{
[recorder pause];
[self.RecordButton setTitle:@"Record" forState: UIControlStateNormal];
[self.timer invalidate];
self.timer = nil;
[self updateTimer];
}
[self.PauseButton setEnabled:YES];
[self.PlayButton setEnabled:NO];
}
//UI Functions
- (IBAction)PauseButtonTapped:(id)sender {
[recorder stop];
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setActive:NO error: nil];
/* NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentPath_ = [searchPaths objectAtIndex:0];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSMutableArray *arrayList =[[NSMutableArray alloc] initWithArray:[fileManager contentsOfDirectoryAtPath:documentPath_ error:nil]];
NSLog(@"==== %@", arrayList); */
}
- (IBAction)PlayButtonTapped:(id)sender {
if(!recorder.recording){
player = [[AVAudioPlayer alloc] initWithContentsOfURL:recorder.url error:nil];
[player setDelegate:self];
[player play];
}
}
//Audio Functions
-(void) audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag{
[self.RecordButton setTitle: @"Record" forState:UIControlStateNormal];
[self.PauseButton setEnabled:NO];
[self.PlayButton setEnabled:YES];
}
-(void) audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Done" message:@"Finished Playing the recording!" delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles: nil];
[alert show];
}
//Timer Function
-(void) updateTimer
{
// Create date from the elapsed time
NSDate *currentDate = [NSDate date];
NSTimeInterval timeInterval = [currentDate timeIntervalSinceDate:self.startDate];
NSDate *timerDate = [NSDate dateWithTimeIntervalSince1970:timeInterval];
// Create a date formatter
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"mm:ss.SS"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];
// Format the elapsed time and set it to the label
NSString *timeString = [dateFormatter stringFromDate:timerDate];
self.time.text = timeString;
}
@end
答案 0 :(得分:0)
在此按钮窗口中,删除所有连接,然后重新添加。