Nothing showing up in Tableview


#1

I believe I followed the code in the book to a tee, but I’m not getting the list of voices to show up in the tableview. I’m getting this error in the console:

2012-07-09 23:46:42.524 SpeakLine[4710:707] *** Illegal NSTableView data source (<SpeakLineAppDelegate: 0x10013e430>). Must implement numberOfRowsInTableView: and tableView:objectValueForTableColumn:row:

Here’s my code:

[code]//
// SpeakLineAppDelegate.m
// SpeakLine
//
// Created by Joey on 7/8/12.
// Copyright © 2012 MyCompanyName. All rights reserved.
//

#import “SpeakLineAppDelegate.h”

@implementation SpeakLineAppDelegate
@synthesize stopButton = _stopButton;
@synthesize speakButton = _speakButton;
@synthesize tableView = _tableView;

@synthesize window = _window;
@synthesize textField = _textField;

-(id)init
{
self = [super init];
if (self) {
NSLog(@“init”);

    _speechSynth = [[NSSpeechSynthesizer alloc]initWithVoice:nil];
    [_speechSynth setDelegate:self];
    _voices = [NSSpeechSynthesizer availableVoices];
}
return self;

}

  • (NSInteger)numberofRowsInTableView:(NSTableView *)tv
    {
    return (NSInteger)[_voices count];
    }

-(id)tableView:(NSTableView *)tv objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
NSString *v = [_voices objectAtIndex:row];
return v;
// NSDictionary *dict = [NSSpeechSynthesizer attributesForVoice:v];
// return [dict objectForKey:NSVoiceName];
}

-(void)speechSynthesizer:(NSSpeechSynthesizer *)sender didFinishSpeaking:(BOOL)finishedSpeaking
{
NSLog(@“finishedSpeaking = %d”, finishedSpeaking);
[_stopButton setEnabled:NO];
[_speakButton setEnabled:YES];
}

  • (void)applicationDidFinishLaunching:(NSNotification *)aNotification
    {
    // Insert code here to initialize your application
    }

  • (IBAction)sayIt:(id)sender {
    NSString *string = [_textField stringValue];
    //is the string zero-length?
    if ([string length] == 0){
    NSLog(@“string from %@ is of zero-length”,_textField);
    return;
    }
    [_speechSynth startSpeakingString:string];
    NSLog(@“Have started to say: %@”,string);

    [_stopButton setEnabled:YES];
    [_speakButton setEnabled:NO];
    }

  • (IBAction)stopit:(id)sender {
    NSLog(@“stopping”);
    [_speechSynth stopSpeaking];

}

@end
[/code]

[code]//
// SpeakLineAppDelegate.h
// SpeakLine
//
// Created by Joey on 7/8/12.
// Copyright © 2012 MyCompanyName. All rights reserved.
//

#import <Cocoa/Cocoa.h>

@interface SpeakLineAppDelegate : NSObject <NSApplicationDelegate, NSSpeechSynthesizerDelegate>
{
NSSpeechSynthesizer *_speechSynth;
NSArray *_voices;
}

@property (assign) IBOutlet NSWindow *window;
@property (weak) IBOutlet NSTextField *textField;
@property (weak) IBOutlet NSButton *stopButton;
@property (weak) IBOutlet NSButton *speakButton;
@property (weak) IBOutlet NSTableView *tableView;

  • (IBAction)stopit:(id)sender;
  • (IBAction)sayIt:(id)sender;

@end
[/code]

What am i doing wrong?


#2

I’m also having this issue, but since it’s not an issue for the solutions, I’m presuming it’s an issue with the frameworks being updated. I hate to say it, but we may need to just wait for the next edition of the book given how old this one is. I do have to say, it’s pretty funny that the only thing not happening is the names appearing. Functionally it’s all working, but between the error and the names not appearing it’s pretty disparaging.

Naturally it’ll be a 1 line fix once the authors chime in.


#3

I have exactly the same problem !

No one to give the solution ? or an explanation ?


#4

Since you didn’t post any code, I’ll post this for you to compare with.
This code is right out of the book and works in Xcode 6.1.

Interface

[code]#import <Cocoa/Cocoa.h>

@interface SpeakLineAppDelegate : NSObject <NSApplicationDelegate, NSSpeechSynthesizerDelegate>
{
NSArray *_voices;
NSSpeechSynthesizer *_speechSynth;
}

@property (weak) IBOutlet NSTextField *textField;
@property (assign) IBOutlet NSWindow *window;
@property (weak) IBOutlet NSButton *stopButton;
@property (weak) IBOutlet NSButton *speakButton;
@property (weak) IBOutlet NSTableView *tableView;

  • (IBAction)stopIt:(id)sender;
  • (IBAction)sayIt:(id)sender;

@end
[/code]

Implementation

[code]#import “SpeakLineAppDelegate.h”

@implementation SpeakLineAppDelegate

  • (id) init
    {
    self = [super init];
    if (self)
    {
    NSLog(@“init”);
    _speechSynth = [[NSSpeechSynthesizer alloc] initWithVoice:nil];
    [_speechSynth setDelegate:self];
    _voices = [NSSpeechSynthesizer availableVoices];
    }
    return self;
    }

  • (void) awakeFromNib
    {
    NSString *defaultVoice = [NSSpeechSynthesizer defaultVoice];
    NSInteger defaultRow = [_voices indexOfObject:defaultVoice];
    NSIndexSet *indices = [NSIndexSet indexSetWithIndex:defaultRow];
    [_tableView selectRowIndexes:indices byExtendingSelection:NO];
    [_tableView scrollRowToVisible:defaultRow];
    }

  • (void)applicationDidFinishLaunching:(NSNotification *)aNotification
    {
    // Insert code here to initialize your application
    }

  • (IBAction)stopIt:(id)sender
    {
    NSLog(@“stopping”);
    [_speechSynth stopSpeaking];
    }

  • (IBAction)sayIt:(id)sender
    {
    NSString *string = [_textField stringValue];

    if ([string length] == 0)
    {
    NSLog(@“string from %@ is of zero-length”, _textField);
    return;
    }
    [_speechSynth startSpeakingString:string];
    NSLog(@“Have started to say: %@”, string);

    [_stopButton setEnabled:YES];
    [_speakButton setEnabled:NO];
    [_tableView setEnabled:NO];
    }

  • (void) speechSynthesizer:(NSSpeechSynthesizer *)sender didFinishSpeaking:(BOOL)finishedSpeaking
    {
    NSLog(@“finishedSpeaking = %d”, finishedSpeaking);
    [_stopButton setEnabled:NO];
    [_speakButton setEnabled:YES];
    [_tableView setEnabled:YES];
    }

  • (NSInteger) numberOfRowsInTableView:(NSTableView *)tv
    {
    return (NSInteger)[_voices count];
    }

  • (id) tableView:(NSTableView *)tv objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
    {
    NSString *v = [_voices objectAtIndex:row];
    NSDictionary *dict = [NSSpeechSynthesizer attributesForVoice:v];
    return [dict objectForKey:NSVoiceName];
    }

  • (void) tableViewSelectionDidChange:(NSNotification *)notification
    {
    NSInteger row = [_tableView selectedRow];
    if (row < 0 || row > [_voices count])
    return;

    NSString *selectedVoice = [_voices objectAtIndex:row];
    [_speechSynth setVoice:selectedVoice];
    NSLog(@“new voice = %@”, selectedVoice);
    }

@end
[/code]

Mitch