忍者ブログ

[PR]

2025年02月01日
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

こんな機能があったのか

2009年03月16日
とりあえず断りを入れておきますが、この記事はプログラミングとは直接の関係はありません。

iPhoneやiPod touchではQuickTimeムービーの再生はできません。以前アップルの英語サイトからiPhone SDKがらみのムービーを入手したとき、移動しながらでも見られて便利かと手持ちのiPod touchにムービーを放りこんで見ていた事がありました。その時、アップルの日本語サイトでcocoaのセミナーを収録したビデオを発見した私は、それもiTunesに取り込めば転送できるのかと思っていました。でも、同期を行っても転送はされず、iPodでは再生できない形式だという警告が出るだけでした。

その時は全く気がつかず転送を諦めただけだったのですが、実はビデオのサムネイルの上で右クリックをしたところで(私はもともとWindowsユーザーなので、Windows用のUSBマウスを流用しています)、ポップアップしたメニュー項目の中に「iPod/Phoneバージョンを作成」などという項目があったのです(グリッド表示の時は出ません)。こんな項目あったっけと思いつつ、その項目を試しに選んでみると、しばらくしてビデオの項目が分身したかのように2個になりました。そして同期を行うと、新しく作られた方のビデオファイルが転送されました。もとからあるほうは以前と同じく警告が出て転送できないままでした。そして転送されたビデオはきちんと再生できました。

これと似たような事が音楽ファイルでもあります。それはmidiファイルの場合です。こちらも「AAC バージョンを作成」という項目が選べるので、それを選択するとAACフォーマットのファイルが作られます。これも先ほどの場合と同様に転送し再生する事ができます。もしかしたらソフトの説明にはちゃんとこの機能について書いてあるのかもしれませんが、いちいち説明書を読まなくても基本的な事は出来てしまいます。そのため、私と同じように最近使い始めたばかりの人の中には、これらの機能の存在に気がついていない人が結構多いのではないでしょうか。なおAACに変換した方は普通にmidiファイルをQuickTime Playerで再生した時より音質は良くないようです。そもそもPC用CPUの機能をフルに利用可能な状態で再生させた音質と、携帯機で再生できるように加工したものの音質とを比較するのが間違いなのですけどね。手持ちのmidi曲が大した手間もかけずに持ち歩いて聞けるようになることを考えれば、有用な機能である事は間違いないでしょう。
PR

Kigen ver 1.7.0 アップしました

2009年03月12日
kigen170.PNGKigenとKigen Liteがバージョンアップします。変更点は、

  1. エディットモードでセル本体のタップでも編集画面に移動するようになりました。
  2. リストビューに絞り込み表示機能を追加しました。(左の写真)
  3. 期限一覧メール送信でメール送信時認証への対応をしました。(開発中のTiny3D新バージョンと同様 POP before SMTPとSMTP-AUTHのPLAINおよびLOGIN認証をサポート)
  4. ヘルプ以外をフランス語、ドイツ語、イタリア語、スペイン語表示に対応しました。
  5. その他細かな修正。

こんなところです。2.はリストビュー画面でアイテム名やカテゴリ名の一部を入力するとどちらかに一致する文字列のあるものだけ表示するという機能です。上の写真だとカテゴリ名かアイテム名に「カレー」を含むものが表示されています。カテゴリ名を入れればそのカテゴリ以下のみを抽出して表示させる事もできます。キーボードが邪魔なので3行しか表示しませんが、この状態でもスクロールは可能なので日付順で下にあるものも順次下へとスクロールさせれば表示できます。また、絞り込んだままの状態で削除や日付および個数の編集画面への移行も可能です。

Tiny3D 1.4.0 開発中

2009年03月10日
現在1.3.0が審査中のTiny3Dですが、エレメント詳細設定画面にバグがあったためその修正をしました。そのためりリリースが少々遅れます。リリースまでいましばらくお待ちください。

現在リリース待ちという状況にもかかわらず、既に次のバージョンを開発中です。現在のところ以下の変更を予定しています。

  1. 3D表示の見直しによる描画速度の高速化と最大FPS設定の追加
  2. DXFデータのメール添付による出力への対応

T3dTool140.PNGT3dMail140.PNGこのうちメール出力に関しては、Kigenでも実現していた通常の25番ポートによる認証なしのメール送信以外に、POP before SMTP および サブミッションポート(587番ポート)を利用したSMTP認証(SMTP-AUTH PLAIN および LOGINまで)への対応を行っています。自分の契約プロバイダでしか実験できませんが、動作に問題は無いようです。これでデータ出力の選択肢が増え、Windowsマシンへもメールサーバー経由ですがより簡単にデータを渡せるようになります。バージョン1.3.0ではFTPサーバーソフトを導入しなければWindowsマシンでデータを受け取れないので、それよりは手間もかかりません。(なお左の画像は開発中のものです)

何故Windowsネットワークと直接通信をしないのかと疑問に思う方もいると思いますが、その理由は簡単です。米マイクロソフトとライセンス契約を行わないとWindowsネットワーク用のファイルプロトコルが使えないためです。一個人プログラマが全ての契約文書を読んだ上で契約を行うというのはちょっとハードルが高いため、そこに労力を割くよりは誰もが自由に使える通信プロトコルで迂回するほうが良いだろうと思っています。このためCIFS(Windowsネットワークのファイルシステム関連プロトコル)の実装は保留となっています。なおAFP(アップルファイルプロトコル)はライセンスうんぬんとうるさくは無く自由に使えるようなのですが(アップル自身によるプログラミングガイドも英語ですがPDF形式などで公開されています)、以前に触れたように現在のMac OS Xでは簡単にFTPサーバー化ができるのでまずはそれで十分だろうと思い、こちらも実装は保留になってます。

Tiny3D 1.3.0 アップロードしました

2009年02月28日
先ほどTiny3Dバージョン1.3.0をアップロードしました。主な変更点は以下になります。

  1. 3Dデータ生成処理を見直し、3D表示画面への切替を高速化しました。このため起動時間も従来より短縮されています。
  2. ツールにこれまでの独自形式に加えて、CADの代表的なファイル形式であるDFX形式でのFTP出力機能を追加しました。入力は従来どおり独自形式のみです。
  3. マクロリストの編集モードで削除と移動だけしか行えない状態になっていたのを、通常モードと同様にマクロデータの変更も出来るようにしました。
  4. マクロ機能にあった不具合を修正しました。
  5. 編集モードの表示を見やすいように変更しました。

all_item16.pngCAD業界では標準的なファイル形式であるDFX形式に対応した事で、3Dモデル生成ツールとしても応用可能になりました。思いついた時にその場でだいたいの形を生成し、母艦にFTP転送してから細かい修正を行う、などといった使い方もできます。画像はDXF形式の生みの親、Autodesk社のDWG TrueView 2009(Windows用のフリーソフトとして配布されています)を用いて転送したファイルを開いて検証した時のスクリーンショットです。このスクリーンショットは縮小されているので見えませんが、ちゃんと点エレメントも変換されています。ただ、ほとんどの3Dソフトでは点や線は無視されるようです。とりあえずすぐ試せそうなものということでMetasequoiaLEやHira3DViewerで読み込ませてみました。どちらも3DFACEは認識するので四角や三角のポリゴンは描かれましたが、点や線は認識されませんでした。実際の出力過程は下のビデオを見てください。なお、FTP出力に関してはこちらの記事も参考にしてください。


アラートを出す その2

2009年02月27日
前回の記事では、単純にOKボタンのみを表示するアラートを出しました。今回は2個目のボタンを付けて、どちらのボタンが押されたかで動作を変えられるようにする方法についてです。まず、2個目のボタンは、前回nilだったotherButtonTitlesにボタン用の文字列を追加すれば簡単に追加できます。以下に例を示します。


alertType1;

UIAlertView *alert = [[UIAlertView alloc]

initWithTitle:NSLocalizedString(@"Tiny3D",@"title")

message:NSLocalizedString(@"Reset all settings?",@"message")
delegate:self cancelButtonTitle:NSLocalizedString(@"Cancel",@"")
otherButtonTitles:NSLocalizedString(@"Reset",@""),nil];

[alert show];

[alert release];


これはツールの設定をリセットする項目を選んだ時に実行するコードです。alertTypeというのはヘッダーで宣言したNSInteger型の変数で、これは別に他の名前でも構いません。同じビューコントローラから複数のアラートを表示するときの場合分けをするために作っています。これで表示されるアラートには、日本語環境でキャンセルとリセットという2個のボタンが表示されます。なお、otherButtonTitlesの引数カンマ区切りで列挙し最後にnilがきます。では次にボタンが押された時の動作を追加しましょう。そのためにはまず、このビューコントローラがアラートからのメッセージを受信するようにする必要があります。具体的にはまずヘッダーファイルの@Interface部分を変更します。

@interface SettingTableViewController : UITableViewController <UIAlertViewDelegate> {

 
この<UIAlertViewDelegate>を追加しておく事で、ビューコントローラがアラート表示終了時のメッセージを受信できます。そこで次にメッセージを受信したときに実行される命令をメソッドファイルに追加します。

- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex

{

if(buttonIndex == 1) {
// 押されたのは2番目のボタンです。

if(alertType == 1){

// リセット用のアラートでリセットボタンが押されています。

// ここに具体的なリセット用のコードを書きます。

}

}

}

 
buttonIndexは一番左(3個以上ならボタンは縦配列になるので一番上)のボタンが0で順番に1増えます。上の例ではキャンセルが0でリセットが1です。キャンセルの場合は特に何もする必要がないので分岐を用意していません。リセットする場合はbuttonIndexが1になるのでそれを条件に分岐します。他のアラート(マクロの全削除の確認用などで出しているアラート)と区別するため、さらにalertTypeの値で分岐します。ここにリセットに必要なコードを記述します。別のアラートでもボタンによりアクションが必要なら、別のalertTypeの値を作っておいて分岐させれば良いでしょう。

2010年4月28日追記:
UIAlertViewはUIViewの派生クラスなのでメンバ変数でtagという値を持っています。それを使うことでも分岐を行わせることが出来ます。例えば上のアラートの表示設定でalert.tag = 1;としておき、分岐判定コードではalertTypeのかわりにactionSheet.tag==1などの条件にすれば同じような動作をさせられます。

アラートを出す

2009年02月27日
ユーザーへの通知方式として、一番確実なのはアラートの表示でしょう。これを使うと、画面が暗くなって、中央にメッセージを表示します。OKボタンを押すと元の画面に戻ります。今回はTiny3DのFTPアップロードが終わった時を例にして説明します。まず、アップロードが終わるとコールバック関数から代表クラス(Tiny3DAppDelegeteという名前になっています)にメッセージを送ります。

objc_msgSend(appDelegate,@selector(finishUpload));


この命令でのappDelegateが代表クラスのid値です。特に引数を付けていないのでセレクタのfinishUploadには右に:が付きません。

-(void)finishUpload {

NSLog(@"call appDelegate finishUpload");

if([tabBarController selectedIndex]==3) {

id viewController = [(UINavigationController *)[tabBarController

selectedViewController]topViewController];

objc_msgSend(viewController,@selector(uploadFinished));

}

}


上がTiny3DAppDelegateのfinishUploadです。Tiny3Dの場合はタブバーのボタンが入れ替わる事はないので、必ずツールのインデックス番号は3(一番左が0なので、左から4番目)になります。そのツールのトップ画面のビューコントローラーへ向けて、メッセージを送ります。

-(void)uploadFinished {

NSLog(@"call FTPUpload uploadFinished");

[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Tiny3D",@"title")
message:NSLocalizedString(@"Upload completed.",@"message")

delegate:self cancelButtonTitle:@"OK" otherButtonTitles: nil];

[alert show];

[alert release];

}


そして上にあるのがそのビューコントローラー(FTPUploadViewControllerと勝手に命名してますが)にあるuploadFinishedです。ちなみに2行目の命令で画面の左上に通信中などに表示される回転するアニメーションの表示を消しています。表示の開始の時はNOの部分がYESになります。その後にあるのがアラートの表示内容を決めているところです。英語では"Upload completed."と表示しますが、日本語だと「アップロードに成功しました。」と出るようになっています。実際に表示するのは[alert show]の部分です。alertは自分でallocで作ったオブジェクトなので、表示させたらreleaseで解放します。当たり前ですがリリースしたからといって表示が消える事はありません。OKが押されない限りは表示したままになります。なお、このときに表示されるボタンでいろいろと凝った事もできるのですが、それは次の機会に書きます。





Tiny3D 1.2.0 アップロードしました

2009年02月19日
前から何度か話題にしていたバージョンアップ版をアップロードしました。これまでの経験からするとおそらく1週間程度以内にAppStoreにバージョンアップ版が出ると思います。今回のバージョンアップ内容は以下の通りです。

  1. 3Dエディタのオブジェクト・パート・エレメントの各編集モードで項目をタッチすると、表示・非表示が切り替わるようになりました。
  2. 円柱の塗りスイッチオフ状態での表示を修正しました。
  3. エレメント(基本図形)を2種類追加しました。
  4. ツールにデータの手動保存機能を追加しました。

戻り先のビューへメッセージを送る

2009年02月17日
TableViewでpushViewControllerを呼び出してスクロールさせていく場合には、スクロールする前にいろいろとデータを渡してやるのに苦労することはまずありません。なぜならpushViewControllerで次のビューを表示するために使うViewControllerの参照を書いているからです。それをもとに関数を呼ぶなり変数を変更するなり好きにすれば良いのです。ここまでは当たり前な話です。

では、その逆にpopViewControllerで戻る側にデータを渡したい場合はどうでしょう。代表クラスに全部データを持たせておき、そちらを通じてやりとりする手もあります。渡したいデータは代表クラスに渡しておき、戻り先のViewControllerにあるViewWillAppearで代表クラスへデータを取りにいくようにさせれば、更新内容を反映させる事はできます。でも、プログラムが終了したら破棄するようなデータなどにもいちいち代表クラスを橋渡しに使う必要はあるのかと思う事も多々あります。かといって今表に見えているViewControllerまでの道のりが常に同じとは限らないこともあります。同じような値の設定をする場合には再利用した方が効率が良いだろうと、設定用のViewControllerが数種類の呼び出し元を持つ事もあります。では、そんな場合で直接データを渡したい時はどうするかですが、まずは以下のコードを見てください。

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

[myTableView deselectRowAtIndexPath:indexPath animated:YES];

NSArray *naviArray = [self.navigationController viewControllers];

NSInteger nowIndex = [naviArray count];

id aViewController = [naviArray objectAtIndex:nowIndex-2];

if([aViewController isKindOfClass:[FTPUploadViewController class]]) {

FTPUploadViewController *controller = (FTPUploadViewController *)[naviArray
objectAtIndex:nowIndex-2];

NSString *aString = [[listContent objectAtIndex:indexPath.row]
objectForKey:@"url"];

[controller setDirectoryTextFieldText:aString];

aString = [[listContent objectAtIndex:indexPath.row]
objectForKey:@"username"];

[controller setUsernameTextFieldText:aString];

} else if([aViewController isKindOfClass:[FTPDownloadViewController class]]){

FTPDownloadViewController *controller = (FTPDownloadViewController *)
[naviArray
objectAtIndex:nowIndex-2];

NSString *aString = [[listContent objectAtIndex:indexPath.row]
objectForKey:@"url"];

[controller setDirectoryTextFieldText:aString];

aString = [[listContent objectAtIndex:indexPath.row]
objectForKey:@"username"];

[controller setUsernameTextFieldText:aString];

}

[self.navigationController popViewControllerAnimated:YES];

}


FTP用のアドレスとユーザー名の組み合わせ(Tiny3Dではこいつをブックマークと呼んでます)をテーブルでリスト表示させていて、選択されたら元の設定用のビューにデータを渡そうという部分です。FTPはダウンロードとアップロードの両方で使いますが、同じFTP用なのにわざわざ2種類のブックマークリストを持つ必要もあるまいと、どちらからも同じTableViewControllerをpushViewControllerを使って表示しています。そのため、選択後の戻り先はアップロードの設定用かダウンロードの設定用のどちらかのViewControllerになります。この場合にはnaviArrayという配列を作ってその中にnavigationControllerが持っているこれまでに通過してきたViewControllerのリストを放り込んでいます。配列はインデックス0から始まるので、countで返ってくる配列の個数から2を引いたインデックス値が、今のViewControllerの呼び出し元になります。そして呼び出し元クラスがアップロードかダウンロードかで場合分けを行い、データを変更するための関数へメッセージを送っています。この当時はまだobjc_msgSendの使い方を知らなかったためにこんなコードになっていますが、どちらでもメッセージを受け取る関数は同じなので、型キャストをせずにid値だけを得て、objc_msgSendでメッセージを送るだけで済ませてしまえば分岐する必要が無くなります。ただ、何か問題が起きた場合のデバックをする場合は上のように書いてある方がやりやすいのかもしれません。