<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns="http://purl.org/rss/1.0/"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:admin="http://webns.net/mvcb/"
  xmlns:content="http://purl.org/rss/1.0/modules/content/"
  xmlns:sy="http://purl.org/rss/1.0/modules/syndication/">
  <channel rdf:about="http://www.fraction.jp/log/category/Program/Cocoa/">
    <title>Program/Cocoa -- BONNOH FRACTION 14</title>
    <link>http://www.fraction.jp/log/category/Program/Cocoa/</link>
    <description>世の中に寝るより楽はなかりけり&lt;br /&gt;浮世の馬鹿は起きて働く</description>
    
    <dc:creator>Yuanying</dc:creator>
	<dc:date>2018-06-18T09:39:55+09:00</dc:date>
	<admin:generatorAgent rdf:resource="http://webby.rubyforge.org/?v=0.9.4"/>
    <items>
      <rdf:Seq>
        <rdf:li rdf:resource="http://www.fraction.jp/log/archives/2016/10/31/openstack-summit-barcelona" />
        <rdf:li rdf:resource="http://www.fraction.jp/log/archives/2010/06/17/ReferrerHackKit_v0_3_2_is_Released" />
        <rdf:li rdf:resource="http://www.fraction.jp/log/archives/2008/06/24/Debug__NSLog_" />
        <rdf:li rdf:resource="http://www.fraction.jp/log/archives/2008/06/16/Safaris_Referrer" />
        <rdf:li rdf:resource="http://www.fraction.jp/log/archives/2008/02/06/Cocoa_de_Endian" />
        <rdf:li rdf:resource="http://www.fraction.jp/log/archives/2008/01/23/localize_nib_file_with_ibtool" />
        <rdf:li rdf:resource="http://www.fraction.jp/log/archives/2008/01/17/File_IO_by_Cocoa" />
        <rdf:li rdf:resource="http://www.fraction.jp/log/archives/2007/12/20/Build_WebKit_on_Windows_2" />
        <rdf:li rdf:resource="http://www.fraction.jp/log/archives/2007/12/19/Build_WebKit_on_Windows" />
        <rdf:li rdf:resource="http://www.fraction.jp/log/archives/2007/12/12/Building_a_JNI_Universal_Application_with_Xcode_30" />
      </rdf:Seq>
    </items>
  </channel>
  <item rdf:about="http://www.fraction.jp/log/archives/2016/10/31/openstack-summit-barcelona">
    <title>バルセロナ出張</title>
    <link>http://www.fraction.jp/log/archives/2016/10/31/openstack-summit-barcelona</link>
    <description>春に引き続き、スペインはバルセロナに出張してきた。今回の出張では会いたかった開発者が来れてなかったり、前回のようにプレゼンもなく、予定していたデモは機材の関係でできなかったりと、ちょっと微妙だったが、バルセロナは良かった。物価も安く、美味かった。これまでも、パリ、バンクーバー、オースチン、バルセロナと半年おきで出張があったわけだが、これでもしかすると終わりかもしれぬと思うと感慨深い。特に役得的に。...</description>
    <content:encoded><![CDATA[
        <p><a href="/log/archives/2016/05/01/openstack-summit-austin">春に引き続き</a>、
スペインはバルセロナに出張してきた。</p>

<p class='image'>
<img  src='/log/2016/10/IMG_4731.JPG'
      width='640'
      height='480'
      alt=''  />
</p>


<p>今回の出張では会いたかった開発者が来れてなかったり、
前回のようにプレゼンもなく、予定していたデモは機材の関係でできなかったりと、
ちょっと微妙だったが、</p>

<p class='image'>
<img  src='/log/2016/10/IMG_4750.JPG'
      width='640'
      height='480'
      alt=''  />
</p>




<p class='image'>
<img  src='/log/2016/10/IMG_4768.JPG'
      width='640'
      height='480'
      alt=''  />
</p>




<p class='image'>
<img  src='/log/2016/10/IMG_4840.JPG'
      width='640'
      height='480'
      alt=''  />
</p>


<p>バルセロナは良かった。物価も安く、美味かった。
これまでも、パリ、バンクーバー、オースチン、バルセロナと半年おきで出張があったわけだが、
これでもしかすると終わりかもしれぬと思うと感慨深い。特に役得的に。</p>

    ]]></content:encoded>
    <dc:subject>日記</dc:subject>
    <dc:subject>Program/Python</dc:subject>
    <dc:subject>Program/Cocoa</dc:subject>
    <dc:creator>Yuanying</dc:creator>
    <dc:date>2016-10-31T14:55:44+09:00</dc:date>
  </item>
  <item rdf:about="http://www.fraction.jp/log/archives/2010/06/17/ReferrerHackKit_v0_3_2_is_Released">
    <title>ReferrerHackKit v0.3.2 リリース</title>
    <link>http://www.fraction.jp/log/archives/2010/06/17/ReferrerHackKit_v0_3_2_is_Released</link>
    <description>Safari 5.0 に対応した ReferrerHackKit v0.3.2 をリリースしました。ダウンロードプロジェクトページ からどうぞ。変更点Safari 5.0 対応。_initWithRequest:delegate:usesCache:maxContentLength:startImmediately:connectionProperties: の呼び出しをフックするように修正。Info8_pWildcardPattern が二重定義されて警告が出ることがあった問題を修正。...</description>
    <content:encoded><![CDATA[
        <p>Safari 5.0 に対応した ReferrerHackKit v0.3.2 をリリースしました。</p>

<h2>ダウンロード</h2>

<ul>
<li><a href="/projects/wiki/SafariRefManage">プロジェクトページ</a> からどうぞ。</li>
</ul>


<h2>変更点</h2>

<ul>
<li>Safari 5.0 対応。

<ul>
<li>_initWithRequest:delegate:usesCache:maxContentLength:startImmediately:connectionProperties: の呼び出しをフックするように修正。</li>
<li>Info8_pWildcardPattern が二重定義されて警告が出ることがあった問題を修正。</li>
</ul>
</li>
</ul>


    ]]></content:encoded>
    <dc:subject>Apple</dc:subject>
    <dc:subject>Program/Cocoa</dc:subject>
    <dc:creator>Yuanying</dc:creator>
    <dc:date>2010-06-17T03:03:40+09:00</dc:date>
  </item>
  <item rdf:about="http://www.fraction.jp/log/archives/2008/06/24/Debug__NSLog_">
    <title>Debug ビルド時のみ NSLog を出力する</title>
    <link>http://www.fraction.jp/log/archives/2008/06/24/Debug__NSLog_</link>
    <description>CとかC++とかを普通に使ってる人には当たり前のことなんでしょうが、知らなかったので書く。DEBUG_NSLog を定義まず、DEBUGというプリプロセッサマクロが定義されていた場合のみ、ログを出力する、DEBUG_NSLog というプリプロセッサマクロを仕込む。(プリプロセッサマクロ、という単語で良いんだよね？？)#ifdef DEBUG#define DEBUG_NSLog NSLog#else#define DEBUG_NSLog#endifそして、デバッグビルド時のみに出力してほしい場合に...</description>
    <content:encoded><![CDATA[
        <p>CとかC++とかを普通に使ってる人には当たり前のことなんでしょうが、
知らなかったので書く。</p>

<h2>DEBUG_NSLog を定義</h2>

<p>まず、DEBUGというプリプロセッサマクロが定義されていた場合のみ、
ログを出力する、<code>DEBUG_NSLog</code> というプリプロセッサマクロを仕込む。</p>

<p>(プリプロセッサマクロ、という単語で良いんだよね？？)</p>

<pre><code class='prettyprint'>
#ifdef DEBUG
#define DEBUG_NSLog NSLog
#else
#define DEBUG_NSLog
#endif
</code></pre>


<p>そして、デバッグビルド時のみに出力してほしい場合には、DEBUG_NSLogを使う。</p>

<h2>ターゲットの設定</h2>

<p>Debugビルド時のターゲットの設定に、プリプロセッサマクロ「DEBUG」を追加する。</p>

<p><img src="/log/2008/06/debug.png" width="300" height="282" alt="debug.png" /></p>

<p>Releaseビルド時の設定には何もなし。</p>

<p><img src="/log/2008/06/release.png" width="300" height="257" alt="release.png" /></p>

<p>これで Debugビルド時のみ、DEBUG_NSLogはログを出力するようになる。</p>

    ]]></content:encoded>
    <dc:subject>Program/Cocoa</dc:subject>
    <dc:creator>Yuanying</dc:creator>
    <dc:date>2008-06-24T12:45:54+09:00</dc:date>
  </item>
  <item rdf:about="http://www.fraction.jp/log/archives/2008/06/16/Safaris_Referrer">
    <title>Safari のリファラを変更したい</title>
    <link>http://www.fraction.jp/log/archives/2008/06/16/Safaris_Referrer</link>
    <description>FC2 のブログとかを Google Reader や LDR で読むと画像が表示されなくてヒジョーにストレスを感じる。ほんと死んじまえ！って感じでブログを書くならFC2はやめてほしいけど、そんな非現実的なことを呻いていても仕方ないので Safari のリファラをなんとかいじってみようと調べてみる。ってか Firefox 使いなら RefControl :: Firefox Add-onsがあるので Firefox にしとけばいいじゃんって話なんだけど。ここは Safariで。NSURLDownl...</description>
    <content:encoded><![CDATA[
        <p>FC2 のブログとかを Google Reader や LDR で読むと画像が表示されなくてヒジョーにストレスを感じる。</p>

<p>ほんと死んじまえ！って感じでブログを書くならFC2はやめてほしいけど、
そんな非現実的なことを呻いていても仕方ないので Safari のリファラをなんとかいじってみようと調べてみる。</p>

<p>ってか Firefox 使いなら <a href="https://addons.mozilla.org/ja/firefox/addon/953">RefControl :: Firefox Add-ons</a>
があるので Firefox にしとけばいいじゃんって話なんだけど。ここは Safariで。</p>

<h2>NSURLDownload + NSURLRequest</h2>

<p>HMDTの本、</p>

<iframe src="//rcm-jp.amazon.co.jp/e/cm?t=bonnohfract00-22&o=9&p=8&l=as1&asins=4861001242&fc1=000000&IS2=1&lt1=_blank&lc1=0000FF&bc1=000000&bg1=FFFFFF&f=ifr" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe>


<p>とか読む限り、WebKit はリソースのリクエストに NSURLRequest を使うらしい。</p>

<p>それならば話は簡単だ！と思ったのはちょっと軽率だったが、まあとりあえずこんな努力をしてみた。</p>

<pre><code class='prettyprint'>
@implementation NSURLRequest (SRHSwizzle)
-(NSDictionary *) _srh_allHTTPHeaderFields
{
    NSMutableDictionary* headers = [NSMutableDictionary 
        dictionaryWithDictionary:[self _srh_allHTTPHeaderFields]
    ];
    [headers setValue:@"http://www.google.com/" forKey:@"Referer"];
    return headers;
}
@end

@implementation SRHSafariReferrerHack
+ (void) load
{
    BOOL rc;
    rc = MethodSwizzle(
        [NSURLRequest class], 
        @selector(allHTTPHeaderFields), 
        @selector(_srh_allHTTPHeaderFields)
    );
}
@end
</code></pre>


<p>Referrer として必ず "http://www.google.com/" を返す _srh_allHTTPHeaderFields というメソッドを NSURLRequestに用意してやって、
allHTTPHeaderFields と MethodSwizzling。</p>

<p>これを SIMBL プラグインとして Safari に読み込ませてやった。</p>

<p>が、駄目。</p>

<p>自分の鯖にアクセスしてみたらこんなログを残した。</p>

<pre><code>0.238.74.67 - - [16/Jun/2008:12:11:40 +0900] "GET / HTTP/1.1" 200 27161 "http://www.google.com/" "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_3; en-us) AppleWebKit/525.18 (KHTML, like Gecko)"
60.238.74.67 - - [16/Jun/2008:12:11:41 +0900] "GET /images/banner.png?1208240823 HTTP/1.1" 200 2192 "http://yuanying.oeilvert.org/" "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_3; en-us) AppleWebKit/525.18 (KHTML, like Gecko)"
</code></pre>

<p>直のアクセスのリファラは変わったんだけど、そのHTMLから読み込まれる画像とかのリファラは変わってない。</p>

<p>webView:resource:willSendRequest:redirectResponse:fromDataSource: が送られてくる時点のヘッダはちゃんと置き換わってるから、
実際にリソースをダウンロードする時点でリファラをちゃんと直してるっぽい。</p>

<h2>WebKit のソースを読む</h2>

<p>こうなったらもう絶対ハックしてやる！っていう勢いで、
WebKit のソースをダウンロードして読み始める。</p>

<h3>WebFrame.mm</h3>

<p>WebFrame.mm の 1196行目あたりにドキュメント中のリソースを読み込んでるらしきソースを発見する。</p>

<pre><code class='prettyprint'>
- (void)loadRequest:(NSURLRequest *)request
{
    _private->coreFrame->loader()->load(request);
}
</code></pre>


<p>えーっと。。。WebCore に潜れとおっしゃりますか？</p>

<h2>ハックできそう</h2>

<p>WebCore 読んでたら、結局のところリソースのダウンロードは NSURLConnection を使うってところに行き着いた。</p>

<p>とりあえず簡単に試してみようと、NSURLConnection をポージング。</p>

<pre><code class='prettyprint'>
@implementation SRHNSURLConnection
+ (void)load
{
    [self poseAsClass:[NSURLConnection class]];
        NSLog(@"NSURLConnection is overridded.");
}

- (id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate
{
        NSMutableURLRequest* newRequest = [NSMutableURLRequest requestWithURL:[request URL]];
        [newRequest setCachePolicy:[request cachePolicy]];
        [newRequest setTimeoutInterval:[request timeoutInterval]];
        [newRequest setAllHTTPHeaderFields:[request allHTTPHeaderFields]];
        [newRequest setHTTPMethod:[request HTTPMethod]];
        [newRequest setValue:@"http://www.bonnoh.org/" forHTTPHeaderField:@"Referer"];
        
    self = [super initWithRequest:newRequest delegate:delegate];
    return self;
}
- (id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate startImmediately:(BOOL)startImmediately
{
        NSMutableURLRequest* newRequest = [NSMutableURLRequest requestWithURL:[request URL]];
        [newRequest setCachePolicy:[request cachePolicy]];
        [newRequest setTimeoutInterval:[request timeoutInterval]];
        [newRequest setAllHTTPHeaderFields:[request allHTTPHeaderFields]];
        [newRequest setHTTPMethod:[request HTTPMethod]];
        [newRequest setValue:@"http://www.bonnoh.org/" forHTTPHeaderField:@"Referer"];

    self =[super initWithRequest:newRequest delegate:delegate startImmediately:startImmediately];
    return self;
}
@end
</code></pre>


<p>うまくいきましたよ、奥さん！</p>

<h2>報告</h2>

<ul>
<li><a href="/trac/rana2/wiki/SafariRefManage">SafariRefManage – Uzume Project – Trac</a></li>
</ul>


<p>Safari でリファラをいじるSIMBLプラグインをリリースしました。</p>

    ]]></content:encoded>
    <dc:subject>Apple</dc:subject>
    <dc:subject>Program/Cocoa</dc:subject>
    <dc:creator>Yuanying</dc:creator>
    <dc:date>2008-06-16T03:51:55+09:00</dc:date>
  </item>
  <item rdf:about="http://www.fraction.jp/log/archives/2008/02/06/Cocoa_de_Endian">
    <title>Cocoa で Endian 変換</title>
    <link>http://www.fraction.jp/log/archives/2008/02/06/Cocoa_de_Endian</link>
    <description>FLVやMP3をCocoaから読むにあたってバイトオーダーの違いに気をつけなくちゃいけなかったので、それについてメモ。エンディアンを判別するAPIでエンディアンを得るlong NSHostByteOrder (   void);実行時のバイトオーダーを返す。返り値は以下の定数。enum _NSByteOrder {   NS_UnknownByteOrder = CFByteOrderUnknown,   NS_LittleEndian = CFByteOrderLittleEndian,   N...</description>
    <content:encoded><![CDATA[
        <p>FLVやMP3をCocoaから読むにあたってバイトオーダーの違いに気をつけなくちゃいけなかったので、それについてメモ。</p>

<h2>エンディアンを判別する</h2>

<h3>APIでエンディアンを得る</h3>

<pre>
<code class='prettyprint'>long NSHostByteOrder (
   void
);</code>
</pre>


<p>実行時のバイトオーダーを返す。</p>

<p>返り値は以下の定数。</p>

<pre>
<code class='prettyprint'>enum _NSByteOrder {
   NS_UnknownByteOrder = CFByteOrderUnknown,
   NS_LittleEndian = CFByteOrderLittleEndian,
   NS_BigEndian = CFByteOrderBigEndian
};</code>
</pre>


<p>Rosettaで動作していればBigEndianを返すのかな？</p>

<h2>マクロで判別</h2>

<p>コンパイル時にバイトオーダーによって以下のどちらかの定数が定義される。</p>

<ul>
<li><strong>LITTLE_ENDIAN</strong></li>
<li><strong>BIG_ENDIAN</strong></li>
</ul>


<p>それぞれのバイトオーダー特有の処理を書きたい場合は、</p>

<pre>
<code class='prettyprint'>#if __LITTLE_ENDIAN__ 
  // リトルエンディアンの場合の処理
#else
  // その他の場合の処理
#endif</code>
</pre>


<p>こんな感じ。</p>

<h2>データ型の変換</h2>

<p>NSSwap* という関数がshort, int, long, long long, float, double 型についてそれぞれ用意されている。</p>

<p>例えばint型については、</p>

<pre>
<code class='prettyprint'>unsigned int NSSwapInt (
   unsigned int inv
);

unsigned int NSSwapLittleIntToHost (
   unsigned int x
);

unsigned int NSSwapHostIntToLittle (
   unsigned int x
);

unsigned int NSSwapBigIntToHost (
   unsigned int x
);

unsigned int NSSwapHostIntToBig (
   unsigned int x
);</code>
</pre>


<p>という感じで関数がそろっている。</p>

    ]]></content:encoded>
    <dc:subject>Program/Cocoa</dc:subject>
    <dc:creator>Yuanying</dc:creator>
    <dc:date>2008-02-06T01:11:42+09:00</dc:date>
  </item>
  <item rdf:about="http://www.fraction.jp/log/archives/2008/01/23/localize_nib_file_with_ibtool">
    <title>ibtoolによるnibファイルのローカライズ</title>
    <link>http://www.fraction.jp/log/archives/2008/01/23/localize_nib_file_with_ibtool</link>
    <description>とりあえずCocoa初心者が、nibファイルのローカライズ方法をまとめてみた。通常の方法Cocoaアプリをローカライズする一番簡単な方法は、Xcode上からnibファイルのローカリゼーションを追加する方法だ。まず、ローカライズしたいnibファイルを選択し、「ローカリゼーションを追加」を選択する。そして最後に、できあがったnibファイルを、その言語用に編集する。ただ、この方法にはとても気持ち悪い問題がある。例えば、元のnibファイルを編集してユーザインタフェースを変更した場合、同じ修正を別言語のni...</description>
    <content:encoded><![CDATA[
        <p>とりあえずCocoa初心者が、nibファイルのローカライズ方法をまとめてみた。</p>
<h2>通常の方法</h2>
<p>Cocoaアプリをローカライズする一番簡単な方法は、Xcode上からnibファイルのローカリゼーションを追加する方法だ。</p>
<p>まず、ローカライズしたいnibファイルを選択し、</p>
<p><img src="/log/2008/01/nib001.png" width="312" height="199" alt="nib001.png" /></p>
<p>「ローカリゼーションを追加」を選択する。</p>
<p><img src="/log/2008/01/nib002.png" width="320" height="190" alt="nib002.png" /></p>
<p>そして最後に、できあがったnibファイルを、その言語用に編集する。</p>
<p><img src="/log/2008/01/nib003.png" width="330" height="97" alt="nib003.png" /></p>
<p>ただ、この方法にはとても気持ち悪い問題がある。</p>
<p>例えば、元のnibファイルを編集してユーザインタフェースを変更した場合、同じ修正を別言語のnibファイルに行うか、一旦、別言語のnibファイルを削除して、もう一度ローカライズを行わなければならない。</p>
<p>これはひどい。</p>
<p>Subversionとの相性も最悪で、どうしようかと悩んでいるところにibtoolを知った。</p>
<h2>ibtool</h2>
<p>ibtoolを使うと以下の流れでローカライズを行うことができる。</p>
<ol><li> nibファイルから文字列の取り出し</li><li> 取り出した文字列をローカライズ</li><li> ローカライズした文字列からnibファイルを生成</li></ol>

<h3>nibファイルから文字列の取り出し</h3>
<p>以下のコマンドをプロジェクトのルートディレクトリで行うことでnibファイルから文字列を取り出すことができる。</p>
<pre>[yuanying@Magnus test]$ ibtool --generate-stringsfile English.lproj/MainMenu.nib.strings English.lproj/MainMenu.nib</pre>
<p>出来上がったMainMenu.nib.stringsファイルはXcodeのResourceグループにドラッグアンドドロップして、プロジェクトに追加しておく。</p>
<p>生成されたMainMenu.nib.stringsのエンコードは <code>Unicode (UTF-16LE)</code> なので、Xcodeで開いて文字化けする場合は、文字コードを設定する。</p>
<h3>取り出した文字列をローカライズ</h3>
<p>生成されたMainMenu.nib.stringsを通常の方法と同様に、ローカリゼーションを追加する。</p>
<p><img src="/log/2008/01/nib004.png" width="211" height="100" alt="日本語のリソースを追加。" /></p>
<p>追加された言語環境(この場合は日本語)に翻訳する。</p>
<p><img src="/log/2008/01/nib005.png" width="320" height="38" alt="nib005.png" /></p>
<h3>ローカライズした文字列からnibファイルを生成</h3>
<p>翻訳した文字列から、その言語用のnibファイルを生成する。</p>
<pre>[yuanying@Magnus test]$ ibtool --write Japanese.lproj/MainMenu.nib -d Japanese.lproj/MainMenu.nib.strings English.lproj/MainMenu.nib</pre>
<p>この例だと、English.lproj/MainMenu.nibを利用して、Japanese.lproj/MainMenu.nib.stringsからJapanese.lproj/MainMenu.nibを生成してる。</p>
<h2>自動化</h2>
<p>インタフェース(English.lproj/MainMenu.nib)を変更するたびにibtoolを使って日本語用のnibファイルを生成し直すのは面倒なので、最後のステップを自動化する。</p>
<p>まず、プロジェクトのターゲットを選択し、新規スクリプトを実行を追加する。</p>
<p><img src="/log/2008/01/nib006.png" width="330" height="94" alt="nib006.png" /></p>
<p>追加したビルドフェーズを、ビルドの一番最初に持ってくる。</p>
<p><img src="/log/2008/01/nib007.png" width="287" height="120" alt="nib007.png" /></p>
<p>スクリプトの編集を行い、以下のスクリプトを追加する。</p>
<pre>ibtool --write Japanese.lproj/MainMenu.nib -d Japanese.lproj/MainMenu.nib.strings English.lproj/MainMenu.nib</pre>
<p><img src="/log/2008/01/nib008.png" width="340" height="119" alt="nib008.png" /></p>
<p>以上でビルドを行うたびにEnglish.lproj/MainMenu.nibからJapanese.lproj/MainMenu.nibが生成されるようになった。</p>
<h2>もっと簡単に</h2>
<p><a href='http://pisces-319.seesaa.net/article/71705307.html'>iLingual</a>っていうソフトが使いやすそう。シェアウェアなのでまだ使ったこと無いけど。</p>
<p>よくある翻訳を、Appleの純正ソフトウェアから学習できるってのがいいかも。これがあるだけで一般的なメニューの翻訳はだいぶ楽になるなー。3000円か…。同じようなツールを自分で作る？</p>
    ]]></content:encoded>
    <dc:subject>Program/Cocoa</dc:subject>
    <dc:creator>Yuanying</dc:creator>
    <dc:date>2008-01-23T02:14:27+09:00</dc:date>
  </item>
  <item rdf:about="http://www.fraction.jp/log/archives/2008/01/17/File_IO_by_Cocoa">
    <title>Cocoaでファイル入出力</title>
    <link>http://www.fraction.jp/log/archives/2008/01/17/File_IO_by_Cocoa</link>
    <description>Cocoaでファイルの読み書きがしたいなーと思ったのですが、MacOSX Cocoa プログラミングにも、Happy Macintosh Developing Timeにも、たのしいCocoaプログラミングにも、ファイルの読み書きの話が書いてないのでもしやCのライブラリを使うのかなーと思いながら嫌々Cの入門本をめくってたのですが、全然関係ないところでCocoaの該当クラスを見つけました。使用するクラスNSFileManagerNSFileHandleNSDataソース// #1 パスをフルパスにN...</description>
    <content:encoded><![CDATA[
        <p>Cocoaでファイルの読み書きがしたいなーと思ったのですが、</p>
<ol><li><a href="//www.amazon.co.jp/gp/redirect.html?ie=UTF8&location=http%3A%2F%2Fwww.amazon.co.jp%2Fdp%2F489471440X%3Fie%3DUTF8%26s%3Dbooks%26qid%3D1200548394%26sr%3D1-1&tag=bonnohfract00-22&linkCode=ur2&camp=247&creative=1211">MacOSX Cocoa プログラミング</a><img src="//www.assoc-amazon.jp/e/ir?t=bonnohfract00-22&amp;l=ur2&amp;o=9" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />にも、</li><li><a href="//www.amazon.co.jp/gp/redirect.html?ie=UTF8&location=http%3A%2F%2Fwww.amazon.co.jp%2Fdp%2F4861001242%3Fie%3DUTF8%26s%3Dbooks%26qid%3D1200548529%26sr%3D1-1&tag=bonnohfract00-22&linkCode=ur2&camp=247&creative=1211">Happy Macintosh Developing Time</a><img src="//www.assoc-amazon.jp/e/ir?t=bonnohfract00-22&amp;l=ur2&amp;o=9" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />にも、</li><li><a href="//www.amazon.co.jp/gp/redirect.html?ie=UTF8&location=http%3A%2F%2Fwww.amazon.co.jp%2Fdp%2F4861004438%3Fie%3DUTF8%26s%3Dbooks%26qid%3D1200548593%26sr%3D1-1&tag=bonnohfract00-22&linkCode=ur2&camp=247&creative=1211">たのしいCocoaプログラミング</a><img src="//www.assoc-amazon.jp/e/ir?t=bonnohfract00-22&amp;l=ur2&amp;o=9" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />にも、</li></ol>
<p>ファイルの読み書きの話が書いてないのでもしやCのライブラリを使うのかなーと思いながら嫌々Cの入門本をめくってたのですが、全然関係ないところでCocoaの該当クラスを見つけました。</p>
<h2>使用するクラス</h2>
<ul><li><a href='http://www.oomori.com/cocoafw/Foundation/NSFileManager/index.html'>NSFileManager</a></li><li><a href='http://www.oomori.com/cocoafw/Foundation/NSFileHandle/index.html'>NSFileHandle</a></li><li><a href='http://www.oomori.com/cocoafw/Foundation/NSData/index.html'>NSData</a></li></ul>
<h2>ソース</h2>
<pre><code class='prettyprint'>// #1 パスをフルパスに
NSString* outputFilePath = [outputFilePath stringByExpandingTildeInPath];
// #2 出力するファイルを生成
[[NSFileManager defaultManager] createFileAtPath:outputFilePath contents:nil attributes:nil];
NSFileHandle* input = [NSFileHandle fileHandleForReadingAtPath:inputFilePath];
NSFileHandle* output = [NSFileHandle fileHandleForWritingAtPath:ouputFilePath];

// #3 ループ
@try {
	NSData* data
	while (data = [input readDataOfLength:1]) {
		[output writeData:data];
	}
} @finally {
	[input closeFile];
	[output closeFile];
}</code></pre>
<p>一応解説すると、</p>
<h3>1 パスをフルパスに</h3>
<p><code><a href='http://www.oomori.com/cocoafw/Foundation/NSString/stringByExpagTildeInPath.html'>stringByExpandingTildeInPath</a></code>を使ってチルダ付きのパスをフルパスにしてます。</p>
<h3>2 出力するファイルを生成</h3>
<p><code>NSFileHandle</code>で書き込むファイルは存在してないと駄目っぽい。最初これではまった、<code>fileHandleForWritingAtPath</code>でnilしか返ってこないんだもんね…。ということで、<code>createFileAtPath</code>を使ってファイル生成。</p>
<p>実を言うとこのメソッドでついでに書き込むデータも一緒に指定できるんだけど、今日はまあ練習ということで…。</p>
<h3>3 ループ</h3>
<p>inputから1バイト読み込んでoutputに書き込んでます。なんて無駄な処理。今日はまあ練習ということで…。</p>
<h2>感想</h2>
<p>ファイルIOの学習にこんな時間かかるなんて、なんて新鮮！</p>
<p>たまには違う言語もやってみるものですな。</p>

    ]]></content:encoded>
    <dc:subject>Program/Cocoa</dc:subject>
    <dc:creator>Yuanying</dc:creator>
    <dc:date>2008-01-17T05:59:40+09:00</dc:date>
  </item>
  <item rdf:about="http://www.fraction.jp/log/archives/2007/12/20/Build_WebKit_on_Windows_2">
    <title>WindowsでWebKitをビルド 2</title>
    <link>http://www.fraction.jp/log/archives/2007/12/20/Build_WebKit_on_Windows_2</link>
    <description>WindowsでWebKitをビルドの続き。ソースコードの入手最新版のソースコードをsubversionからチェックアウト。これまたなんのひねりもなく、Getting the Codeに書いてあるそのまんま。SubversionでチェックアウトおもむろにCygwinのシェルを立ち上げ、ソースコードをチェックアウトしたいディレクトリに移動してチェックアウト。私は特に何も考えずそのままホームにチェックアウトしてしまったけど結構な量なので気になる人は別にパーティションつくってそこにチェックアウトとかして...</description>
    <content:encoded><![CDATA[
        <p><a href='/log/archives/2007/12/19/Build_WebKit_on_Windows'>WindowsでWebKitをビルド</a>の続き。</p>
<h2>ソースコードの入手</h2>
<p>最新版のソースコードをsubversionからチェックアウト。これまたなんのひねりもなく、<a href="http://webkit.org/building/checkout.html">Getting the Code</a>に書いてあるそのまんま。</p>
<h3>Subversionでチェックアウト</h3>
<p>おもむろにCygwinのシェルを立ち上げ、ソースコードをチェックアウトしたいディレクトリに移動してチェックアウト。</p>
<p>私は特に何も考えずそのままホームにチェックアウトしてしまったけど結構な量なので気になる人は別にパーティションつくってそこにチェックアウトとかしてる模様。</p>
<pre>$ svn checkout http://svn.webkit.org/repository/webkit/trunk WebKit</pre>
<h3>Webkit Support Libraries のインストール</h3>
<p><a href="http://developer.apple.com/opensource/internet/webkit_sptlib_agree.html">WebKit Support Libraries</a>をダウンロードして「WebKitSupportLibrary.zip」という名前のまま解凍せずにソースコードをチェックアウトしてきたディレクトリのルートにコピーする。</p>
<pre>$ /cygdrive/c/Documents\ and\ Settings/Administrator/My\ Documents/Downloads/WebKitSupportLibrary.zip ./WebKit/</pre>
<h3>追加ライブラリのインストール</h3>
<p>さらに追加のライブラリをインストールするために以下のコマンドを実行する。</p>
<pre>$ WebKit/WebKitTools/Scripts/update-webkit</pre>
<p>本来はソースコードを最新にアップデートするコマンドらしいが、Windowsの場合は初回時に必ず実行しておかないと依存するライブラリが解決しないらしい。</p>
<h2>ビルド</h2>
<p>これで準備は終わり。あとはビルドを実行するだけ！</p>
<pre>$ WebKit/WebKitTools/Scripts/build-webkit</pre>
<p>この手順でやれば特に何の問題もエラーもなくビルドが終了する。何も失敗がないとドキュメント通りになってまったく面白みがないですね！</p>
<h2>WebKit を実行してみる</h2>
<p>Windowsに<a href='http://www.apple.com/jp/safari/'>Safari</a>がインストールされている場合は以下のコマンドで自分でビルドしたWebKitを使ってSafariが起動する。</p>
<pre>$ WebKit/WebKitTools/Scripts/run-safari</pre>
<p>さて、一通りビルドが終わって確認したのでソースコードを色々見てみますか…。</p>

<h2>参考</h2>
<ul><li><a href="http://d.hatena.ne.jp/gyuque/20070927">WebKitビルドガイド（ドザー用） - 最速チュパカブラ研究会</a></li><li><a href="http://www35.atwiki.jp/safari3cowiki-room1/pages/24.html">safari3beta co-wiki room1 - ビルド環境</a></li></ul>
    ]]></content:encoded>
    <dc:subject>PC/Windows</dc:subject>
    <dc:subject>Program/Cocoa</dc:subject>
    <dc:creator>Yuanying</dc:creator>
    <dc:date>2007-12-20T01:20:17+09:00</dc:date>
  </item>
  <item rdf:about="http://www.fraction.jp/log/archives/2007/12/19/Build_WebKit_on_Windows">
    <title>WindowsでWebKitをビルド</title>
    <link>http://www.fraction.jp/log/archives/2007/12/19/Build_WebKit_on_Windows</link>
    <description>遅ればせながらWindowsでWebKitをビルドしてみた。環境WindowsXP SP2Visual C++ 2005 Express EditionMicrosoft Platform SDK for Windows Server 2003 SP1上記の環境を VMware Fusion 上に構築してビルド。えらい時間かかって死ぬかと思った。最近はハマりポイントがつぶされているのかどうかわかりませんが一発でビルド成功、WebKit起動した。先人様々ですな。開発環境構築特に変なことをせずInst...</description>
    <content:encoded><![CDATA[
        <p>遅ればせながらWindowsでWebKitをビルドしてみた。</p>
<h2>環境</h2>
<ul><li>WindowsXP SP2</li><li>Visual C++ 2005 Express Edition</li><li>Microsoft Platform SDK for Windows Server 2003 SP1</li></ul>
<p>上記の環境を VMware Fusion 上に構築してビルド。えらい時間かかって死ぬかと思った。</p>
<p>最近はハマりポイントがつぶされているのかどうかわかりませんが一発でビルド成功、WebKit起動した。先人様々ですな。</p>
<h2>開発環境構築</h2>
<p>特に変なことをせず<a href="http://webkit.org/building/tools.html">Installing the Developer Tools</a>通りに。安上がりにやるためにVisual C++ 2005 Express Editionを使いますよ。</p>
<h3>Visual C++のインストール</h3>
<ol><li><a href="http://go.microsoft.com/fwlink/?LinkId=51410">Visual C++ 2005 Express</a>のインストール。</li><li><a href="http://download.microsoft.com/download/7/7/3/7737290f-98e8-45bf-9075-85cc6ae34bf1/VS80sp1-KB926748-X86-INTL.exe">Microsoft Visual C++ Express 2005 Service Pack 1</a>のインストール。</li><li><a href="http://msdn.microsoft.com/vstudio/express/visualc/usingpsdk/">Windows Platform SDK</a>のインストール。</li><li>includeパスに<code>C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\Include\mfc</code>を追加。</li></ol>
<p>最後のステップはVisual C++を起動した後にメニューの<code>ツール - オプション - プロジェクトおよびソリューション - VC++ ディレクトリ</code>から以下のように設定。</p>
<p><img src="/log/2007/12/webkit1.gif" width="400" height="195" alt="webkit1.gif" /></p>
<h3>Cygwinのインストール</h3>
<p>SubversionやPerlやらビルドに必要なツールをCygwinを利用してインストールする模様。WebKitのビルドに必要なパッケージを揃えた自動インストーラが webkit.org で配布されているのでそれを使ってインストールすると簡単。</p>
<ol><li><a href="http://svn.webkit.org/repository/webkit/trunk/WebKitTools/CygwinDownloader/cygwin-downloader.zip">cygwin-downloader.zip</a>をダウンロード。</li><li>解凍したフォルダの中に入ってるcygwin-downloader.exeを実行。</li><li>必要なパッケージのダウンロードが終わるとCygwinのsetup.exeが自動で起動するので、「Install from Local Directory」を選択してインストール。</li></ol>
<p><img src="/log/2007/12/webkit2.gif" width="380" height="258" alt="webkit2.gif" /> </p>
<p>すでにCygwinがインストールされている場合は、<a href='http://www35.atwiki.jp/safari3cowiki-room1/pages/24.html'>いくつかのパッケージ</a>をインストールしておく必要がある模様。</p>
<p><a href="/log/archives/2007/12/20/Build_WebKit_on_Windows_2">WindowsでWebKitをビルド 2</a>に続く。</p>

<h2>参考</h2>
<ul><li><a href="http://d.hatena.ne.jp/gyuque/20070927">WebKitビルドガイド（ドザー用） - 最速チュパカブラ研究会</a></li><li><a href="http://www35.atwiki.jp/safari3cowiki-room1/pages/24.html">safari3beta co-wiki room1 - ビルド環境</a></li></ul>
    ]]></content:encoded>
    <dc:subject>PC/Windows</dc:subject>
    <dc:subject>Program/Cocoa</dc:subject>
    <dc:creator>Yuanying</dc:creator>
    <dc:date>2007-12-19T09:20:11+09:00</dc:date>
  </item>
  <item rdf:about="http://www.fraction.jp/log/archives/2007/12/12/Building_a_JNI_Universal_Application_with_Xcode_30">
    <title>Building a JNI Universal Application with Xcode 3.0</title>
    <link>http://www.fraction.jp/log/archives/2007/12/12/Building_a_JNI_Universal_Application_with_Xcode_30</link>
    <description>アップルにある「Building a JNI Universal Application with Xcode」というドキュメントがちょっと古くてXcode 3.0(Leopard)だとうまくチュートリアルの通りに進まなかったのでメモ。Creating the Initial Applicationまず、最初からつまづく。なんといってもNew Projectに「Java Swing Application」が見当たらない。出来上がりのアプリケーションから察するにXcode 3.0では単純に「Jav...</description>
    <content:encoded><![CDATA[
        <p>アップルにある「<a href='http://developer.apple.com/java/jniuniversal.html'>Building a JNI Universal Application with Xcode</a>」というドキュメントがちょっと古くてXcode 3.0(Leopard)だとうまくチュートリアルの通りに進まなかったのでメモ。</p>
<h2>Creating the Initial Application</h2>
<p>まず、最初からつまづく。なんといってもNew Projectに「Java Swing Application」が見当たらない。出来上がりのアプリケーションから察するにXcode 3.0では単純に「Java Application」と名前を変えているらしい。</p>
<p><img src="/log/2007/12/jni01.png" width="320" height="268" alt="jni01.png" /></p>
<h2>プロジェクトの構成</h2>
<p>そして一番の問題がプロジェクトがほとんどAnt-basedになっちゃってること。</p>
<p><img src="/log/2007/12/jni02.png" width="400" height="191" alt="jni02.png" /></p>
<p>そのせいで新規にビルドフェーズをXcode上から追加できない。全部自分でbuild.xmlをいじらなくちゃいけない模様。</p>
<p>まあJava開発者ならAntの方が使いやすいだろうという配慮なんだけど私には余計なお世話でした…。</p>
<p>まあとりあえず<a href='http://developer.apple.com/java/jniuniversal.html'>Building a JNI Universal Application with Xcode</a>通りにnativeメソッドをJavaのソースコードに追加して、ライブラリをロードするところまで進める。</p>
<h3>Adding the Native Method Declaration and Call</h3>
<pre>public native String getMyFullName();</pre>
<h3>Loading the Dynamic Library</h3>
<pre>static { System.loadLibrary( "MyFirstJNILib" ); }</pre>

<h2>Creating the Header File</h2>
<p>さて、ここら辺からドキュメントが役立たずになってきますよ。</p>
<p>今回はヘッダファイルを作るのに(ドキュメントにあるJavaHeadersターゲットは作成せずに、)antタスクのjavahを使います。javahでヘッダファイルを作るためにいくつかの変数をbuild.xmlに追加します。</p>
<h3>build.xml</h3>
<p>initターゲットとjarターゲットを修正。</p>
<pre><code class='prettyprint'>	&lt;!-- Initialization target, for any prelimary setup needed to build --&gt;
	&lt;target name="init" description="Preparation"&gt;
		<strong>&lt;!-- Get properties from environment --&gt;
		&lt;property environment="env"/&gt;	
		&lt;property name="curr_build_dir" location="build/${env.CONFIGURATION}"/&gt;
		&lt;property name="curr_header_dir" location="build/${env.CONFIGURATION}/Headers"/&gt;</strong>

		&lt;mkdir dir="${curr_build_dir}"/&gt;
		&lt;mkdir dir="${curr_header_dir}"/&gt;	

		&lt;mkdir dir="${src}"/&gt;
		&lt;mkdir dir="${lib}"/&gt;
	&lt;/target&gt;

	&lt;target name="jar" depends="compile" description="Build jar"&gt;
		&lt;mkdir dir="${jars}"/&gt;
		&lt;jar jarfile="${jars}/${ant.project.name}.jar" basedir="${bin}" manifest="${resources}/Manifest"&gt;
			&lt;!-- Inject resources --&gt;
			&lt;fileset dir="${resources}/"
				excludes="${resources}/Manifest"
			/&gt;
			&lt;!-- Merge library jars into final jar file --&gt;
			&lt;zipgroupfileset refid="lib.jars"/&gt;
		&lt;/jar&gt;

		<strong>&lt;!-- generate the header files --&gt;
		&lt;javah classpath=""${jars}/${ant.project.name}.jar" outputfile="${curr_header_dir}/MyFirstJNILib.h"&gt;
			&lt;class name="MyLeopardJNIProject"/&gt;
		&lt;/javah&gt;</strong>
	&lt;/target&gt;</code></pre>
<p>propertyとjavacタスクを追加したよ。</p>
<p>とりあえずここまででビルドしてみると、うまくいってれば<code>build/${env.CONFIGURATION}/Headers</code>フォルダに<code>MyFirstJNIProject.h</code>ができているはず。</p>
<h2>Adding the JNI Library Target</h2>
<p>ここのセクションはいくつかの相違点以外は基本的にそのまま。</p>
<h3>相違点</h3>
<ul><li>ヘッダ検索パスの追加</li><li>ヘッダファイルのincludeの指定の仕方</li><li>MyFirstJNILibターゲットのDependenciesにJavaHeadersを<strong>追加しない</strong></li><li>build.xmlにターゲットを追加する</li></ul>
<h3>ヘッダ検索パスの追加</h3>
<p>ドキュメントではヘッダ検索パスとして<code>$(SDKROOT)/System/Library/Frameworks/JavaVM.framework/Headers</code>を追加していたが、さらに"${TARGET_BUILD_DIR}/Headers"も追加する。</p>
<p><img src="/log/2007/12/jni03.png" width="400" height="226" alt="jni03.png" /></p>
<h3>ヘッダファイルのincludeの指定の仕方</h3>
<p>MyFirstJNILib.cはMyFirstJNILib.hをincludeするが、MyFirstJNILib.hはヘッダ検索パスを前項で追加したため、<code>#include "MyFirstJNILib.h"</code>ではなく、以下のように指定する。</p>
<pre>#include &lt;MyFirstJNILib.h&gt;</pre>
<h3>build.xmlにターゲットを追加する</h3>
<p>追加したMyFirstJNILibターゲットをAntからコンパイルするようにbuild.xmlを編集する。</p>
<p>まず、build.xmlの最初の方にネイティブコードをコンパイルするための変数を追加。</p>
<h4>property追加</h4>
<pre><code class="prettyprint">...
	&lt;property name="application.resources" location="${dist}/${ant.project.name}.app/Contents/Resources"/&gt;
	&lt;property name="application.resources.java" location="${dist}/${ant.project.name}.app/Contents/Resources/Java"/&gt;

    <strong>&lt;property name="native.target" value="MyFirstJNILib"/&gt;
    &lt;property name="native.project" value="MyLeopardJNIProject.xcodeproj"/&gt;
    &lt;property name="native.library" value="libMyFirstJNILib.jnilib"/&gt;
    &lt;property name="env.CONFIGURATION" value="Release"/&gt;</strong>

	&lt;!-- lib directory should contain any pre-built jar files needed to build the project
		 AppleJavaExtensions.jar is included to allow the built jars to run cross-platform if you depend on Apple eAWT or eIO classes.
		 See http://developer.apple.com/samplecode/AppleJavaExtensions/index.html for more information --&gt;
...</code></pre>
<h4>ネイティブコードのコンパイル</h4>
<p>ネイティブコードをXcodeを利用してコンパイルするターゲットを追加。</p>
<pre><code class="prettyprint">	&lt;!-- Note: this target requires that Xcode Tools be installed --&gt;
	&lt;target name="nativelib" depends="jar"&gt;
		&lt;exec executable="/usr/bin/xcodebuild"&gt;
			&lt;arg line="-project ${native.project}"/&gt;
			&lt;arg line="-target ${native.target}"/&gt;
			&lt;arg line="-configuration ${env.CONFIGURATION}"/&gt;
		&lt;/exec&gt;		
        &lt;copy file="${curr_build_dir}/${native.library}" toDir="${jars}" failonerror="true" verbose="true"/&gt;
	&lt;/target&gt; </code></pre>
<h4>パッケージング</h4>
<p>packageターゲットの依存関係にnativelibターゲットを追加し、*.jnilibをリソースとして追加するタスクを追加する。</p>
<pre><code class="prettyprint">	&lt;target name="package" depends="nativelib" description="Make a double-clickable Mac OS X application"&gt;
		&lt;mkdir dir="${dist}"/&gt;
		&lt;mkdir dir="${application.resources.java}"/&gt;
		&lt;mkdir dir="${application.macos}"/&gt;
		&lt;!-- copy jars --&gt;
		&lt;copy toDir="${application.resources.java}"&gt;
			&lt;fileset dir="${jars}"&gt;
				&lt;include name="*.jar"/&gt;
				&lt;include name="*.jnilib" /&gt;
			&lt;/fileset&gt;
		&lt;/copy&gt;</code></pre>
<h2>実行</h2>
<p>以上で設定終わり。「ビルドして進行」ボタンを押せばJNIを利用したSwingアプリケーションができあがってるはず。</p>
<h2>感想</h2>
<p>LeopardになってからJavaが蔑ろにされてる気が…。</p>
<p>ところでJavaでJNI使ってる人ってまだいるのかしらん？</p>
<h2>ダウンロード</h2>
<p>念のため今回作ってみたプロジェクト。</p>
<ul><li><a href="/log/2007/12/MyLeopardJNIProject.zip">MyLeopardJNIProject.zip</a></li></ul>
    ]]></content:encoded>
    <dc:subject>Apple</dc:subject>
    <dc:subject>Program/Java</dc:subject>
    <dc:subject>Program/Cocoa</dc:subject>
    <dc:creator>Yuanying</dc:creator>
    <dc:date>2007-12-12T04:38:01+09:00</dc:date>
  </item>
</rdf:RDF>
