2011.09.12

【正誤情報】『まるごと学ぶiPhoneアプリ制作教室』

まるごと学ぶiPhoneアプリ制作教室

下記のような誤りがありました。お詫びの上、訂正させていただきます。
また、補足情報も掲載しています。


 

◇◆全体的な事柄:Xcode 4.1/4.2での動作について◆◇

 

本書の紙面やダウンロードファイルは、執筆当時の最新版Xcode 4.0で動作確認しています。Xcode 4.1や4.2では主に下記のような違いが生じています。詳しくは該当ページごとに補足情報を掲載しています。

  • Xcode 4.1: ヘッダファイルで生成される内容の違い (例)p.22の画面
  • Xcode 4.2: (Xcode 4.1での違いに加えて)新しいプロジェクトの作成画面 (例)p.11の3つの画面

本書のダウンロードファイルのプロジェクトは、Xcode 4.1や4.2でもコンパイル・実行できます。

 


 

◇◆個別の事柄◆◇

 


 

◆p.ii相当(大扉裏の「著者プロフィール」で始まるページ)、上から14行目のURL

サポートページのURLが誤っていました。カバーや奥付(最終ページ)のURLは適切です。
《誤》 URL http://isbn.sbcr.jp/62619/
《正》 URL http://isbn.sbcr.jp/64620/

 


 

◆p.iv相当、「■感謝のことば」の上から6行目

《誤》 グを一度も経験したことない
《正》 グを一度も経験したことない

 


 

◆p.8、1.2節、下から3行目

為替レートの変更に伴って、日本円での費用が更新されています。今後も変わる可能性がありますのでご注意ください。
《誤》 Developer Programに参加登録する必要があります(年会費は10,800円)。
《正》 Developer Programに参加登録する必要があります(年間参加費は8,400円)。

 


 

◆p.11、1.3節、<Xcode 4.2についての補足>

《1番目の画面》
①で「Single View Application」を選択します。
64620_p011a.gif
《2番目の画面》
Product Nameに①プロジェクトの名前「MyFlagIQ」、Company Identifierに②会社の識別子「jp.myiphonecompany」、Class Prefixに「MyFlagIQ」(後続の紙面との整合性のため)を入力し、Device Familyに「iPhone」を選択します。Use Storyboard/Use Automatic Reference Counting/Include Unit Testsの3つのチェックボックスはチェックしません。
64620_p011b.gif
《3番目の画面》

この新しいプロジェクトの保存先を選択して、③「Create」ボタンを押します。
64620_p011c.gif

 


 

◆p.22、1.9節、<Xcode 4.1/4.2についての補足>

《画面》
「@interface MyFlagIQViewController : UIViewController」に続く「{ 」~「}」のブロック部分がありません。ないままで大丈夫です。p.23の画面内も同様です。

@interface MyFlagIQViewController : UIViewController

@end

 


 

◆p.24/25、1.10節、<Xcode 4.1/4.2についての補足>

《p.24の1/2/3番目、p.25の画面》
「@interface MyFlagIQViewController : UIViewController」に続く「{ 」~「}」のブロック部分がありません。ないままで大丈夫です。p.26の画面内も同様です。

 


 

◆p.29、1.12節、<Xcode 4.2についての補足>

《画面》
「/*」~「*/」でコメントアウトされていません。

 


 

◆p.42/43、1.15節、<Xcode 4.1/4.2についての補足>

《p.42/43の画面》
「@interface MyFlagIQViewController : UIViewController」に続く「{ 」~「}」のブロック部分がありません。ないままで大丈夫です。

 


 

◆p.60、1.23節、<Xcode 4.1/4.2についての補足>

《画面》
「@interface MyFlagIQViewController : UIViewController」に続く「{ 」~「}」のブロック部分がありません。ないままで大丈夫です。

 


 

◆p.70、1.26節、<Xcode 4.1/4.2についての補足>

《1番目の画面》
「@interface MyFlagIQViewController : UIViewController」に続く「{ 」~「}」のブロック部分がありません。そのため、「 NSArray *imageNames;」を追加する際に、「{ 」~「}」も下記のように追加します。

@interface MyFlagIQViewController : UIViewController {
    NSArray *imageNames;
}

 


 

◆p.71、1.27節、<Xcode 4.1/4.2についての補足>

《1番目の画面》
「@interface MyFlagIQViewController : UIViewController」に続く「{ 」~「}」のブロック部分の内容はp.70の状態に操作するので、仕上がりは下記のようになります。

@interface MyFlagIQViewController : UIViewController {
    NSArray *imageNames;
    int randomNumber[4];    
}

 


 

◆p.77/81、1.27/31節、<Xcode 4.1/4.2についての補足>

《p.77/81の1番目の画面》
「@interface MyFlagIQViewController : UIViewController」に続く「{ 」~「}」のブロック部分の内容はp.71で操作した状態のままです。

@interface MyFlagIQViewController : UIViewController {
    NSArray *imageNames;
    int randomNumber[4];    
}

 


 

◆p.86、1.33節、<Xcode 4.1/4.2についての補足>

《画面》
「@interface MyFlagIQViewController : UIViewController」に続く「{ 」~「}」のブロック部分の内容はp.71の状態に操作するので、仕上がりは下記のようになります。

@interface MyFlagIQViewController : UIViewController {
    NSArray *imageNames;
    int randomNumber[4];    
    int correctAnswer;
}

 


 

◆p.92、1.36節、<Xcode 4.1/4.2についての補足>

《画面》
「@interface MyFlagIQViewController : UIViewController」に続く「{ 」~「}」のブロック部分の内容はp.86で操作した状態のままです。

@interface MyFlagIQViewController : UIViewController {
    NSArray *imageNames;
    int randomNumber[4];    
    int correctAnswer;
}

 


 

◆p.94、1.37節、ページ上側の箇条書きの項目②

《誤》 ②音声を再生するためのラブラリの取り込む
《正》 ②音声を再生するためのライブラリを取り込む

 


 

◆p.95、1.37節、上から2行目の大見出し

これに伴って、p.xiiのContents(目次)の大見出しも同様に訂正いたします。
《誤》 音声を再生するためのライブラリ取り込む(ライブラリの追加方法)
《正》 音声を再生するためのライブラリ取り込む(ライブラリの追加方法)

 


 

◆p.101、1.40節、soundメソッドの引数の名前

紙面では「audioFileName」としていますが、ダウンロードファイルに揃えて「soundFileName」へ訂正いたします。
◎ページ下側の画面写真(上側4行分)
《誤》
- (void) sound:(NSString*)audioFileName {
    SystemSoundID soundID;
    CFBundleRef mainBundle = CFBundleGetMainBundle();
    CFURLRef soundURL = CFBundleCopyResourceURL(mainBundle, (CFStringRef)audioFileName, CFSTR("aiff"), NULL);
《正》
- (void) sound:(NSString*)soundFileName {
    SystemSoundID soundID;
    CFBundleRef mainBundle = CFBundleGetMainBundle();
    CFURLRef soundURL = CFBundleCopyResourceURL(mainBundle, (CFStringRef)soundFileName, CFSTR("aiff"), NULL);
◎ページ下側の画面写真の次の行
《誤》 このように記述すると、「audioFileName」という名前で文字列を引数として受け取ることができます。
《正》 このように記述すると、「soundFileName」という名前で文字列を引数として受け取ることができます。

 


 

◆p.102、1.40節、soundメソッドの引数の名前と変数score

p.101同様、紙面では「audioFileName」としていますが、ダウンロードファイルに揃えて「soundFileName」へ訂正いたします。
また、画面写真中で変数scoreを使用していますが、p.120から使用するので、ここではまだ宣言していません。そのため、「score++;」や「score–;」の行がないように訂正いたします。
◎画面写真
《誤》
- (void) sound:(NSString*)audioFileName {
    SystemSoundID soundID;
    CFBundleRef mainBundle = CFBundleGetMainBundle();
    CFURLRef soundURL = CFBundleCopyResourceURL(mainBundle, (CFStringRef)audioFileName, CFSTR("aiff"), NULL);
    AudioServicesCreateSystemSoundID(soundURL, &soundID);
    AudioServicesPlaySystemSound(soundID);
    CFRelease(soundURL);
}

- (IBAction)answerButtonAction0:(id)sender {
    imageLabel0.text = [imageNames objectAtIndex:randomNumber[0]];
    if (correctAnswer == 0) {
        answerLabel0.text = @"O";
        nextQuizButton.userInteractionEnabled = true; //ボタンを押せるようにする
        [self sound:@"good"];
        score++;
    } else {
        answerLabel0.text = @"X";
        [self sound:@"bad"];
        score--;
    }
}

- (IBAction)answerButtonAction1:(id)sender {
    imageLabel1.text = [imageNames objectAtIndex:randomNumber[1]];
    if (correctAnswer == 1) {
        answerLabel1.text = @"O";
        nextQuizButton.userInteractionEnabled = true; //ボタンを押せるようにする
        [self sound:@"good"];
        score++;
    } else {
        answerLabel1.text = @"X";
        [self sound:@"bad"];
        score--;
    }
}

- (IBAction)answerButtonAction2:(id)sender {
    imageLabel2.text = [imageNames objectAtIndex:randomNumber[2]];
    if (correctAnswer == 2) {
        answerLabel2.text = @"O";
        nextQuizButton.userInteractionEnabled = true; //ボタンを押せるようにする
        [self sound:@"good"];
        score++;
    } else {
        answerLabel2.text = @"X";
        [self sound:@"bad"];
        score--;
    }
}

- (IBAction)answerButtonAction3:(id)sender {
    imageLabel3.text = [imageNames objectAtIndex:randomNumber[3]];
    if (correctAnswer == 3) {
        answerLabel3.text = @"O";
        nextQuizButton.userInteractionEnabled = true; //ボタンを押せるようにする
        [self sound:@"good"];
        score++;
    } else {
        answerLabel3.text = @"X";
        [self sound:@"bad"];

《正》
- (void) sound:(NSString*)soundFileName {
    SystemSoundID soundID;
    CFBundleRef mainBundle = CFBundleGetMainBundle();
    CFURLRef soundURL = CFBundleCopyResourceURL(mainBundle, (CFStringRef)soundFileName, CFSTR("aiff"), NULL);
    AudioServicesCreateSystemSoundID(soundURL, &soundID);
    AudioServicesPlaySystemSound(soundID);
    CFRelease(soundURL);
}

- (IBAction)answerButtonAction0:(id)sender {
    imageLabel0.text = [imageNames objectAtIndex:randomNumber[0]];
    if (correctAnswer == 0) {
        answerLabel0.text = @"O";
        nextQuizButton.userInteractionEnabled = true; //ボタンを押せるようにする
        [self sound:@"good"];
    } else {
        answerLabel0.text = @"X";
        [self sound:@"bad"];
    }
}

- (IBAction)answerButtonAction1:(id)sender {
    imageLabel1.text = [imageNames objectAtIndex:randomNumber[1]];
    if (correctAnswer == 1) {
        answerLabel1.text = @"O";
        nextQuizButton.userInteractionEnabled = true; //ボタンを押せるようにする
        [self sound:@"good"];
    } else {
        answerLabel1.text = @"X";
        [self sound:@"bad"];
    }
}

- (IBAction)answerButtonAction2:(id)sender {
    imageLabel2.text = [imageNames objectAtIndex:randomNumber[2]];
    if (correctAnswer == 2) {
        answerLabel2.text = @"O";
        nextQuizButton.userInteractionEnabled = true; //ボタンを押せるようにする
        [self sound:@"good"];
    } else {
        answerLabel2.text = @"X";
        [self sound:@"bad"];
    }
}

- (IBAction)answerButtonAction3:(id)sender {
    imageLabel3.text = [imageNames objectAtIndex:randomNumber[3]];
    if (correctAnswer == 3) {
        answerLabel3.text = @"O";
        nextQuizButton.userInteractionEnabled = true; //ボタンを押せるようにする
        [self sound:@"good"];
    } else {
        answerLabel3.text = @"X";
        [self sound:@"bad"];
    }
}

 


 

◆p.106、1.41節、<Xcode 4.1/4.2についての補足>

《1番目の画面》
Xcode 4.0では2番目の画面で「GameOverViewController」という名前を指定する手順でしたが、Xcode 4.2では1番目の画面で「Class」欄に名前を指定します。
64620_p106a.JPG

《2番目の画面》
②「Save」ボタンは、Xcode 4.2では「Create」ボタンとなっています。

 


 

◆p.111、1.43節、<Xcode 4.2についての補足>

《画面》
新しいXcodeで生成されるコードには「- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions」の冒頭に、紙面の画面写真と異なる行が加わっています。「self.window.rootViewController = self.viewController;」の行のみコメントアウトしてください。
64620_p111a.jpg
(本書のダウンロードファイルのプロジェクトはXcode 4.0で作成しているので、こちらをご利用の場合は紙面の通りです。)

 


 

◆p.112~114、1.44節、<Xcode 4.1/4.2についての補足>

《p.112の画面》
「@interface MyFlagIQViewController : UIViewController」に続く「{ 」~「}」のブロック部分の内容はp.86で操作した状態のままです。

@interface MyFlagIQViewController : UIViewController {
    NSArray *imageNames;
    int randomNumber[4];    
    int correctAnswer;
}

《p.113/114の2番目の画面》
「@interface GameOverViewController : UIViewController」に続く「{ 」~「}」のブロック部分がありません。ないままで大丈夫です。

 


 

◆p.115、1.45節、<Xcode 4.2についての補足>

《画面》
新しいXcodeで生成されるコードには「- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions」の冒頭に、紙面の画面写真と異なる行が加わっています。p.111で書き換えた「self.window.rootViewController = [[GameOverViewController alloc] init];」の行をコメントアウトしてください。
64620_p115.jpg
(本書のダウンロードファイルのプロジェクトはXcode 4.0で作成しているので、こちらをご利用の場合は紙面の通りです。)

 


 

◆p.119、1.46節、<Xcode 4.1/4.2についての補足>

《画面》
「@interface MyFlagIQViewController : UIViewController」に続く「{ 」~「}」のブロック部分の内容はp.86の状態に操作するので、仕上がりは下記のようになります。

@interface MyFlagIQViewController : UIViewController {
    NSArray *imageNames;
    int randomNumber[4];    
    int correctAnswer;
    int quizCount;
}

 


 

◆p.121、1.47節、<Xcode 4.1/4.2についての補足>

《画面》
「@interface MyFlagIQViewController : UIViewController」に続く「{ 」~「}」のブロック部分の内容はp.119の状態に操作するので、仕上がりは下記のようになります。

@interface MyFlagIQViewController : UIViewController {
    NSArray *imageNames;
    int randomNumber[4];    
    int correctAnswer;
    int quizCount;
    int score;
}

 


 

◆p.122、1.47節、<Xcode 4.2についての補足>

《2つの画面》
「- (void)view WillAppear:(BOOL)animated」がすでに生成されているので、自分で直接打ち込む必要はありません。該当箇所を探して「score = 0;」を記述してください。
64620_p122b.jpg
(本書のダウンロードファイルのプロジェクトはXcode 4.0で作成しているので、こちらをご利用の場合は紙面の通りです。)

 


 

◆p.123、1.48節、画面写真中の吹き出しテキストの下行

「viewDidLoaded」を「viewDidLoad」へ訂正いたします。
《誤》 の中の「-(void)viewDidLoaded」です
《正》 の中の「-(void)viewDidLoad」です

 


 

◆p.124、1.48節、<Xcode 4.1/4.2についての補足>

《画面》
「@interface GameOverViewController : UIViewController」に続く「{ 」~「}」のブロック部分がありません。そのため、「 int score;」を追加する際に、「{ 」~「}」も下記のように追加します。

@interface GameOverViewController : UIViewController {
    int score;
}

 


 

◆p.126、1.49節、<Xcode 4.1/4.2についての補足>

《1番目の画面》
「@interface GameOverViewController : UIViewController」に続く「{ 」~「}」のブロック部分の内容はp.124で操作した状態のままです。

@interface GameOverViewController : UIViewController {
    int score;
}

 


 

◆p.130、1.51節、画面写真中の吹き出しテキスト、上から4番目

《誤》 Animation終了時のUI部品の姿
《正》 Animation終了時のUI部品の姿

 


 

◆p.179、4.1節、<Xcode 4.2についての補足>

《右側の画面》
Product Nameにプロジェクトの名前「HelloWorld」、Company Identifierに会社の識別子「jp.myiphonecompany」を入力し、Typeは「C」を選択します。Use Automatic Reference Countingはチェックしません。
64620_p179b.jpg

 


 

◆p.333、5.41節、下から3行目の中央

「viewDidLoaded」を「viewDidLoad」へ訂正いたします。
《誤》 画面が表示される前に終えておく必要があるのでviewDidLoaded
《正》 画面が表示される前に終えておく必要があるのでviewDidLoad