Cocoa練習帳 -24ページ目

[OSX][iOS]データ解析

データ・ファイルを解析する際の、よくあるパターンとして行単位で読み込んで、それを解析するというのがある。これをPerlで処理する場合、こんな感じになる。




#!/usr/bin/perl
my $line;
while ($line = <>) {


}



これをCocoaで行うとどうなるか?まずは、標準入力の内容を標準出力に印字する。




#import <Foundation/Foundation.h>
 
int main(int argc, const char * argv[])
{
    @autoreleasepool {        
        NSFileHandle    *fhi = [NSFileHandle fileHandleWithStandardInput];
        NSFileHandle    *fho = [NSFileHandle fileHandleWithStandardOutput];
 
        NSData  *datainput = [fhi readDataToEndOfFile];
        NSString    *str = [[NSString alloc] initWithData:datainput encoding:NSUTF8StringEncoding];
        
        NSData  *dataout = [[NSData alloc] initWithBytes:[str UTF8String] length:[str lengthOfBytesUsingEncoding:NSUTF8StringEncoding]];
        [fho writeData:dataout];
    }
    return 0;
}



次に行単位で取り込む。




#import <Foundation/Foundation.h>


int main(int argc, const char * argv[])
{
    @autoreleasepool {        
        NSFileHandle    *fhi = [NSFileHandle fileHandleWithStandardInput];
        NSFileHandle    *fho = [NSFileHandle fileHandleWithStandardOutput];
 
        NSData  *datainput = [fhi readDataToEndOfFile];
        NSString    *str = [[NSString alloc] initWithData:datainput encoding:NSUTF8StringEncoding];
        
        NSError *error = NULL;
        NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(.+)\n|(.+)"
                                                                               options:NSRegularExpressionCaseInsensitive
                                                                                 error:&error];
        NSArray    *array = [regex matchesInString:str options:0 range:NSMakeRange(0, str.length)];
        NSTextCheckingResult    *matches;
        for (matches in array) {
            NSString    *s = [str substringWithRange:[matches rangeAtIndex:0]];
            NSData  *dataout = [[NSData alloc] initWithBytes:[s UTF8String] length:[s lengthOfBytesUsingEncoding:NSUTF8StringEncoding]];
            [fho writeData:dataout];
        }
    }
    return 0;
}



ソースコード
GitHubからどうぞ。

https://github.com/murakami/workbook/tree/master/mac/analog - GitHub


関連情報
File System Programming Guide

[iOS][Web]ネイティブWebアプリケーション(その3)

ほんの最初の一歩にしかならないと思うが。以前紹介したWebアプリケーションで、HTMLとObjective-Cでやり取りするのに挑戦した。




HTMLコンテンツにObjective-Cから値(日付)を設定する領域を用意する。




Date: <input name="demo" type="text"><br /> 



UIWebViewを管理するビューコントローラをUIWebViewDelegateに対応させる。




@interface ViewController : UIViewController <UIWebViewDelegate>
@end



デリゲートメッソドに、HTMLコンテンツの表題を取得するコードを追加する。




- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    NSString    *title = [webView stringByEvaluatingJavaScriptFromString:@"document.title"];
    NSLog(@"%@", title);
}



デリゲートメッソドに、HTMLコンテンツの要素demoの値を書き換えるコードを追加する。




- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    NSString    *date = [NSString stringWithFormat:
            @"document.getElementsByName('demo').item(0).value='%@'",
            [NSDate date]];
    [webView stringByEvaluatingJavaScriptFromString:date];
}



ソースコード
GitHubからどうぞ。

https://github.com/murakami/workbook/tree/master/ios/WebApp - GitHub


関連情報
UIWebView Class Reference

UIWebViewDelegate Protocol Reference

[OSX][iOS]Code Snippet Library

スニペットのライブラリは、よく使うコードを直ぐに取り出せる機能だ。




設定による位置は変わるが、初期状態だと右下にスニペット・ライブラリが表示される。




CodeSnippetLibrary




登録したいコードをCode Snippet Libraryにドラッグ&ドロップする。




DragDrop

追加されたスニペットを選択して開く。そして、Editボタンを押下する。




open




Titileを編集して、Doneボタンを押下する。




edit




利用者が入力する項目がある場合は、<#と#>で囲まれた文字列を追加する。




dbgmsg




登録したスニペットをソースファイルにドラッグ&ドロップすれば追加できるようになる。




関連情報

Xcode 4 User Guide

[iOS]モーダルViewController(その3)

presentModalViewController:animated: の使用は推奨されなくなったようだ。


presentViewController:animated:completion: を使用するのだが、最後にBlockを指定するので期待したのだが、これはモーダル・ビュー表示後に実行する処理を記述する為で、独自にデリゲートやBlocksを用意する手間を省く為のものではないようだ。残念。





- (IBAction)modalPane:(id)sender
{
    ModalPaneViewController *viewController = [[ModalPaneViewController alloc] 
                                               initWithNibName:@"ModalPaneViewController"
                                               bundle:nil];
    [viewController setCompletionHandler:^(ModalPaneViewControllerResult result) {
        switch (result) {
            case ModalPaneViewControllerResultCancelled:
                [self performSelectorOnMainThread:@selector(didCancel:) withObject:nil waitUntilDone:NO];
                break;
            case ModalPaneViewControllerResultDone:
                [self performSelectorOnMainThread:@selector(didDone:) withObject:nil waitUntilDone:NO];
                break;
            default:
                break;
        }
        
        [self dismissModalViewControllerAnimated:YES];
    }];
    /* [self presentModalViewController:viewController animated:YES]; */
    [self presentViewController:viewController animated:YES completion:nil];
}



ソースコード
GitHubからどうぞ。

https://github.com/murakami/ModalPane - GitHub



関連情報
http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/ModalViewControllers/ModalViewControllers.html

[OSX][Python]QuartzとPythonスクリプト

Pythonをマスターする必要が出てきた。でも漠然と素のスクリプトの練習をしても仕方がないと思う。多分、PythonのWebアプリケーションのフレームワークを使ったサイトを立ち上げてみるのが要求に対する適切な対応だと思うが、ここはCocoa練習帳ですし、他とは少し違うスキルが必要という事で、QuartzツールをPythonスクリプトで制作する事に挑戦だ!




OS X Lion (10.7)には、2.7系列が組み込まれているようだ。




$ python -V
Python 2.7.1
$ python --version
Python 2.7.1
$ which python
/usr/bin/python



以前は、/Developer/Examples/Quartz/Python/API-SUMMARY にQuartz Python APIの文書があったようが、現在はない。




色々探してみて見つけたのがこれ。実は新しいXcodeインストール時に誤って古いXcodeを削除しなかったのだが、それがよかった。/Developer/Documentation/Python/ に情報があった。




早速、Retina以前のiPhone画面サイズの空のPDF書類「demo.pdf」を作成。




$ cat demo.py 
#!/usr/bin/env python
# -*- coding: utf-8 -*-
 
from CoreGraphics import *
 
# iOS size
mediaRect = CGRectMake(0.0, 0.0, 640.0, 960.0)
 
context = CGPDFContextCreateWithFilename("demo.pdf", mediaRect)
context.beginPage(mediaRect)
 
context.endPage()
context.finish()
 
# End Of File



このスクリプトを実行すれば、demo.pdfというファイルが生成されるのが確認できると思う。




空白ページだと寂しいので、赤色の四角形を描画。




$ cat demo.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
 
from CoreGraphics import *
 
# iOS size
mediaRect = CGRectMake(0.0, 0.0, 640.0, 960.0)
 
context = CGPDFContextCreateWithFilename("demo.pdf", mediaRect)
context.beginPage(mediaRect)
 
context.setRGBFillColor(1.0, 0.0, 0.0, 1.0)
ourRect = CGRectMake(20.0, 20.0, 130.0, 100.0)
context.fillRect(ourRect)
 
context.endPage()
context.finish()
 
# End Of File



あれ、CGContextSetRGBFillColorに相当する箇所でエラーとなっている。




$ ./demo.py
Traceback (most recent call last):
  File "./demo.py", line 12, in
    context.setRGBFillColor(1.0, 0.0, 0.0, 1.0)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/CoreGraphics/__init__.py", line 528, in setRGBFillColor
    def setRGBFillColor(*args): return _CoreGraphics.CGContext_setRGBFillColor(*args)
TypeError: in method 'CGContext_setRGBFillColor', argument 2 of type 'CGFloat'



何故だろう?




関連情報
Programming with Quartz: 2D and PDF Graphics in Mac OS X

Quartz 2D Programming Guide

Python Programming Language

RubyCocoa

Scripting Bridge Programmin Guide

Ruby and Python Programming Topics for Mac

[iOS]多言語化(5)

今回はStoryboardではなく、ソースコード中に言語に依存する文字列を埋め込んでいる場合の多言語化に挑戦だ。




ソースコード中に@"文言"で文字列を埋め込んでいる箇所をNSLocalizedString(@"文言", nil)に置換する。ベースは英語版の前提で話を進めているので、文言に相当する文字列はASCIIだ。




cell.detailTextLabel.text = NSLocalizedString(@"Detail", nil);



前回、Storyboardから文言を抜き出すターゲットを用意したが、これにNSLocalizedString()で多国語化する文字列を埋め込んだソースから文言を抜き出すスクリプトを追加する。




日本語を抜き出す




genstrings Homepwner/MasterViewController.m -o Homepwner/en.lproj
cp -p Homepwner/en.lproj/Localizable.strings Homepwner/ja.lproj/



このターゲットを実行すると、Localizable.stringsというファイルが生成されるはずだ。




ここからが前回の反省点をふまえた手順だ。


resourcesというグループを作成して多国語化で使用する文言のファイルをここに格納する。Finderからドラッグ&ドロップで追加という事になるか、これで追加するのは、en.lproj配下のファイルのみ。


追加したLocalizable.stringsを選択して、LocalizationとしてJapaneseを追加する。




日本語を選択




すると、ja.lprojにコピーが生成され、Xcode上の表示も操作しやすくなると思う。この時、この操作の前にja.lproj配下のファイルを日本語化していたら、英語版ファイルで上書かれるので注意する事。




多国語化


日本語化




Localizable.stringsをカスタマイズ。




/* No comment provided by engineer. */
"Detail" = "詳細表示";



実行




実行





関連情報

iPhoneアプリケーションプログラミング

[iOS]多言語化(4)

今回も、『iPhoneアプリケーションプログラミング』で紹介されていた方法。Xcodeでibtoolを使った日本語Storyboar生成の方法だ。




「ビルドフェーズ」に「スクリプトを実行」を追加する。




target


add_run_script




以前と同様、ja.lprojのMainStoryboard.stringsを日本語化する。




/* Class = "IBUITableViewController"; title = "Master"; ObjectID = "12"; */
"12.title" = "原盤";
 
/* Class = "IBUIViewController"; title = "Detail"; ObjectID = "21"; */
"21.title" = "詳細";
 
/* Class = "IBUINavigationItem"; title = "Detail"; ObjectID = "26"; */
"26.title" = "詳細";
 
/* Class = "IBUILabel"; text = "Detail view content goes here"; ObjectID = "27"; */
"27.text" = "詳細を表示";
 
/* Class = "IBUINavigationItem"; title = "Master"; ObjectID = "36"; */
"36.title" = "原盤";
 
/* Class = "IBUILabel"; text = "Title"; ObjectID = "phq-AM-6qj"; */
"phq-AM-6qj.text" = "表題";



スクリプトを記述。




script




ibtool --import-strings-file Homepwner/ja.lproj/MainStoryboard.strings --write Homepwner/ja.lproj/MainStoryboard.storyboard Homepwner/en.lproj/MainStoryboard.storyboard
exit 0



実行




storyboard




run




日本語化されている。




関連情報
iPhoneアプリケーションプログラミング

[iOS]多言語化(3)

今回は、『iPhoneアプリケーションプログラミング』で紹介されていた方法。Xcodeでibtoolを使う方法だ。




新規ターゲットを追加する。




NewTarget




以前のXcodeはShell Script Targetというのがあったが、今はないのでAggregateを選択する。




shell_script_target




ターゲット名を設定。




GenerateStringsFile




「スクリプトを実行」を追加する。




AddRunScript




スクリプトを記述。※例のプロジェクト名はHomepwner。




script




ibtool --export-strings-file Homepwner/en.lproj/MainStoryboard.strings Homepwner/en.lproj/MainStoryboard.storyboard
cp Homepwner/en.lproj/MainStoryboard.strings Homepwner/ja.lproj/MainStoryboard.strings
exit 0



アクティブターゲットを切り替える。




select_target




実行。更新されている。




$ ls -l *.lproj
en.lproj:
total 32
-rw-r--r--@ 1 yukio  staff    45  6 17 15:38 InfoPlist.strings
-rw-r--r--  1 yukio  staff  8174  6 18 07:50 MainStoryboard.storyboard
-rw-r--r--  1 yukio  staff  1228  6 21 22:33 MainStoryboard.strings
 
ja.lproj:
total 24
-rw-r--r--@ 1 yukio  staff  8050  6 20 23:19 MainStoryboard.storyboard
-rw-r--r--  1 yukio  staff  1228  6 21 22:33 MainStoryboard.strings



次回は、日本語Storybardの生成の自動化だ。




関連情報
iPhoneアプリケーションプログラミング

[iOS]多言語化(2)

ibtoolは仕様が代わったようで、以前のiPhone SDK向けの情報と違いがあるようだ。




まずは、基本的なibtoolを使用方法を試してみる。




前回の手作業で日本語版Storyboardのローカライズは、自動化というか、機械化というか、手順化できないという課題がある。ibtoolはそれを行う為のツールだ。




ベースとなる英語版Storybardから文字列情報を抜き出す。




$ ibtool --export-strings-file MainStoryboard.strings MainStoryboard.storyboard



生成したMainStoryboard.stringsを日本語環境にコピーして、文言の日本語に変更する。




$ cp MainStoryboard.strings ../ja.lproj/



これがオリジナル。




/* Class = "IBUITableViewController"; title = "Master"; ObjectID = "12"; */
"12.title" = "Master";
 
/* Class = "IBUIViewController"; title = "Detail"; ObjectID = "21"; */
"21.title" = "Detail";
 
/* Class = "IBUINavigationItem"; title = "Detail"; ObjectID = "26"; */
"26.title" = "Detail";
 
/* Class = "IBUILabel"; text = "Detail view content goes here"; ObjectID = "27"; */
"27.text" = "Detail view content goes here";
 
/* Class = "IBUINavigationItem"; title = "Master"; ObjectID = "36"; */
"36.title" = "Master";
 
/* Class = "IBUILabel"; text = "Title"; ObjectID = "phq-AM-6qj"; */
"phq-AM-6qj.text" = "Title";



これを翻訳する。





/* Class = "IBUITableViewController"; title = "Master"; ObjectID = "12"; */
"12.title" = "原盤";
 
/* Class = "IBUIViewController"; title = "Detail"; ObjectID = "21"; */
"21.title" = "詳細表示";
 
/* Class = "IBUINavigationItem"; title = "Detail"; ObjectID = "26"; */
"26.title" = "詳細表示";
 
/* Class = "IBUILabel"; text = "Detail view content goes here"; ObjectID = "27"; */
"27.text" = "ここに詳細を表示";
 
/* Class = "IBUINavigationItem"; title = "Master"; ObjectID = "36"; */
"36.title" = "原盤";
 
/* Class = "IBUILabel"; text = "Title"; ObjectID = "phq-AM-6qj"; */
"phq-AM-6qj.text" = "表題";



これから日本語版Storyboardを生成。




$ ibtool --import-strings-file MainStoryboard.strings --write MainStoryboard.storyboard ../en.lproj/MainStoryboard.storyboard



翻訳されている。

storyboard




勿論、実行しても。

run




関連情報

iPhoneアプリケーションプログラミング

[iOS]多言語化

しっ!ここだけの話、著者が明るくない分野として多言語化というのがある。なので弊社のアプリは英語版のみとなっている。これは他言無用だ!




というわけで、今回は多言語化だ!




そして、後ろを振り向かない著者が取り組むのは、NIBファイルでなく、Storyboardファイルだ!




Storyboardファイルを選択して、情報領域のLocalizaionの+ボタンを押下する。

Localization




Japaneseを選択する。

日本語を選択




すると日本語向けStoryboarファイルが用意されるので、タイトル等を日本語に変更する。

日本語




環境設定で日本語を選ぶと、日本語のリソースが選択された!

実行




機会があれば、ibtoolのような、もっと手順化できる方法に挑戦したい。




関連情報
iPhoneアプリケーションプログラミング