Archive for the ‘Mac’ Category

XCodeで「一時的にデータフォーマッタが使用できません」というエラーが起きてしまい、
実行できなくなってしまっていた。

原因は、フレームワークも一緒に直していて、
フレームワークの改修をしてビルドしている途中に、
フレームワークを読み込んでいるアプリを実行しようとすると発生すると思われる。

一度、陥ったら、再起動してもうまく行かない。
とりあえず、フレームワークのリンクを削除して、
再度フレームワークを追加することで、直った。

あせっちゃいけませんってことですかね。。。

XCodeでSQLiteを使用する

Cocoaアプリケーションに久々に触ったので、
忘れないようにメモ。

SQLiteを使用したい場合は、既存のフレームワーク「libsqlite3.0.dylib」を使用することで、
簡単にアクセスすることができる。

書いたコードは以下

  1.  
  2. #import <sqlite3.h>
  3.  
  4. /*間省略*/
  5.  
  6. - (NSArray *)getSQLiteTable {
  7.         sqlite3* db; //DBハンドラー
  8.         sqlite3_stmt *sth; //ステートメントハンドラー
  9.         NSString * databaseFilePath = @"/Users/admin/SQLite/test.db"; //SQLiteのファイルパス
  10.         NSMutableArray * resultArray = [ NSMutableArray array ]; //結果を格納する配列
  11.         NSString * sql = [ NSString stringWithString:@"SELECT * FROM users" ]; //SQL
  12.        
  13.         //SQLファイルをオープン
  14.         //ファイルが存在しない場合は、作成してしまうので、
  15.         //エラーにしたい場合は、ファイルの有無をNSFileManager等で判断する
  16.         if( sqlite3_open([databaseFilePath UTF8String ], &db) == SQLITE_OK )
  17.         {
  18.                 //prepare
  19.                 int result = sqlite3_prepare_v2(
  20.                                                 db,
  21.                                                 [sql UTF8String ],
  22.                                                 -1,
  23.                                                 &sth,
  24.                                                 NULL );
  25.                 //SQLiteでコンパイルできたか
  26.                 if( result != SQLITE_OK){
  27.                         NSLog(@"Faild to Sqlite");
  28.                         NSLog(@"%s",sqlite3_errmsg(db) ); //エラーになった際の詳細のエラー文
  29.                         return;
  30.                 }
  31.                 int count = sqlite3_column_count(sth); //カラムの数を取得
  32.                 int i;
  33.                 NSMutableArray * keyArray = [ NSMutableArray array ]; //カラム名の配列
  34.                 for( i=0; i<count; i++){
  35.                         //カラム名を取得し、配列に格納
  36.                         [ keyArray addObject:[ NSString stringWithUTF8String:(char*)sqlite3_column_name(sth, i)] ];
  37.                 }
  38.                
  39.                 while( sqlite3_step(sth) == SQLITE_ROW ){
  40.                         NSMutableDictionary * dict = [ NSMutableDictionary dictionary ];
  41.                         //各値を取得
  42.                         for( i=0; i<count; i++){
  43.                                 NSString * value = [ NSString stringWithUTF8String:(char*)sqlite3_column_text(sth, i)];
  44.                                 [ dict setValue:value forKey:[ keyArray objectAtIndex:i ] ];
  45.                
  46.                         }
  47.                         //結果配列に格納
  48.                         [ resultArray addObject:dict ];
  49.                 }
  50.                 //ステートメントハンドラを破棄(これしないとメモリが廃棄されない)
  51.                 sqlite3_finalize(sth);
  52.         }
  53.         sqlite3_close(db); //DBを閉じる
  54.  

ポイント
・16行目 ・・・ SQLiteのファイルを開く。MySQLとかの場合はconnectと同じことかと。
         ただし、ファイルが存在しなくても作成されてしまうので、ファイルが存在しない場合にエラーにする場合は、
         NSFileManagerで存在チェックするべき。

いまさら感はすごいあるが、AppleScriptを触る必要があるので、
初めて勉強するから忘れないようにメモ

#dropletで書いています

  1.  
  2. on open dropItems
  3.   repeat with theItem in dropItems
  4.     tell application "Finder"
  5.       open theItem
  6.       – 開いたあとの処理
  7.     end tell
  8.   end repeat
  9. end open
  10.  

久々にMacを触ったら「objc_class_nameクラス名」というエラーに引っかかった。
OS 10.6 XCode 3.2のお話です。

開発環境のマシンが変更になっていたので、
昔のソースを引っ張ってビルドしてみたら、こんなエラーで引っかかった。

とりあえず分からなかったので、調べてみたところ
こちらのサイトを見てみた。
iPhoneメモ “.objc_class_name_クラス名”, referenced from:

なるほど、いらなくなったソースを消すと出やすいのか。
まずは、クリーニングということで、やってみたが、
事態は一向に変わらず。。。

まずはリンクが怪しいということで、
自作のFrameworkをクリーニング、再ビルド。

Frameworkを一度削除し、再度新規に登録。
クリーニングを行い、再度ビルド。

まだダメ。

これは、もうクリーニングではないなということで、
設定を再度見直し。
#そもそもソース削除してないし。。。

ターゲットのLink Binary With Librariesの中を見ると、
なんとCocoaとCarbonがないではないか。
そりゃ動かんよ。

そこにCocoaとCarbonを移し、ビルド。
うまく行ったと思いきやまた同じエラー(クラス名が違う)

再度、設定を見直すと、
ターゲットの「ソースをコンパイル」の部分に
エラーになったクラスのソースが含まれて無いじゃん!

ということで、そこに目的のファイルを入れたら、
無事動きました。

久々だったので、いろいろ対処を忘れちゃいました。

ファイルがエイリアスかどうかを判断する必要がある場合に、
NSFileManager経由で、attributesを取ったところで、
取得できない。
シンボリックリンクかどうかはattributeのNSFileTypeがNSFileTypeSymbolicLinkかどうかで
取得することができる。
#Finderで見ると、同じアイコンなので紛らわしい。。。

そこで、CoreServicesのCarbonCoreにあるAlias.hの
FSIsAliasFileを使って判別することにする。
NSFileManagerのカテゴリとして実装

  1.  
  2. -(BOOL)isAlias:(NSString*)path{
  3.         BOOL returnValue = NO; //返戻値
  4.         FSRef fsref;
  5.         Boolean isAlias, isFolder;
  6.        
  7.         if( [ self stringPathToFSRef:path fsRef:&fsRef ] &&
  8.                 noErr == FSIsAliasFile(&fsref, &isAlias, &isFoder ) ){
  9.                 returnValue = isAlias;
  10.         }
  11.        
  12.         return returnValue;
  13. }
  14.  
  15. -(BOOL)stringPathToFSRef:(NSString*)path fsRef:(FSRef*)outRef{
  16.         BOOL returnValue = NO;
  17.        
  18.         OSStatus err = FSPathMakeRef((const UInt8*)[ path fileSystemRepresentation ] , outRef, NULL );
  19.        
  20.         if( err == noErr ){
  21.                 returnValue = YES;
  22.         }
  23.        
  24.         return returnValue;
  25. }
  26.  

これで、パスのファイルがエイリアスかどうかわかった。

なにかの操作をしていて、急にかな入力になってしまう場合がある。
そして、戻し方を忘れてしまうので、メモ
ただし、BootCampでWindowsを起動しているMacが対象

Alt+かな(スペースの右隣)

「KA」と入力したいのに「のち」になったときはイラっとする。。。

覚えておこう

MacでMySQLを動かすためのインストールメモ
Macの環境(古い…orz)
PowerPC
OS 10.4.11 tiger
1.ダウンロード 最新版は、PowerPC版はないので、
5.1.40をダウンロード ダウンロード先は、
以下のURL http://downloads.mysql.com/archives.php?p=mysql-5.1&v=5.1.40
32ビット版のインストーラフォーマットを使用
MD5のチェックサムは196d5075ecacaede862d85ffd0e90a0b

2.インストール
2-1.ダウンロードしたファイルをダブルクリックで展開
2-2.展開したファイルのmysql-5.1.40-osx10.4-powerpc.pkgをダブルクリック
画面の指示に従って、インストール
2-3.MySQL Start up Itemをインストール
2-4.MySQL.prefPaneを登録(システム環境設定から起動/終了ができます)

3.起動確認
3-1.システム環境設定のMySQLの項目を選択し、MySQLをスタートする
3-2.ターミナルからmysqlにログインできることを確認する
/usr/local/mysql/bin/mysql -u root mysqlで起動すれば、
インストール&起動確認完了

4.MySQLの設定
4-1.ルートのパスワード設定(ルートでログイン後)

  1. SET PASSWORD FOR root@localhost=PASSWORD(‘設定したいパスワード’);
  2. exit
  3.  

4-2.リモートからツールを使用してDBを操作したいので、
新たにユーザを作成

  1.  
  2.  GRANT ALL ON *.* to ユーザ名@% identified by "パスワード" WITH GRANT OPTION;
  3.  

#すべてのホストからログイン可能になっていますが、セキュリティ上微妙です。

5.ツール「Squel Pro」を使用して接続

FireFoxのアドオンのSeleniumIDEを使用して
動作を記録し、そのテストコードをPerlで書き出せる機能がある。

そのPerlのテストコードを動かしてみたときのメモ

まず、そのまま書き出されるPerlのテストスクリプト

  1. use strict;
  2. use warnings;
  3. use Time::HiRes qw(sleep);
  4. use Test::WWW::Selenium;
  5. use Test::More "no_plan";
  6. use Test::Exception;
  7.  
  8. my $sel = Test::WWW::Selenium->new( host => "localhost",
  9.                                     port => 4444,
  10.                                     browser => "*chrome",
  11.                                     browser_url => "http://www.google.co.jp/" );
  12.  
  13. $sel->click_ok("link=28");
  14. $sel->wait_for_page_to_load_ok("30000");
  15. $sel->open_ok("/search?hl=ja&amp;source=hp&amp;q=DZ%E7%A9%BA%E9%96%93&amp;aq=f&amp;aqi=g1&amp;aql=&amp;oq=&amp;gs_rfai=");
  16. WAIT: {
  17.     for (1..60) {
  18.         if (eval { "" eq join(‘,’, $sel->get_all_links()) }) { pass; last WAIT }
  19.         sleep(1);
  20.     }
  21.     fail("timeout");
  22. }
  23. $sel->click_ok("link=NSView » DZ空間");

動かしてみたが、当然モジュールがなくて動かない。

動かすための手順

1,モジュールのインストール

use句に書かれているモジュールのインストールを

CPAN経由で行う。

2.Selenium RCをダウンロード

こちらからSelenium RCをダウンロード

(2010年5月28日現在、バージョン1.0.3)

3.ダウンロードしたSelnium RCを展開

ダウンロードしたフォルダ/selenium-remote-control-1.0.3/selenium-server-1.0.3/selenium-server.jarを起動

#/usr/bin/などに上記jarファイルをmoveしても良い

起動する際は、Terminalで以下のコマンドを実行

java -jar selenium-server.jar

4.Perlのテストスクリプトを編集

今回はほとんど変えずに行った

  1. use strict;
  2. use warnings;
  3. use Time::HiRes qw(sleep);
  4. use Test::WWW::Selenium;
  5. use Test::More "no_plan";
  6. use Test::Exception;
  7.  
  8. my $sel = Test::WWW::Selenium->new( host => "localhost",
  9.                                     port => 4444,
  10.                                     browser => "*firefox",
  11.                                     browser_url => "http://www.google.co.jp/" );
  12.  
  13. $sel->click_ok("link=28");
  14. $sel->wait_for_page_to_load_ok("30000");
  15. $sel->open_ok("/search?hl=ja&amp;source=hp&amp;q=DZ%E7%A9%BA%E9%96%93&amp;aq=f&amp;aqi=g1&amp;aql=&amp;oq=&amp;gs_rfai=");
  16. WAIT: {
  17.     for (1..60) {
  18.         if (eval { "" eq join(‘,’, $sel->get_all_links()) }) { pass; last WAIT }
  19.         sleep(1);
  20.     }
  21.     fail("timeout");
  22. }
  23. $sel->click_ok("link=NSView » DZ空間");

5.テストスクリプトを実行

別ターミナル画面からperlを実行

すると、firefoxが自動的に立ち上がり、処理を行ってくれる。

【おまけ】

会社や学校などでは、プロキシ経由しないといけない場合がある。

firefoxには、profileによって設定を変更することができるので、

profileを指定してfirefoxを自動化する方法は以下の通りである

selenium-serverを起動する際に、以下のコマンドにすることによって

プロファイルを読み込んでFirefoxを立ち上げてくれる(testというプロファイルを使用)

java -jar selenium-server.jar -firefoxProfileTemplate /Users/xxxxx/Library/Application Support/Firefox/Profiles/?????.test/

※1firefoxのプロファイルを作成するには、ターミナルから以下のコマンドを実行することでプロファイルを作成できる

/Applications/Firefox.app/Contens/MacOS/firefox -ProfileManager

※2 作成したプロファイルの保存先は、

~/Library/Application Support/Firefox/Profiles/何か文字列.プロファイル名/

これで、ターミナルからテストを実行することができた。

今回は、Webアプリを自動化してくれるSeleniumを試してみたので、
そのメモ。

自動化のためのスクリプトなどは全然しらなかったので、
手軽に扱えるFireFoxのアドオンのSelenium IDEを使ってみる事にした。

以下のサイトのSelenium IDEをFireFoxでダウンロードすれば、
インストール可能。
#便利♪

インストールしたアドオンを実行して、
操作を記録しておくことによって
自分の行った作業をリスト化してくれる。
#画面の右端にある赤いボタンを押す事で、記録のオンオフができる。

もちろん、記録した作業は、後で編集可能だし、
リンクを判断するキーの項目を変更したり、
手動で動作を追加することができる。

そして、記録したものを実行すれば、
なんと自動化ができてしまうのである。
#目からウロコでした。。。

記述のフォーマットを変えれば
Java,Perl,Rubyなどたくさんのプログラミング言語に書き換えてくれる。
ってことは、テストコードの一部として作成することもできるのですね♪
#Perlで動かすのは今度やってみよう。

画面イメージです。

CocoaでSleepのような動作を実装する場面があったので、
メモメモ。

例えば、ファイル関連で、ファイルのIOより、メソッドの実行速度が早い場合に
よく行う手ですが、実行を少し遅らせたい場合にとっても有効な手段。

  1.  
  2. //次のメソッドの実行を0.5秒遅らせる(AAAがログに表示されるのが0.5秒遅らせる)
  3. [NSThread sleepUntilDate:[[NSDate date] addTimeInterval:0.5]];
  4. NSLog(@"AAA");
  5.  

覚えておきたい書き方です。

追記–2010.08.18
上記のサンプルは、10.4までの書き方。

10.5以上なら以下の書き方

  1.  
  2. //次のメソッドの実行を0.5秒遅らせる(AAAがログに表示されるのが0.5秒遅らせる)
  3. [NSThread sleepForTimeInterval:0.5];
  4. NSLog(@"AAA");
  5.  

シンプルでいいなぁ~

SM様よりコメントいただきました。ありがとうございます。