2013年1月29日火曜日

Admob組み込み(GADBannerView)

Admobの組み込みに苦戦したので、共有いたします。。

Admobの言う通りに組み込み!!


Undefined symbols for architecture i386:
  "_OBJC_CLASS_$_SKStoreProductViewController", referenced from:
      objc-class-ref in libGoogleAdMobAds.a(GADOpener.o)
  "_SKStoreProductParameterITunesItemIdentifier", referenced from:
      -[GADOpener openInAppStore:fallbackURLString:] in libGoogleAdMobAds.a(GADOpener.o)
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)


こんなエラーが出現

[プロジェクト名をダブルクリック]
  ↓
[Build Phase]タブを選択
[ライブラリーの追加]
Admobのサイトには以下の4つだけでしたが、
AudioToolbox
MessageUI
SystemConfiguration
CoreGraphics
  +
AdSupport framework
StoreKit.framework


を追加
     ↓
[Build Setting]タブ
  ↓
[Other Linker Flags]
  ↓
-ObjCを設定

ソースはAdmobさんの
おっしゃる通りで


そうすると




こんな広告が出現!!

これで、ガッポリわっははは
になるといいですね。


2013年1月28日月曜日

009-BGMの再生(AVAudioPlayer)

NO MUSIC NO LIFE
方々へ

1969を忘れない
方々へ

今回はアプリ内でBGMや効果音を使う方法を紹介します。

学生は授業中
会社員は打ち合わせ中
議員さんは国会中

音が鳴るアプリを使えなくなるし、
電池の消費も増えるので、個人的には音は必要ないかなと思っていたのですが。。。

地味にユーザー様から、BGMが欲しいというご要望が多かったので、
実装してみました。


■生成
//BGM用のAVAudioPlayerを生成します
NSString *sBgmFilePath = [[NSBundle mainBundle] pathForResource:@"CrazyLove" ofType:@"m4a"];
//ファイルパスから、URLを作成
NSURL *sBgmFileUrl = [NSURL fileURLWithPath:sBgmFilePath];
//URLを読み込みオーディオのインスタンスを生成
AVAudioPlayer *mBgmSound = [[AVAudioPlayer alloc] initWithContentsOfURL:sBgmFileUrl error:nil];
//音楽をLOOPさせる
[mBgmSound setNumberOfLoops:-1];
//すぐに再生できるように準備
[bgmSound prepareToPlay];




NSString *sBgmFilePath = [[NSBundle mainBundlepathForResource:@"CrazyLove" ofType:@"m4a"];
処理は音楽ファイルのパスとファイル形式を指定しています。
今回の音楽のサンプルは"CrazyLove"という音楽ファイル、拡張子はm4a形式です。

今回の音楽のサンプルはm4a形式の音楽ファイルとなっていますが、
wavやcafも使えるので、地味に便利です。

音楽ファイルは画像ファイルと同じようにResourcesフォルダに格納してください。



[mBgmSound setNumberOfLoops:-1];
曲が終わったら、最初に戻りもう一度再生する設定をしています。

[mBgmSound setNumberOfLoops:2];
こうすると、2回ループする設定になります。

[mBgmSound setCurrentTime:3.0f];
曲の開始時間を設定します。


[bgmSound prepareToPlay];
再生する準備をする命令です。
音楽ファイルをあらかじめバッファリングして、
再生の命令ともに音楽が始まるようにしています。

■Music
//BGM用の再生
[bgmSound play];
//BGM用の停止
[bgmSound stop];


playで曲をかけて
stopで停止
あと、pauseとかもあったと思います。


■総論
BGMの実装事態はそんなに難しくないですね。

大ヒットしたなめこのゲームはなめこを採取するときの音が
良くてヒットしたとか、ヲインPOPもかわいい効果音がよくて
ヒットしたとかで。。。
なんやかんやで音は大事ですね。

とかいいつつも、カメラの音を消すアプリは大ヒットしてますね。。。

2013年1月20日日曜日

008−ダイアログの作成(UIAlertView)


ダイアログの表示について記載していこうと思います。
今回もコンセプトとしては、storyboardを使わない方向で行きたいと思います。
iPhoneのダイアログはAndroidと比べってかっこいいダイアログなので、
カスタマイズしなくてもそのまま使えるのがいいですね。

個人的にはアプリを作成すると、
一番お世話になるのがダイアログです。

どういう時に、どう使うかというと

・強制的にユーザー操作を止めたい!!
・ユーザーにメッセージを送りたい!!
・ユーザーに選択肢を与えたい!!

おまけで、

・座標を気にしなくても画面の真ん中に表示される


まぁ、結構便利なんです。

はい。。。。。


一番下のは、作り手側の気持ちとして、
すごいありがたいことでして、
サンプルソースでは、直接座標をしている事が多いのですが、
やっぱり、作り手としては座標の決め打ちはちょっと怖いですよね。

まぁ、iPhoneならそこまで端末が多い訳ではないので、
そこまで気にしなくてもいいかもしれませんが。。。

導入部分はこのくらいにして、メインのダイアログの表示方法です。


//ダイアログの作成
oAlert = [[UIAlertView alloc] init];
oAlert.delegate = self;
//ダイアログのタイトルを設定
oAlert.title = @"テストのダイアログ";
//メッセージを設定
oAlert.message = @"ラベルを表示する";
//ボタンを追加
[oAlert addButtonWithTitle:@"はい"];
[oAlert addButtonWithTitle:@"いいえ"];
//ダイアログを表示する
[oAlert show];

他のUIと同じ感覚で、
生成して文字列設定しています。
addSubviewのかわりに
showを使っています。

oAlert.delegate = self;

こちらの処理ですが、細かい事は自分も
あまりよくわからないので、大変申し訳ないのですが、
処理内容を通知する関数をどこに作るかという設定だと思います。

ダイアログ押下時に呼ばれる関数を作ると

// ダイアログのボタンが押された時に呼ばれるデリゲート例文
-(void)alertView:(UIAlertView*)alertView
clickedButtonAtIndex:(NSInteger)buttonIndex {
    switch (buttonIndex) {
        case 0:
            //1番目のボタンが押されたときの処理を記述する
            break;
        case 1:
            //2番目のボタンが押されたときの処理を記述する
            break;
    }    
}


こんな、感じです。
ダイアログとボタンとラベルを使った簡単なサンプルソースを
作ったので、こちらで全体的な動きの確認を

■サンプルソース
h.ファイル

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController{
    UILabel *oLabel;
    UIAlertView *oAlert;
}

@end

m.ファイル

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
    
    //ボタンの生成・ボタンタイプの指定
    UIButton *oButton =[UIButton buttonWithType:UIButtonTypeRoundedRect];
    //ボタン枠の作成
    oButton.frame = CGRectMake(00.0f, 150.0f, 300.0f, 50.0f);
    //普段のボタンタイトル
    [oButton setTitle:@"ダイアログを表示する" forState:UIControlStateNormal];
    //ボタン押下時のタイトル
    [oButton setTitle:@"ボタン押下中!!" forState:UIControlStateHighlighted];
    // ボタンがタッチダウンされた時にonPushメソッドを呼び出す
    [oButton addTarget:self action:@selector(onPush::)forControlEvents:UIControlEventTouchDown];
    //ボタンを画面に追加
    [self.view addSubview:oButton];


    //1番目のボタンが押されたときの処理を記述する
    oLabel = [[UILabel alloc] init];
    //枠の作成
    oLabel.frame = CGRectMake(00.0f, 00.0f, 350.0f, 100.0f);
    //文字列をラベルに設定
    oLabel.text = @"Hello World!!";
    //Viewに追加
    [self.view addSubview:oLabel];
    [oLabel setHidden:YES];
    
    
    //ダイアログの作成
    oAlert = [[UIAlertView alloc] init];
    oAlert.delegate = self;
    //ダイアログのタイトルを設定
    oAlert.title = @"テストのダイアログ";
    //メッセージを設定
    oAlert.message = @"ラベルを表示する";
    //ボタンを追加
    [oAlert addButtonWithTitle:@"はい"];
    [oAlert addButtonWithTitle:@"いいえ"];


    [super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

// ダイアログのボタンが押された時に呼ばれるデリゲート例文
-(void)alertView:(UIAlertView*)alertView
clickedButtonAtIndex:(NSInteger)buttonIndex {
    switch (buttonIndex) {
        case 0:
            //1番目のボタンが押されたときの処理を記述する
            [oLabel setHidden:NO];
            break;
        case 1:
            //2番目のボタンが押されたときの処理を記述する
            [oLabel setHidden:YES];
            break;
    }
    
}

// 呼ばれるonPushメソッド
-(void)onPush:(UIButton*)button:(id)sender{
    //ダイアログを表示する
    [oAlert show];
}

@end


■実行結果
1.初期表示

2.ボタン押下後

3.はいを押すと

4.もう一度、ダイアログを出して、いいえを押すと



実行結果はこんな感じです。
だいぶアプリっぽくなってきましたね。

すごい人なら、これくらいの機能だけで、
大ヒットアプリを余裕で作れます。
いや、本当に!!
なんたって
すごい人ですから。。。


ソースを振り返ると、
//ボタン押下時のタイトル
[oButton setTitle:@"ボタン押下中!!" forState:UIControlStateHighlighted];

このソースが全然意味がないですね。
2.の画像をよく見るとわかると思うのですが、
ボタンの文字列が押下前とかわっていません。。。

それと、今更ですが、

iOSだと、Dialogという文字列は使われていませんでした。
代わりに、Alertがよく使われていますね。

今更ですが、今回のタイトルは

008-アラートの作成(UIAlertView)

で、お願いいたします。

なぜ、ダイアログを使わない??

007-Button(UIButton)

今回もstroyboardを使わないシリーズです。

ラベル作成が簡単だったので、
今回も簡単だと思っています。おそらく余裕ですね。

代表的なユーザー操作である、
ボタンを押すという処理。

ボタンを制する物はユーザーを制するとかしないとか。

//ボタンの生成・ボタンタイプの指定
UIButton *oButton =[UIButton buttonWithType:UIButtonTypeRoundedRect];
//ボタン枠の作成
oButton.frame = CGRectMake(00.0f, 150.0f, 300.0f, 50.0f);
//普段のボタンタイトル
[oButton setTitle:@"Hello World" forState:UIControlStateNormal];
//ボタン押下時のタイトル
[oButton setTitle:@"Goodbye World!!" forState:UIControlStateHighlighted];
// ボタンがタッチダウンされた時にonPushメソッドを呼び出す
[oButton addTarget:self action:@selector(onPush::)forControlEvents:UIControlEventTouchDown];
//ボタンを画面に追加
[self.view addSubview:oButton];


こんな感じで。。
ラベルと違って、
buttonTypeを指定しないと画面に表示されませんでした。。。

[oButton addTarget:self action:@selector(onPush::)forControlEvents:UIControlEventTouchDown];
ボタン押下時にonPushという関数を読んでいます。


呼ばれる関数はこんな感じで作っちゃってください。
-(void)onPush:(UIButton*)button:(id)sender{

}

Androidのように
クッリクした時の処理を別関数で作る仕様になっております。

また、idを引数にする事で、オブジェクトをなんでも渡せます。
なので、割と便利。。




■サンプルソース
h.ファイル

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController
{
    UILabel *oLabel;
}

@end



m.ファイル
#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
    //ボタンの生成・ボタンタイプの指定
    UIButton *oButton =[UIButton buttonWithType:UIButtonTypeRoundedRect];
    //ボタン枠の作成
    oButton.frame = CGRectMake(00.0f, 150.0f, 300.0f, 50.0f);
    //普段のボタンタイトル
    [oButton setTitle:@"Hello World" forState:UIControlStateNormal];
    //ボタン押下時のタイトル
    [oButton setTitle:@"Goodbye World!!" forState:UIControlStateHighlighted];
    // ボタンがタッチダウンされた時にhogeメソッドを呼び出す
    [oButton addTarget:self action:@selector(onPush::)forControlEvents:UIControlEventTouchDown];
    //ボタンを画面に追加
    [self.view addSubview:oButton];
    
    //順位を表示するラベル
    oLabel = [[UILabel alloc] init];
    //枠の作成
    oLabel.frame = CGRectMake(00.0f, 00.0f, 350.0f, 100.0f);
    //文字列をラベルに設定
    oLabel.text = @"ボタン押された";
    //背景色をかえる
    oLabel.backgroundColor = [UIColor blackColor];
    //文字の色
    oLabel.textColor = [UIColor yellowColor];
    //フォントの設定
    oLabel.font = [UIFont fontWithName:@"AppleGothic" size:24];
    //文字の場所
    oLabel.textAlignment = UITextAlignmentCenter;
    [oLabel setHidden:YES];

    //Viewに追加
   [self.view addSubview:oLabel];
    
    [super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

// 呼ばれるhogeメソッド
-(void)onPush:(UIButton*)button:(id)sender{
    Boolean bPushFlg = [oLabel isHidden];
    [oLabel setHidden:!bPushFlg];
}
@end


■実行結果
1.初期起動時

2,ボタン押下後
3.もう一回ボタンを押すと

こんな感じになります。

ボタンを押すと前回紹介したラベルを表示させます。


Boolean bPushFlg = [oLabel isHidden];
[oLabel setHidden:!bPushFlg];


Hiddenを使う事で、
表示、非表示の設定をしています。

取得した現在のステータスの反対を
設定しています。

2013年1月19日土曜日

006−storyboardを使わないでラベル表示(UILabel)

Ojective-Cはただでさえ、hファイルとmファイルが存在して、
ちょっと面倒なのにstoryboardもみないといけないとか大変!!

という方に。。。
ソースコードから、ラベルを生成して、
画面に貼付けてみましょう。

■サンプルソース
//順位を表示するラベル
UILabel *oLabel = [[UILabel alloc] init];
//枠の作成
oLabel.frame = CGRectMake(00.0f, 00.0f, 350.0f, 100.0f);
//文字列をラベルに設定
oLabel.text = @"Goodbye World!!";
//Viewに追加
[self.view addSubview:oLabel];

■実行結果







簡単にできたので、
他のプロパティーも紹介します。
addSubviewの前に下記を追加してください。

//背景色をかえる
oLabel.backgroundColor = [UIColor blackColor];
//文字の色
oLabel.textColor = [UIColor yellowColor];
//フォントの設定
oLabel.font = [UIFont fontWithName:@"AppleGothic" size:24];
//文字の場所
oLabel.textAlignment = UITextAlignmentCenter;

■実行結果



■総括
ラベルの表示ですが、
結構、面倒くさいのかなと思っていましたが、
わりと結構簡単にできました。

2013年1月12日土曜日

005-保存機能(NSUserDefaults)

アプリ内でデータを保存したくなることありますよね。

ゲームのアプリならハイスコアやパラメータ。
便利ツールのアプリなら個人設定内容や履歴などなど。。

まあ、それはそれとしてハイスコアの保存って、発想がふるいですね

Webでデータを持つ方法やDBを使う方法もありますが、
今回紹介するのはNSUserDefaultsを用いた保存です。

Androidで言うところのPreference機能です。
使い方もPreferenceとだいたい同じです。

■保存する関数

-(Boolean)Save_Date:(NSString *)sKey :(NSString *)sItem{
    NSUserDefaults *oDefaults = [NSUserDefaults standardUserDefaults];
    [oDefaults setObject:sItem forKey:sKey];
    Boolean successful = [oDefaults synchronize];
    if (successful) {
        NSLog(@"%@", @"データ保存成功");
        return true;
    }
    NSLog(@"%@", @"データ保存失敗");
    return false;
}


キー(ユニークな文字列)を指定して、
そのキーに保存内容を渡して、保存します。
Dictionary感覚ですね。

[oDefaults setObject:sItem forKey:sKey];

setObjectの箇所は変数の型によってかわります。


intならsetInteger
boolならsetBool


となりますので、ご気を付けてください。

■保存内容を取得する関数

-(NSString *)Get_Date:(NSString *)sKey{
    NSUserDefaults *oDefaults = [NSUserDefaults standardUserDefaults];
    NSString *sDate = [oDefaults stringForKey:sKey];
    if (sDate) {
        return sDate;
    }
    NSLog(@"%@", @"データが存在しません。");
    return @"";
}

の取得の仕方も保存とだいたい同じです。

NSString *sDate = [oDefaults stringForKey:sKey];
stringForKeyの箇所は変数の型によってかわります。

intならintegerforKey
boolならboolforKey

となりますので、ご気を付けてください。


■保存内容を消す関数

-(Boolean)Delete_Date:(NSString *)sKey{
    NSUserDefaults *oDefaults = [NSUserDefaults standardUserDefaults];
    [oDefaults removeObjectForKey:sKey];
    Boolean successful = [oDefaults synchronize];
    if (successful) {
        NSLog(@"%@", @"保存データは消えました。笑");
        return true;
    }
    NSLog(@"%@", @"保存データ削除失敗!!");
    return false;
    
}

保存内容を消す関数とか個人的には使う事はないのですが、
一応用意されているので。。。
少しでもキャッシュデータを軽くするために
使うのでしょうか??

端末に保存する機能ですが、
携帯のデータはユーザー操作で簡単に
データが消えてしまうので、
大事な大事なデータは端末で管理するよりも
Webで管理して、ユーザーが復旧できる
措置を作る用にしましょうね。

とかいっても、個人で作るアプリに
そんなクオリティーを求められても
困りますが。。。。





2013年1月6日日曜日

004-クラス(@interface @implementation)

クラスを作成するのに、迷った方へ

JAVA感覚のあなたへ


クラスの作成方法から、呼び出しかたを
簡単にですがまとめてみました。


よかったら、ご参照下さい。

■クラス用に新規ファイル作成

新規ファイルを作成するのに、
戸惑ったので、共有を


[File]→[New]→[File...]



[Cocoa Touch]→[Objective-C class]→[Next]
オブジェクト名の指定

これで、新規ファイルの完成です。

ではまず、hファイルから




TestClass.hファイルを作成したら、



@class TestClass;

@interface TestClass : NSObject
{
    bool bFlg;
}


- (void)Make_Flg;
- (bool)Chk_Flg;

@end


関数の作り方は003-関数をご参照でお願いいたします。

hファイルは

@interface クラス名 : NSObject{
    変数の記述
}

   関数の記述

@end

こんな形になっています。

interfaceのクラス名はファイル名と同じで。。

メソッドとかインスタンス変数とか覚えないといけないことはありますが、
とりあえず今回は置いときましょう。

そして、mファイル


#import "TestClass.h"

@implementation TestClass

-(bool) Chk_Flg{
    if (bFlg){
        return true;
    }
    return false;
}

-(void) Make_Flg{
    bFlg = true;
}


@end




importは対になるhファイルだけで、
関数の書き方は、前回と同じでお願いいたします。

@implementationは使い方としては


@ implementation クラス名
    関数の記述
@end


これで、大丈夫。。。


今回作った関数の説明をいたしますと。。

Chk_FlgはbFlgがtrueなら、
trueを返す関数です。

Make_FlgはbFlgをtrueにする関数です。

本当なら、コンストラクター的な何かで、
初期化して、bFlgをfalseにしないといけないですね。


そして、この関数を呼び出すときは


#import "TestClass.h"

をhファイルに追記して、
mファイルに

    TestClass obj = [[TestClass allocinit];
(もしくは    id obj = [[TestClass alloc] init];)

    [obj Make_Flg];
    
    if ([obj Chk_Flg]){
        
        oLabel1.text = @"trueだ!!";
    }else{
        oLabel1.text = @"falseだ!!";
    }


こんな感じで記述すれば使えます。
make_Flgをコメントアウトすると、
falseに入ります。

呼び出し方で大事なのは、


    TestClass obj = [[TestClass allocinit];
(もしくは    id obj = [[TestClass allocinit];)


allocしてから、initすることです。

こんな感じで、とりあえずのところは
クラスの作成と呼び出し完了です。

もっと
基本的なことや覚えないといけないことはありますが、
とりあえず動く物で。


Undefined symbols for architecture i386 エラー

こんな、エラーが出てしまった。


Undefined symbols for architecture i386:
  "_main", referenced from:
      start in crt1.o
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)



どうすればのかな??

プロジェクトをクリーンしてもうまくいかないし。。。。

importのファイルを間違えているのか??


いろいろ調べた結果。。。。。。。。。

supportfileが消えているのが原因でしたあ。。

以後気を付けます。