MOSA Multi-OS Software Artists

MOSAはソフトウェア開発者を支援します

  • iPhone/iPod touch アプリ紹介
  • MOSA掲示板
  • 活動履歴
  • About MOSA(English)

MOSA Developer News[MOSADeN=モサ伝]第342号

2009-05-12

目次

  • 「Wonderful Server Life」    第92回   田畑 英和
  • 小池邦人のCarbon視点でiPhone探求
  • ターミナルの向こうから      第47回  海上 忍 

「Wonderful Server Life」  第92回  田畑 英和

〜「Deployment」編〜

 前回、モデルチェンジした新しいXserveをご紹介しましたが、この新Xserve用のLOM Firmwareのアップデートがリリースされています。

・ニュースリリース
http://support.apple.com/downloads/Xserve_LOM_Firmware_Update_1_2

 それでは前回の続きで「システムイメージユーティリティ」を使ったシステムイメージの作成方法について解説していきます。システムイメージを作成するにはまず、イメージのソースの準備が必要になります。

◇イメージのソースの準備 
 イメージのソースとは、イメージの作成元のことです。NetBoot/NetInstallではサーバ上に用意したシステムイメージをネットワークを経由してクライアントコンピュータに提供しますが、この元となる環境をまずは用意しなくてはなりません。起動可能なシステムボリュームをソースとして使用することができます。
 ソースを準備するには、まずモデルとなるMacを用意してそこでクライアントコンピュータの環境を構築します。ここで重要なのは共通のシステムイメージを複数のクライアントで共有しますので、クライアントごとに異なる内容というものは基本的にはソースの中に含めることができません。例えばクライアントコンピュータによってインストール済みのソフトウェアを変えたいといった場合1つのソースだけでは対応できないことになります。ですのでソースはあくまでもすべてのクライアントに共通の内容にしておきます。どうしても1つのソースで対応できない場合は、複数のソースから複数のイメージを作成することもできます。
 またモデルとして使用するMacの機種にも注意が必要です。基本的には実際に使用するクライアントと同じ機種を用意するのが最も問題のない方法です。もし使用するクライアントが複数の機種から構成されている場合にはその中から最新の機種を使用するようにしましょう。OSのバージョンによっては機種によって起動できたりできなかったりする場合があるからです。クライアントの機種が統一されている環境が理想的です。イメージは複数運用できますので、機種ごとにイメージを作成することも技術的には可能ですが、ただし管理の手間がかかることになります。
 ネットワーク経由でインストールを行うNetInstallの場合には、OSのインストールディスクからシステムイメージを作成することもできます。

◇イメージの保存場所の設定
 NetBootサービスではサーバ上でイメージを保存しておくための場所をあらかじめ用意しておく必要があります。そこで「サーバ管理」を使ってイメージの保存場所を設定します。
 「サーバ管理」でサーバに接続し、左側のリストからNetBootサービスを選択します。リストにまだNetBootが表示されていない場合は追加しておきます。
ツールバーから「設定」をクリックし「一般」設定画面を表示します。この画面の下半分にあるのがイメージの保存場所の設定になります。ここにはサーバ上でアクセス可能なボリュームの一覧が表示されますので、イメージを保存するボリュームの「イメージ」をチェックし、「保存」ボタンをクリックします。
すると指定したボリュームに「/Library/NetBoot/NetBootSP0」(*1)が作成されここにシステムイメージを保存することになります。イメージの保存場所として指定するボリュームには十分な空き容量があることを確認しておきましょう。

・イメージの保存場所の設定
http://www.htabata.com/img/MXS105/netboot/nb_admin_01.png

 イメージの保存場所の設定の他にも「クライアントデータ」という設定項目がありますが、こちらについてはまた後ほど解説することにします。

*1 環境によってディレクトリ名はNetBootSP1、NetBootSP2…となります

◇イメージの作成
 それではいよいよシステムイメージの作成です。ここではサーバ上でイメージを作成するものとします。ソースとなるモデル用のMacの準備が整ったら、ターゲットディスクモードで起動してFireWireケーブルでサーバに接続します。
するとサーバにソースとなるシステムボリュームがマウントされます。
 次にサーバ上で「システムイメージユーティリティ」を起動し、左側のリストの「ソース」から、マウントしたシステムボリュームを選択します。
 作成するイメージのタイプを選択したら、「続ける」ボタンをクリックし、次の画面でイメージ名と説明を入力します。ここで設定したイメージ名と説明は後から「サーバ管理」で確認できますので、なにか管理しやすい情報を入力しておきましょう。
 「作成」ボタンをクリックすれば使用許諾契約が表示されますので「同意する」をクリックしてイメージの保存場所を選択します。イメージの保存場所とは先ほど「サーバ管理」で設定した「NetBootSP0」のことです。あとは「保存」ボタンをクリックするとイメージの作成が開始されます。イメージの作成にかかる時間はソースのサイズや、ハードウェアのスペックによっても異なりますが、表示メニューから「ログを表示」を選択しておけばイメージ作成の開始時刻と終了時刻を確認できますので、今後の作業の目安になるでしょう。

・イメージの作成
http://www.htabata.com/img/MXS105/netboot/siu_01.png
http://www.htabata.com/img/MXS105/netboot/siu_02.png

 それでは次回はNetBootサービスについて解説します。
                             次回へつづく

小池邦人のCarbon視点でiPhone探求(2009/05/08)

〜 UIImagePickerControllerで画像取り込み 〜

iPhone OS 3.0では画像をコピー&ペーストで別アプリケーションから持ってくることが可能になりました。しかしiPhone OS 2.2では、まだそうした操作はできません。主な画像の入手方法は、iPhoneの「写真ライブラリ」から得るか、アプリケーションから直接「写真撮影」するかのどちらかです。

ちなみに、そうした方法以外にも、ウェブサイト上に登録されている画像を持ってきたり、MacやWindowsマシンに保存されている画像ファイルをネットワーク経由で転送したりすることも可能です。機会があれば、こうした別の方法にもチャレンジしたいと思います。また、写真ライブラリにはiTunes経由で転送された画像も含まれますが、これらの画像は、iPhoneでの表示に最適化するために、オリジナルサイズから縮小されている場合があります。また自作アプリケーションからの写真撮影では、Core Locationを利用した位置情報が画像ファイルに添付されないという制限がありますので御注意ください。

「写真ライブラリ」からの画像の取り込みや「写真撮影」を利用するためには、UIKitに属するUIImagePickerControllerクラスを利用します。このクラスを使う場合に注意しなければいけない点は、iPod touchには「カメラ」が搭載されていないという事です。この事実を無視して、iPod touchでもカメラ撮影用の機能が使える状態になっていると(撮影ボタンなどがあると)App Storeへの登録申請において認可が下りない(リジェクトされる)ことになります。
くれぐれも注意してください。以下は、ユーザが「画像取り込み」ボタンを押した時のターゲット&アクションの一例です。

- (IBAction)getImage:(id)sender
{
   NSString        *b1,*b2,*b3;
   NSString        *esc,*title;
   UIActionSheet  *action;

   if( [UIImagePickerController isSourceTypeAvailable:
                   UIImagePickerControllerSourceTypeCamera]==YES )
                                           //  カメラ機能が使えるかどうか?
   {
       esc=NSLocalizedString( @"ESC_BUTN",@"" );    //  キャンセル
       title=NSLocalizedString( @"ACT_TYPE_01",@"");  //  タイトル
       b1=NSLocalizedString( @"ACT_TYPE_02",@"" );  //  写真アルバム
       b2=NSLocalizedString( @"ACT_TYPE_03",@"" );  //  カメラロール
       b3=NSLocalizedString( @"ACT_TYPE_04",@"" );  //  写真撮影
       if( action=[[UIActionSheet alloc] initWithTitle:title delegate:self 
               cancelButtonTitle:esc destructiveButtonTitle:nil 
               otherButtonTitles:b1,b2,b3,nil] )
       {
           action.actionSheetStyle=UIBarStyleBlackTranslucent; // スタイル設定
           [action showInView:self.view];  //  方法選択のアクションシートを開く
           [action release];
       }
   }
   else
       [self actionSheet:nil clickedButtonAtIndex:0];  //  写真アルバムを開く
}

現在のデバイスでカメラが利用できるかどうかは、 UIImagePickerControllerのクラスメソッドであるisSourceTypeAvailable:で確認できます。もしカメラが使えるならば、先んじてアクションシート(UIActionSheet)を表示させ、「写真アルバム」「カメラロール」「写真撮影」の3つの方法のどれを利用するかユーザに選択させます。カメラが使用できなければ、アクションシートを表示させずに、強制的に「写真アルバム」から画像を読み込む処理を実行させます。この場合は、アクションシート上の最初のボタン(番号はゼロ)を押した処理と同等となります。

アクションシートに表示するボタンのタイトルですが、直接ソースコード内に日本語で書き込んでも問題はありません。しかし、後々の英語ローカライズを考慮して「ja.lproj」(日本語リソース)フォルダ内に、Localizable.stringsファイルを用意し、アプリケーション内で使用する文字列をキーで参照できるよう定義しておきます。こうした文字列はNSLocalizedString()ルーチンにキーを渡して読み込むことが可能です。
iPhoneの言語設定を変更すると読み込まれるLocalizable.stringsファイルが切り替わり、その言語設定に対応した文字列が表示される仕組みです(無ければデフォルトが使われる)。

ESC_BUTN="キャンセル";
ACT_TYPE_01="画像の取り込みを行えます。";
ACT_TYPE_02="写真アルバム";
ACT_TYPE_03="カメラロール";
ACT_TYPE_04="写真撮影";

さて、アクションシートが表示され、ユーザにより表示されているボタンのどれかが押されると、UIActionSheetのデリゲートが呼ばれ、そこで適切な処理へと分岐させる処理を実行させます。こうしたデリゲートのいくつかは、各クラスでプロトコルとして定義されています。今回の処理で関係するのは以下の3つのプロトコルです。

@protocol UIActionSheetDelegate
@protocol UIImagePickerControllerDelegate
@protocol UINavigationControllerDelegate

よってそれらを利用する場合には、そのクラス定義(ヘッダファイル)において、各プロトコルに準拠していることを明記しておく必要があります。この「プロトコルへの準拠」の記載がなされていないと、Make時にXcodeがアラート(警告)を表示します。以下の様に、今回のRootViewControllerクラスは3つのプロトコルに準拠していることを明記しておきます。

@interface RootViewController : UITableViewController
< UINavigationControllerDelegate,
UIActionSheetDelegate,
UIImagePickerControllerDelegate >

アクションシートでボタンが押されると、そのデリゲートメソッドであるactionSheet: clickedButtonAtIndex:が呼ばれます。ボタン番号はbuttonIndexから得られますので、その値を確認し、キャンセルボタン以外であればUIImagePickerController(画像ピッカー)を作成して、その後の処理は全部それ(iPhone OS側)に任せてしまいます。

- (void)actionSheet:(UIActionSheet *)actionSheet 
                               clickedButtonAtIndex:(NSInteger)buttonIndex
{
   UIImagePickerController    *picker;
   NSUInteger                type;

   if( buttonIndex!=3 )    //  キャンセルボタンではない
   {
       if( buttonIndex==0 )  //  写真アルバムから画像を読み込む
           type=UIImagePickerControllerSourceTypePhotoLibrary;
       else if( buttonIndex==1 )  //  カメラロールから像を読み込む
           type=UIImagePickerControllerSourceTypeSavedPhotosAlbum;
       else if( buttonIndex==2 )  //  写真撮影を行う
           type=UIImagePickerControllerSourceTypeCamera;

       if( picker=[[UIImagePickerController alloc] init] )
       {
           picker.allowsImageEditing=YES;  //  画像編集(トリミング)を許す
           picker.sourceType=type;  //  画像ピッカーのタイプを設定
           picker.delegate=self;    //  デリゲートはこのオブジェクト
           [self presentModalViewController:picker animated:YES];
                                       //  画像ピッカーをオープンする
           [picker release];
       }
   }
}

タイプ設定のための定数の名称ですが、日本語環境でのUIImagePickerController(画像ピッカー)のタイトル表示と何故だか一致していないので注意してください(仕様変更して欲しい)。
UIImagePickerControllerSourceTypePhotoLibraryでは「写真アルバム」というタイトルが表示され、UIImagePickerControllerSourceTypeSavedPhotosAlbumの方では「カメラロール」というタイトルが表示されます。

画像ピッカーで画像を得るための処理が正しく終了すると、以下のデリゲートメソッドが呼ばれます。引数で渡されるimage(UIImage *)が対象となる画像です。そのデータをファイルへ保存し、そのパス名をモデルオブジェクトへ登録する処理をここに記載すればOKとなります。これらの処理については、また別の機会に解説したいと思います。

- (void)imagePickerController:(UIImagePickerController *)picker 
                       didFinishPickingImage:(UIImage *)image
                         editingInfo:(NSDictionary *)editingInfo
{
  // ここにモデルオブジェクトへの登録と画像ファイルの保存処理を記述する

  [self dismissModalViewControllerAnimated:YES]; // 画像ピッカーを閉じる
}

画像ピッカーでキャンセルボタンが押された場合には、以下のデリゲートメ
ソッドが呼ばれます。この時には何もせずに画像ピッカー
(UIImagePickerController )を閉じます。

- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker;
{
   [self dismissModalViewControllerAnimated:YES];  //  画像ピッカーを閉じる
}

取り込んだ画像をファイルへ保存し、そのパス名をモデルオブジェクトへ登録する準備が整いました。次回からは、UIViewController(多分UITableViewController)上に配置したUITableViewにそうした画像を一覧表示させる処理へと話を進めたいと思います。

ターミナルの向こうから      第47回  海上 忍

〜 リモートでシェルを使う(2) 〜

・「scp」を知る
 scpは、Secure SHell(SSH)の機能を利用し安全にファイルコピーするためのコマンドです。UNIX系OSで古くから利用されているrcp(Remote CoPy)のSSH対応版であり、コマンドの用法はほぼ同じです。rcpと同等以上の機能を備えた、ネットワーク経由で安全なファイル転送を行うためのコマンド、と理解すればいいでしょう。scpの基本的な用法は、以下のとおりです。

- - - - -
scp [option] ファイル名 user@コピー先パス
- - - - -

 ここで、通常の(単独ホスト上での)コピーを行うcpコマンドの用法と比較してみましょう。オプションを指定しないとして、第1引数が(オリジナルの)ファイル名、第2引数がコピー先(ファイルの複製をつくる先)という2点が共通していることがわかるはずです。両者の違いは、scpコマンドが「コピー先にネットワーク上のアドレスを指定できる」という点にあります。

- - - - -
cp [option] ファイル名 コピー先
- - - - -

 なお、scpコマンドを利用するに際しての前提条件は、コマンド実行時に(接続先の)SSHサーバが稼働していること、SSHサーバ上にユーザアカウントが存在していること、そしてMacのターミナルなどscpコマンドを実行できる環境があることの3点です。Mac OS X Leopardを例にすると、接続先のSSHサーバ上にアカウントさえ作成済であれば、OS標準の状態で一連の機能を利用できることになります。GUIのアプリケーションを用意する必要も、事前にsshでログインしておく必要もありません。思い立ったときに最小限の装備でリモートサーバ上へファイルコピーできる点が、scpコマンドを利用するメリットです。

・コピー先パスを記述する

 cpとほぼ同じ用法を持つscpですが、cpはコピー先のパス(ディレクトリ)を示せば十分であることに対し、ユーザ名から始まるコピー先パスを指定しなければなりません。その記述ルールは「ユーザ名@サーバのURL:パス」で、記号「@」と「:」で区切るところがポイントです。たとえば、以下の記述例は、コピー先のサーバが「hoge.com」、サーバ上のパス(ディレクトリ)が「/public_html」、ユーザ名が「dareka」のときのものです。

- - - - -
dareka@hoge.com:public_html
- - - - -

 このとき、パス(「:」以降のディレクトリ名)を省略すると、ユーザのホームディレクトリがコピー先に適用されます。

・手元のファイルをサーバ上にコピーする
 それでは、実例をもとにscpコマンドの使い方を紹介してみましょう。手始めに、基本形の「手元のファイルをサーバ上にコピー」することから始めてみます。コピーしたいファイルが「top.jpg」、その他の前提条件が先ほどの例と同じとすると、以下のとおり実行すればいいことになります。なお、scpコマンドは実行のつどパスワードを入力する必要があります。

- - - - -
$ scp top.jpg dareka@hoge.com:public_html
dareka@hoge.com's password:
- - - - -

・サーバ上のファイルを手元のMacにコピーする
 上記の例とは逆に、サーバ上のファイルを手元のMacにコピーしたい場合には、第1引数に「user@コピー先パス」を指定し、第2引数にMac上のパスを指定します。先ほどの例でサーバにコピーしたファイルを対象にする場合、次のとおりコマンドを実行することになります。

- - - -
$ scp dareka@hoge.com:public_html/top.jpg .
dareka@hoge.com's password:
- - - -

 このとき、Mac上のパスに「.」を指定すると手間がかかりません。「.」はカレントディレクトリを意味するため、その操作時点で利用しているディレクトリにファイルをコピーできるため、以下のコマンドを実行すれば、すぐにFinderでファイルを確認できます。

- - - - -
$ open .
- - - - -

・ファイルを一括コピーする
 scpコマンドでは、cpコマンドと同様にワイルドカード「*」を使用できます(シェルにbashを利用している場合)。拡張子が同じ複数のファイルをまとめてコピーしたい場合は、以下の要領でコマンドを実行するといいでしょう。

- - - - -
$ scp *.jpg dareka@hoge.com:public_html
dareka@hoge.com's password:
- - - - -

 オプションに「-r」を指定すれば、ディレクトリ(フォルダ)ごとコピーすることもできます。たとえば、手元のMacでカレントディレクトリに存在する「MyDocs」フォルダをコピーする場合は、以下の要領でコマンドを実行します。

- - - - -
$ scp -r MyDocs dareka@hoge.com:public_html
dareka@hoge.com's password:
- - - - -

 これで、サーバ間とのファイルコピーが容易になった……といいたいところですが、ファイル1つをコピーするつどパスワードを入力するのは骨が折れる作業です。安全性を確保しつつ手間を減らすため、次回はSSHの「鍵ペア」を作成し、SSHサーバに登録する手順を紹介します。

◇MOSAからのお知らせと編集後記は割愛します◇

 

 MOSA Developer News   略称[MOSADeN=モサ伝]
        配信停止 mailto:mosaden-ml@mosa.gr.jp
 記事内容に関するご意見 mailto:mosaden-toukou@mosa.gr.jp
      記事投稿受付 http://www.mosa.gr.jp/?page_id=850
Apple、Mac OSは米国アップル社の登録商標です。またそのほかの各製品名等
はそれぞれ各社の商標ならびに登録商標です。
このメールの再配信、および掲載された記事の無断転載を禁じます。
特定非営利活動法人MOSA  http://www.mosa.gr.jp/
Copyright (C)2009 MOSA. All rights reserved.