【Objective-C】XcodeでiPhoneアプリを作る基礎を学ぶ14【懐中電灯アプリを作る】

Xcode


だらだらとXcodeを学ぶ記事を書き続けて14回目。

ここまで来たら使えるアプリの1つでも作りたいよ!

ちっとも使えるようにならないよ!

と、モチベーションの低下も甚だしいと思うので、ここは1つ使えるアプリを作ってみよう。



懐中電灯アプリを作ってみよう


カメラの横についているLEDを点灯させて懐中電灯代わり作るアプリを作ってみよう。

そんなの無料のやつ持ってるよ!

って言う人もいるだろうけど、無料アプリは大体広告ついているので、誤ってタップしてしまうとLEDが消えてしまう。

暗いときに消えてしまうとかなりうっとうしいので広告は無い方が望ましい。

かといって有料のものを買うのもばかばかしいので自作してしまおう。

デベロッパ登録をしているけどアプリは何一つ作ったことがないという人にもお勧め。

かなり簡単だしね。



新規プロジェクトの作成


Xcodeを起動し、左上のメニューバーからFile→New→Projectを選択。

Single View Applicationを選択。


skitchQVSgSb



Project NameはLEDLightとつけたが、何でもよい。

変数を学ぶ回でプロジェクトを作ったのでスムーズに行くと思う。

DevicesはiPhoneにするのを忘れずに。


skitch3Pu7m5



AVFoundation.frameworkを追加


今回はiPhoneのカメラ昨日の中のライトを点灯させるため、ビデオカメラを操作するためのフレームワーク、AVFoundationを追加する。

左側のメニューからLEDLightをクリック→TARGETSのLEDLight→Build Phases→Link Binary With Librariesの三角をクリックして開き、+ボタンをクリック。


skitchVmH9HT



開いたメニューの中からAVFoundation.frameworkを選択し、Addをクリック。


skitchzaNZmG



AVFoundation.frameworkが追加された。


skitchSnLhrm



左側のメニューにあるFrameworkフォルダの中にAVFoundation.frameworkがあるはずだが、もし違う場所にあったらドラッグアンドドロップでFrameworkフォルダの中に移動しよう。


skitch4Hag7g



これでAVFoundation.frameworkは実装された。



StoryboardでViewControllerの設定


まず、View Controllerにスイッチを設定するためにStoryboardでの操作。

左メニューからStoryboardをクリックし、ViewControllerをクリックする。

そして、オフの状態の時は画面を黒にするため、backgroundをBlack Colorにする。


skitchkLNXvm



右下のメニューからSwitchを選び、ドラッグアンドドロップしてスイッチをViewControllerに実装する。


skitchIsD8ub



起動時はオフにするため、SwitchをクリックしてStateをonからoffにする。


skitchTYmFRB



ViewController.hにコードを記述


ViewController.hにスイッチを定義する。

オンの時にライトがつき、オフの時にライトが消えるようにするため。

左側にあるメニューの中からViewController.hをクリックする。

開いたら下記のようにコードを記述。

赤字の部分が追加した部分になる。


#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>

@interface ViewController : UIViewController
{
IBOutlet UISwitch *ledLightSwitch;
}

– (IBAction)changeSwitch;



#import <AVFoundation/AVFoundation.h>は、AVFoundation.frameworkを使いますよという宣言。

IBOutlet UISwitch *ledLightSwitch;は、スイッチ機能を使いますよと宣言している。

– (IBAction)changeSwitch;は、実際にオンオフしたときの動作を記述するためのメソッドを宣言。

実際の動作はViewController.mに記述する。



ViewController.hで定義したSwitchをStoryboardで関連づけ


Switchや動作のメソッドを宣言したのはいいものの、このままだとXcodeがどのスイッチを操作したときに動作すればいいのかわからないので、このスイッチを操作したときですよ!と教えてあげる。


まず、Storyboardを選択し、Xcodeの右上にあるEdhitorの真ん中のボタンをクリックする。

左にStoryboard、右にViewController.hが開くはずだが、もしViewController.mだった場合はタキシードボタンをクリックしてautomaticを選択し、ViewController.hを選択する。


skitch8McPh3



StoryboardのSwitchを選択し、controlキーを押しながらコードに向かってドラッグアンドドロップする。

するとコードの左側にある○が●にかわる。

これが関連づけされてますよ、という目印になる。


skitch6D34vV



ViewController.mにコードを記述


さて、本命のViewController.mに実際の動作のコードを記述していこう。

コードは下記の通りになる。

変更したところは赤字の部分。


#import “ViewController.h”

@interface ViewController ()

@end

@implementation ViewController

– (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.

}

– (IBAction)changeSwitch
{
AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

 if (ledLightSwitch.on == YES) {
  self.view.backgroundColor = [UIColor whiteColor];

  [captureDevice lockForConfiguration:NULL];
  captureDevice.torchMode = AVCaptureTorchModeOn;
  [captureDevice unlockForConfiguration];

 }else{
  self.view.backgroundColor = [UIColor blackColor];

  [captureDevice lockForConfiguration:NULL];
  captureDevice.torchMode = AVCaptureTorchModeOff;
  [captureDevice unlockForConfiguration];
  }
}


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

@end


これだけです。

短いね。

とりあえずコードの内容をちょっと説明。

AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

は、iPhone背面のビデオカメラを使いますよ、と宣言している。

これはAVFoundation.frameworkをインストールしていないと使えない。


if (ledLightSwitch.on == YES) {

は、SwitchがONになった場合、という意味。


self.view.backgroundColor = [UIColor whiteColor];

これはバックグラウンドカラーを白に変えろ、という意味。


[captureDevice lockForConfiguration:NULL];
captureDevice.torchMode = AVCaptureTorchModeOn;
[captureDevice unlockForConfiguration];

この三行がiPhoneの背面についているLEDライトを点灯させるコード。

AVCaptureTorchModeOnでライトをONにする。

lockForConfigurationとunlockForConfigurationで挟まれているのは、ロックしないとトーチモードをONに出来ないため。

これはAVFoundationの仕様なので、そんなもんだと思ってくれればいい。


}else{

これは一番最初のif文からの繋がり。

if〜で、〜の場合という意味になるので、elseはそうじゃなかった場合、という意味になる。

今回の場合はONかOFFかの2択なので、OFFになった場合という意味。


self.view.backgroundColor = [UIColor blackColor];

まんまの意味だね。

バックグラウンドカラーを黒にかえる。


[captureDevice lockForConfiguration:NULL];
captureDevice.torchMode = AVCaptureTorchModeOff;
[captureDevice unlockForConfiguration];

トーチモードをオフにする。

これで背面のLEDライトが消える。



実機で動かしてみよう


シミュレータで動かしてもただバックグラウンドカラーがかわるだけだが、デベロッパ登録をしてiPhoneにインストールしてスイッチをいじると、ちゃんとLEDがオンオフされる。


skitchTS47ll



オンにするとバックグラウンドカラーが白くなり、LEDライトが光る。


skitchJ4JL05


これで完成!と思いきやそうでもない。



若干のバグ


このままでも使えるのだが、ライトが点灯しているときにホームボタンを押してバックグラウンドに移してから再度アプリを起動しても、スイッチはオンになっているけどもLEDは点灯しない。

一旦スイッチをオフにし、再度オンにしなければならない。

挙動としてはおかしいので、ホームボタンを押した場合アプリの状態を保存せず、初期状態(スイッチがOFFの状態)にもどすようにする。



AppDelegate.mに追記


左側にあるメニューからAppDelegate.mをクリックしよう。

AppDelegate.mにはホームボタンを押してアプリをバックグラウンドに落としたときに行う動作を書き込むことが出来る。

– (void)applicationDidEnterBackground:(UIApplication *)application がそれ。

そこに下記のように書き込もう。


– (void)applicationDidEnterBackground:(UIApplication *)application
{
  exit(0);
}


これで出来上がり。

LED点灯時にホームを押し、再度起動してもアプリはちゃんとオフになっているはず。



iOS7にはOS内に実装されているけどね


iOS7からはiOSの一機能として統合されているので、わざわざアプリを作る必要が無いと言えば無いが、実際にリリースされるのは9月だしまだしばらく先。

広告のないLEDライトアプリは中々便利だよ。

点灯時や消灯時の画面の色を変更したり、スイッチではなくボタンでの操作に変更したりと色々カスタマイズできるのも自作のいいところ。

色々試してみてください。


【Objective-C】XcodeでiPhoneアプリを作る基礎を学ぶ14【懐中電灯アプリを作る】」への12件のフィードバック

  1. BG-5

    くずのはさん、こんにちは。

    シンプルでいいですね、懐中電灯アプリ。
    バックグラウンドのみ点灯、LEDのみ点灯、両方点灯とか選択できたりすればもっと便利かもw
    バックの色も暗順応を妨げにくい赤色や、オレンジなんかを任意で選べたりしてみる等々、いろいろ出来るようになれば面白いでしょうね。

    ところで、なぜかprowlがちゃんと動いていないっぽいんですよね~
    アプリ起動してやればメール拾っては来るんですが、逆に言うと起動しないとメールを拾って来ないようなんです。着信音もならないし・・・
    バックで起動してなきゃダメ、とかではないですよね・・・。
    前まではちゃんと動いてたんですが、メールがあんまり来ないので今日、気が付きました。
    私のiPhoneだけですかね、この不具合は。
    やはり、5Sに機種変更っすかねぇ・・・
    docomoから出るなら、それはそれでウェルカムですがw

    返信
    1. 葛葉 キョウジ(管理人) 投稿作成者

      Prowlアプリを一度削除して再インストール後再設定でもダメですかね?
      最近使ってないんでよくわからないですけどw

      このLEDライトはビデオカメラを使うときの一機能なので、
      バックグラウンドで点灯させることは出来ないんですよね(;´Д`)
      バックグラウンドで点灯できると凄い便利なんですけど。
      中々うまくいかないもんです(-_-;)

      返信
  2. BG-5

    くずのはさん、こんばんは。

    あー、そういえば、くずのはさんはauの5でしたもんね。
    再インストール、今度やってみます。

    LEDはそういう仕様なんですね~
    なるほど、なかなか理想通りにはいかないもんですねw
    そう考えれば、市販のアプリってホント良く出来てるんだなぁ…
    とあらためて感心してしまいますねw

    返信
  3. BG-5

    くずのはさん、おはようございます。

    prowlの件、なんだか「Appleのデベロッパーが先週の木曜日から予期せぬメンテナンスに入っちゃったけど、すぐの戻るからちょっと待ってて!」みたいなメッセージが書いてあったので、私のiPhone特有の問題ではないようです。
    まぁ、私の解釈が正しければの話ですがw
    英語は嫌いですw

    返信
    1. 葛葉 キョウジ(管理人) 投稿作成者

      ああ、そういえばデベロッパ用サイトがハッキングされちゃったっていうメールが届いてました。
      プッシュ用サーバーはAppleの認証が必要なので、それが影響してたんですね(;´Д`)
      しばらくしたら元にもどるっぽくてよかったですねw

      返信
  4. Nyanchu

    くずのはさん、こんちわー。
    ようやくデベロッパー登録終わり、
    実機でテストランできました♪
    LEDライト面白そうですね。パクらせて頂きますw

    当初は広告がなかった懐中電灯アプリも、
    アップーデートしたらバシバシ入って来ちゃって
    邪魔くさいんすよね。自作バンザーイ!

    返信
    1. 葛葉 キョウジ(管理人) 投稿作成者

      真っ暗なところを照らしてるのに広告を誤ってタッチしてしまうとイライラするので自作最高ですw
      iPhoneアプリの中でもライトアプリは毎晩寝室に行くときに使っているので、
      自作アプリが役にたってますw

      返信
  5. Nyanchu

    LEDソース
    丸々コピペしてハマりましたw
    AVCaptureDevice *captureDevice = [AVCaptureDevicedefaultDeviceWithMediaType:AVMediaTypeVideo];

    で、Device と default の間に半角スペースが必要とか、
    その後の構文には全角スペースが隠れていたりと・・・
    仕事でVBA使いますが、彼は自動で修正してくれるから、
    コピペで行けたのか!という事が分かりました。w

    さらに無駄に手数を踏んで、転送前に行う証明書設定でハマること半日orz。
    ちっ  きしょ〜〜(小梅(ふるっ

    返信
    1. 葛葉 キョウジ(管理人) 投稿作成者

      あれ?スペース入ってなかったですねw
      すいませんw

      返信
  6. Nyanchu

    コピペは自己責任で対処しますw

    ところで、くずのはさんはov-cをどうやって独学!?されてます?
    当方、いまいち為来りになじめず、なかなか楽しくなりませんorz

    返信
    1. 葛葉 キョウジ(管理人) 投稿作成者

      自分も下の中くらいなもんで何とも言えませんが、
      主に業務用アプリケーションを作っているので、
      UITableViewやUICollectionViewなど、
      使えるソースが書いてあるサイトを熟読して実際書いてみるとか、
      Gitでソースを公開している人のを拝借して動かしてみて、
      色々書き換えて挙動を確認したりしてます。
      参考書は何冊か買いましたが、一冊も読み切ったことはありませんw
      読んでるうちに睡魔がw

      返信
  7. Nyanchu

    わりと業種柄、知りうる伝手があるのですね
    うらやましいです。
    Git!? 少し調べましたが、ファイルを同期化させる仕組みみたいな
    ものが出てきましたが違うよね・・・。

    参考書・・・寝れない夜にはいいですけどねw

    にょ〜もにょもにょする〜

    返信

BG-5 へ返信する コメントをキャンセル

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)