ヒレガス本 17章 課題
ランダムな直線の描画部分を曲線に変えろとの事。
これは簡単。変更部分は1カ所だけ。
thePoint = [self randomPoint];
[path lineToPoint:thePoint];
を
[path curveToPoint:[self randomPoint]
controlPoint1:[self randomPoint]
controlPoint2:[self randomPoint]];
に変えただけ。
プロジェクトファイルは、 DrawingFun.zip に置いておきます。
ヒレガス本 16章 課題 その2
前回のアップデートスクリプトに加えて、ビルド時のチェックツールも作ってみた。
機能は、
- 既に存在しないキーで指定された、翻訳文が有れば警告
- ソースコード中にキーが有るが、*.stringsに存在しないキーがあれば警告
- マージがコンクリフトしている場所をエラー
とするツールを作った。
#!/bin/sh
#
# *.lproj/Localizable.stringsの内容のチェックを行う
# stringsの拡張子
theStringsExt=".strings"
# ローカライズディレクトリの拡張子
theLocalizeExt=".lproj"
# Localizable.stringのファイル名
theLocalizableStrings="Localizable"$theStringsExt
##########################################################################################
#
# missingなキーワードの警告
#
##########################################################################################
# warningMessage フルパス 行番号 警告メッセージ 警告行のテキスト
function warningMissingKeyWordMessage() {
local FULL_PATH_FILE_NAME=$1
local KEYWORD_STRING=$2
echo $FULL_PATH_FILE_NAME"::: warning:" $KEYWORD_STRING is a missing key word.":" $KEYWORD_STRING
}
##########################################################################################
#
# danglingなキーワードの警告
#
##########################################################################################
function warningDanglingKeyWordMessage() {
local FULL_PATH_FILE_NAME=$1
local KEYWORD_STRING=$2
echo $FULL_PATH_FILE_NAME":"`grep -n $KEYWORD_STRING $FULL_PATH_FILE_NAME | cut -d":" -f1`":0: warning:" $KEYWORD_STRING is a dangling key word.":" `grep $KEYWORD_STRING $FULL_PATH_FILE_NAME`
}
##########################################################################################
#
# エラーメッセージを出力
#
##########################################################################################
# errorMessage フルパス 行番号 エラーメッセージ エラー行のテキスト
function errorConflictMessage() {
local FULL_PATH_FILE_NAME=$1
local LINE_NUMBER=$2
local TEXT_STRING=$3
echo $FULL_PATH_FILE_NAME":"$LINE_NUMBER":0: error: Merge conflict :" $TEXT_STRING
}
# Base.lprojのフルパス
theBaseLocalizableStrings=`pwd`/Base$theLocalizeExt/$theLocalizableStrings
# キーだけのリストにしてtmpへ保存する
# 一時的な作業フォルダーを作成する
theTempDir="tmp"
if ! [ -d $theTempDir ]; then
mkdir $theTempDir
fi
# コメントと空白行を削除
cat $theBaseLocalizableStrings | sed -e 's:/\*.*\*/::' | sed -e '/^[<space><tab>]*$/d' | cut -d' ' -f1 > $theTempDir/tmplist.txt
# forループの区切りを改行だけにする
IFS=$'\n'
# Base.lproj/以下以外のLocalizable.stringsを全部ループ
for theIterator in `find \`pwd\` -regex ".*/Base.lproj/.*" -prune -o -regex ".*lproj/Localizable\.strings" -print`
do
# 右側にだけある項目
for theWord in `cat $theIterator | sed -e '/^<<<<<<<.*$/d' | sed -e '/^|||||||.*$/d' | sed -e '/^=======.*$/d' | sed -e '/^>>>>>>>.*$/d' | sed -e 's:/\*.*\*/::' | sed -e '/^[<space><tab>]*$/d' | cut -d' ' -f1 | sort | uniq | comm -13 $theTempDir/tmplist.txt -`
do
warningDanglingKeyWordMessage $theIterator $theWord
done
# 左側にだけある項目
for theWord in `cat $theIterator | sed -e 's/^<<<<<<<.*$//' | sed -e 's/^|||||||.*$//' | sed -e 's/^=======.*$//' | sed -e 's/^>>>>>>>.*$//' | sed -e 's:/\*.*\*/::' | sed -e '/^[<space><tab>]*$/d' | cut -d' ' -f1 | sort | uniq | comm -23 $theTempDir/tmplist.txt -`
do
warningMissingKeyWordMessage $theIterator $theWord
done
# コンフリクトな行(下の四行など)をコンクリフトだと報告する
# <<<<<<<
# |||||||
# =======
# >>>>>>>
for theConflictLine in `cat $theIterator | grep -n '^<<<<<<<\|^=======\|^>>>>>>>\|^|||||||'`
do
errorConflictMessage $theIterator `echo $theConflictLine | cut -d':' -f1` `echo $theConflictLine | cut -d':' -f2`
done
done
# 後片付け
rm -f $theTempDir/tmplist.txt
XCodeに組み込んで使います。
ここに置いて、
こんな風に設定すると。
ビルド時に、こんな風に警告が出たりエラーが出ます。
実用的になるかどうかは不明。 16章はここら辺で見切りを付けて明日からは次の章を行うつもり。
ヒレガス本 16章 課題
16章のローカライズの章には課題は無い。無いので自分で課題を作ってみた。
genstringsを使った文字列のローカライズを支援するツールを作成する。
genstringsが自動でLocalizable.stringを作れるのはよい。楽だ。 開発の最後の段階でローカライズを行い、1回の翻訳で全ての文字列を翻訳できるのならば、問題も無い。
しかし、実際には開発を行いながらローカライズも随時行うのが私のやり方です。面倒だと思ってもユーザーインターフェイスを追加したり削除したりします。 ソースコードもリファクタリングしてアラートの数を減らしたりします。
genstringsはLocalizable.stringを上書きしてしまうので、そのまま使うと翻訳済みのデータが消えてします。
そこで、genstringsとdiff3を組み合わせて、翻訳済みのデータを上書きしないようにシェルスクリプトを書いてみました。 練習でつくってみただけですので、実開発では使っていません。
#!/bin/sh
#
# updateLocalizableStrings
#
# マージツール
# stringsの拡張子
theStringsExt=".strings"
# ローカライズディレクトリの拡張子
theLocalizeExt=".lproj"
# Localizable.stringのファイル名
theLocalizableStrings="Localizable"$theStringsExt
theTempDir="tmp"
theNewBaseLocalizableStrings=$theTempDir/$theLocalizableStrings
##########################################################################################
#
# 新たに生成されたLocalizable.stringsを"tmp/Localizable8.strings"に用意する
#
##########################################################################################
# 一時的な作業フォルダーを作成する
if ! [ -d $theTempDir ]; then
mkdir $theTempDir
fi
# ソースコードをなめて、置換えテーブルを作成。作成場所は"./tmp/Localizable.strings"
genstrings -o $theTempDir `find . -name '*.[hcm]'`
# UTF-8に変換
iconv -f UTF-16 -t UTF-8 < $theNewBaseLocalizableStrings > $theNewBaseLocalizableStrings"_tmp"
# 後片付け
mv $theNewBaseLocalizableStrings"_tmp" $theNewBaseLocalizableStrings
##########################################################################################
#
# 古いLocalizable.stringsは"Base.lproj/Localizable.strings"にあると仮定する。なかったら作る
#
##########################################################################################
theOldBaseLocalizableStrings="Base"$theLocalizeExt/$theLocalizableStrings
if ! [ -f $theOldBaseLocalizableStrings ]; then
cp $theNewBaseLocalizableStrings $theOldBaseLocalizableStrings
fi
##########################################################################################
#
# "Base"ディレクトリ以外の"*.lproj/Localizable.strings"をdiff3でアップデートする
#
##########################################################################################
for theLocaleStringsDir in `find . -name "*.lproj" -print`
do
if [ $theLocaleStringsDir != "./Base.lproj" ]; then
theLocaleStringsFile=$theLocaleStringsDir"/Localizable.strings"
# 無ければ作り、あればdiff3でアップデート
if ! [ -f $theLocaleStringsFile ]; then
cp $theNewBaseLocalizableStrings $theLocaleStringsFile
else
diff3 -m $theLocaleStringsFile $theOldBaseLocalizableStrings $theNewBaseLocalizableStrings > $theLocaleStringsFile"_tmp"
mv $theLocaleStringsFile"_tmp" $theLocaleStringsFile
fi
fi
done
# 最後に"Base.lproj/Localizable.strings"を更新する
cp $theNewBaseLocalizableStrings $theOldBaseLocalizableStrings
使い方は、 “*.m” や “*.lproj” があるディレクトリで呼出すだけです。 必要に応じて “*.lproj/Localizable.strings” のデータが更新されます。 コンクリフトが発生した場合は、gitやsvnでおなじみの”<<<<<<<<”の文字列が書き込まれますので随時対処してください。
このスクリプトの課題
- diffのように行毎に比較して判断するのではなく、”*.strings”をパースするコードを書けばもう少し知的な振る舞いが出来そう。
- ibtoolの出力に対してもアップデート出来るコマンドがあると便利かも。
- プログラマだけで開発するのならよいけど、翻訳担当にコマンドラインインターフェイスはキツいかも。せめてExcelで編集csvで読込みが出来るようにするべきでは?
ヒレガス本 15章 課題
削除しないが昇給なし(Keep, but no raise)ボタンを追加しろとの事。
これも簡単、KVCで行うと、NSArrayに含まれる全てのオブジェクトのプロパティーにアクセス出来る。 Controller経由でArrayを取得する事で、Undo/Redoにも対応してる。
- (IBAction) KeepButNoRaise:(id)sender
{
NSArray* theSelectedPeople = [employeeController selectedObjects];
[theSelectedPeople setValue:[NSNumber numberWithFloat:0.0]
forKeyPath:@"expectedRaise"];
}
後は、ボタンのenable/disableはbindingで選択された行数で判定。
プロジェクトファイルは、 RaiseMan_AlertPanel に置いておきます。





