Wednesday, February 27, 2013

MySQL

iOSシミュレータでデバッグできない

XcodeからiOSシミュレータでデバッグできない場合

error: failed to attach to process ID xxxx
デバッガには↑が表示され
Attaching to SampleApp
Xcode上には↑が表示され中止も出来なくなるのでXcodeを強制終了する必要がある

解決法としては、
[Edit Scheme...]→[Run SampleApp.app]→[Info]→[Debugger]
で、デバッガをLLDBからGDBにするか、

PCのhostsに以下を追加する
127.0.0.1    localhost


参考

Friday, February 22, 2013

PhpStormで文字エンコーディング変更

PhpStormのプロジェクトの文字エンコーディングを変更。

[Preferences]→[File Encodings]
・[Autodetect UTF-encoded files]のチェックを外す。
・プロジェクトフォルダの右側の空いてる部分をクリックして任意の文字コードを選択。
PhpStormをリスタート。

NSOperationのプロパティ

NSOperationのサブクラスを作って、
そのクラスに
@property (nonatomic, copy) DummyBlock completionBlock;
という名前のプロパティを作成して、
Operation完了後の処理をこのBlocksで実行するように実装すると、
いろいろ挙動がおかしくなります
(setCompletionBlockというメソッドがNSOperationの抽象メソッドのため)

名前を変えたら期待通りの動きになった
Xcodeだとオーバーライドしてるのがわかりにくいなと思った

Sunday, February 17, 2013

DotMemo ver1.0.0

DotMemoというiPhoneアプリをリリースしました
https://itunes.apple.com/jp/app/dotmemo/id601886212?l=ja&ls=1&mt=8

簡単に言うとUITextViewをwindowにそのままはっつけただけのどうみてもやっつけなアプリです
素人が作ったものだから仕方ないね(言い訳)

微妙にジェスチャーをサポートしてます
一応iPadでも使えるはずです(実機で動くのかは不明)

iOS6の実装の仕方を勉強してて、その流れでoutputしたものなのですが、
まさか審査通るとはおもわなかっt

Xcode4.6でiOS framework作成

iOSのframework作成をしようと、いろいろ参考にしたけど、すごく詰まったので一応書いておく
Xcodeのバージョンは4.6

Project作成

[File]→[New]→[Project]
を選択
[iOS]→[Framework & Library]→[Cocoa Touch Static Library]

[Product Name] "MyLibrary" と入力(名前を決める。***.framework の *** の部分)
[Organization Name] と [Company Identifier] は適当に
[Include Unit Tests] はどちらでも
[Use Automatic Reference Counting] はチェック入れたままで

パスはまあ適当に好きな所に作成


Headerディレクトリ作成

Xcode の MyLibrary ディレクトリを右クリックして[Add Files to "MyLibrary"...]をクリック
出てきたプロンプトの左下の[New Folder]をクリックして "Headers" と入力して[Create]
右下の[Add]でプロジェクトに追加
ここに公開したい .hファイルを置く(ライブラリを実装したら入れてください)


ターゲット作成

[TARGETS]→[MyLibrary]を選択して、左下の[Add Target]をクリック
[iOS]→[Other]→[Aggregate]

[Product Name] "MyLibrary-Universal" と入力(何でもいい?)
[Finish]して作成


スキーマ設定変更

[Manage schemes]で MyLibrary の Show のチェックを外す
(別に外す必要はないけど、使用しないので非表示にしているだけ)


Info.plist作成

[Supporting Files]を右クリックして[New File...]をクリック
[iOS]→[Resource]→[Property List]

[Save As:]に "Info.plist" と入力
[Create]して作成
Info.plist を右クリックして[Open As]→[Source Code]
下のコードをコピーして上書き。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
 <key>CFBundleName</key>
 <string>MyLibrary</string>
 <key>CFBundleIdentifier</key>
 <string>com.blogspot.fiahfy.MyLibrary</string>
 <key>CFBundleInfoDictionaryVersion</key>
 <string>6.0</string>
 <key>CFBundleVersion</key>
 <string>1</string>
 <key>CFBundleExecutable</key>
 <string>MyLibrary</string>
 <key>CFBundleGetInfoString</key>
 <string>MyLibrary</string>
 <key>NSPrincipalClass</key>
 <string></string>
 <key>CFBundlePackageType</key>
 <string>FMWK</string>
 <key>CFBundleIconFile</key>
 <string></string>
 <key>CFBundleSignature</key>
 <string>????</string>
 <key>CFBundleDevelopmentRegion</key>
 <string>English</string>
 <key>NSHumanReadableCopyright</key>
 <string>Copyright fiahfy. All rights reserved.</string>
 <key>CFBundleShortVersionString</key>
 <string>1.0.0</string>
</dict>
</plist>

Info.plist を右クリックして[Open As]→[Property List]
で開き直して、
MyLibrary, com.blogspot.fiahfy.MyLibrary, fiahfy
等の部分を自分で設定したものに適宜変更する


スクリプト設定

[TARGETS]→[MyLibrary-Universal]を選択して、
[Build Phases]→[Add Build Phase]→[Add Run Script]をクリック
"Type a script or drag a script file from your workspace" の部分に以下のスクリプトをコピペ
# Environment Variables
INFO_PLIST="Info.plist"
FRAMEWORK_NAME=${PROJECT_NAME}
FRAMEWORK_VERSION_NUMBER=$(/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" ${SRCROOT}/${PROJECT_NAME}/${INFO_PLIST})
FRAMEWORK_VERSION=A
FRAMEWORK_BUILD_PATH="${SRCROOT}/build/${CONFIGURATION}-framework"
FRAMEWORK_DIR="${FRAMEWORK_BUILD_PATH}/${FRAMEWORK_NAME}.framework"
FRAMEWORK_PACKAGE_NAME="${FRAMEWORK_NAME}.${FRAMEWORK_VERSION_NUMBER}.zip"

# Clean directories
[ -d "${FRAMEWORK_BUILD_PATH}" ] && rm -rf "${FRAMEWORK_BUILD_PATH}"

# Build simulator and device binaries.
xcodebuild -project ${PROJECT_NAME}.xcodeproj \
 -sdk iphonesimulator${IPHONEOS_DEPLOYMENT_TARGET} \
 -target "${PROJECT_NAME}" \
 -configuration ${CONFIGURATION} clean build
xcodebuild -project ${PROJECT_NAME}.xcodeproj \
 -sdk iphoneos${IPHONEOS_DEPLOYMENT_TARGET} \
 -target "${PROJECT_NAME}" \
 -configuration ${CONFIGURATION} clean build

# create framework directories.
mkdir -p ${FRAMEWORK_DIR}
mkdir -p ${FRAMEWORK_DIR}/Versions
mkdir -p ${FRAMEWORK_DIR}/Versions/${FRAMEWORK_VERSION}
mkdir -p ${FRAMEWORK_DIR}/Versions/${FRAMEWORK_VERSION}/Resources
mkdir -p ${FRAMEWORK_DIR}/Versions/${FRAMEWORK_VERSION}/Headers

# create symlinks
ln -s ${FRAMEWORK_DIR}/Versions/${FRAMEWORK_VERSION} ${FRAMEWORK_DIR}/Versions/Current
ln -s ${FRAMEWORK_DIR}/Versions/Current/Headers ${FRAMEWORK_DIR}/Headers
ln -s ${FRAMEWORK_DIR}/Versions/Current/Resources ${FRAMEWORK_DIR}/Resources
ln -s ${FRAMEWORK_DIR}/Versions/Current/${FRAMEWORK_NAME} ${FRAMEWORK_DIR}/${FRAMEWORK_NAME}

# create the universal library
lipo -create \
 ${SRCROOT}/build/${CONFIGURATION}-iphoneos/lib${FRAMEWORK_NAME}.a \
 ${SRCROOT}/build/${CONFIGURATION}-iphonesimulator/lib${FRAMEWORK_NAME}.a \
 -output "${FRAMEWORK_DIR}/Versions/Current/${FRAMEWORK_NAME}"

# copy files
ls ${SRCROOT}/${PROJECT_NAME}/Headers/*.h > /dev/null 2>&1 && cp ${SRCROOT}/${PROJECT_NAME}/Headers/*.h ${FRAMEWORK_DIR}/Headers/
cp ${SRCROOT}/${PROJECT_NAME}/${INFO_PLIST} ${FRAMEWORK_DIR}/Resources

# create zip
cd ${FRAMEWORK_BUILD_PATH}
zip -ry ${FRAMEWORK_PACKAGE_NAME} $(basename $FRAMEWORK_DIR)



ここまで設定すればビルドは一応通るはず(中身がないので意味のないframeworkですが)

ビルド後は
build/Debug-framework/MyLibrary.framework
が作成されているので、これを使用したいプロジェクトで「Linked Frameworks and Libraries」に追加すればおk

リリースビルドした場合は
build/Release-framework/MyLibrary.framework
で、配布したい時は
build/Release-framework/MyLibrary.1.0.0.zip
を配ればよいって感じかと思います

中身書く前に疲れたっていう


参考

Saturday, February 16, 2013

Perlでファイルの上書き

Perlでファイルを上書きしたい場合は
open(OUT, "> $filepath");
print OUT "hoge\n";
close(OUT);
とするが、この方法だと上書きする際にファイルが一度0バイトになってしまう。
その状態で読み込みが走ると、0バイトのファイルが取得されてしまう。
それを回避する為には下の方法で。
open(OUT, "+< $filepath");
flock(OUT, 2);
seek(OUT, 0, 0);
print OUT "hoge\n";
truncate(OUT, tell(OUT));
close(OUT);
ただこのままだと、上書きするファイルが無い場合にエラーが出てしまうため場合分けする。
if (-f $filepath) {
    open(OUT, "+< $filepath");
    flock(OUT, 2);
    seek(OUT, 0, 0);
    print OUT "hoge\n";
    truncate(OUT, tell(OUT));
    close(OUT);
} else {
    open(OUT, "> $filepath");
    print OUT "hoge\n";
    close(OUT);
}


参考

Thursday, February 14, 2013

PhpStormで任意の拡張子を無視

PhpStormで任意の拡張子を無視するように設定。
[Preferences]→[File Types]→[Ignore files and folders]
に追加。(*.aaa みたいに)

No such file or directory

$ ./xxxxx.pl
: No such file or directory!C:/Perl/bin/perl
:
と表示されてエラーが出る場合。
Perlがutf-8で書かれている場合は、BOM無しにしてみると実行できた

Tuesday, February 12, 2013

blocksで遅延実行

blocksで遅延実行
// 2秒遅延
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 2.0f * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
// code
});

Objective-Cのリテラル表現

Objective-Cのリテラル表現(Xcode4.4以降)
// Array
NSArray *array = @[@"hoge", @"fuga"];
// Dictionary
NSDictionary *dictionary = @{@"key1" : @"val2", @"key2" : @"val2"};
// Number
NSNumber *number1 = @100;
NSNumber *number2 = @YES;

// 添字アクセス
NSString *str1 = array[0];     // @"hoge"
NSString *str2 = dictionary[@"key2"];      // @"val2"

コードが大分すっきりするようになっていいです


参考

Objective-Cデバッグ用にエラー出力

デバッグ用に以下を入れる

@AppDelegate.m
void uncaughtExceptionHandler(NSException *exception) {
    NSLog(@"CRASH: %@", exception);
    NSLog(@"Stack Trace: %@", [exception callStackSymbols]);
    // Internal error reporting
}

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);
    // Override point for customization after application launch.
    return YES;
}
なんかいろいろ出てきて便利


参考

Monday, February 11, 2013

eclipse上でのエディタ関連づけ

任意の拡張子のファイルをeclipse内の任意のエディタで開くように設定する方法

例えば、*.inc ファイルを .html ファイルと同じエディタで開くように設定する場合
[環境設定]→[一般]→[コンテンツ・タイプ]→[テキスト]→[HTML]を選択して[追加]
*.inc と入力して[OK]
ファイルを開き直せばおk


[環境設定]→[一般]→[エディター]→[ファイルの関連付け]
に *.inc いれてHTMLエディターを設定しても効果がなかった
こっちの設定は何の為にあるんだか

Sunday, February 10, 2013

iphoneアプリのiconとsplash

アイコンサイズやら起動画面の画像サイズとか

splash
Default.png320x480 px
Default@2x.png640x960 px
Default-568h@2x.png640x1136 px
Default-Portrait~ipad.png768x1004 px
Default-Portrait@2x~ipad.png1586x2008 px
Default-Landscape~ipad.png1024x748 px
Default-Landscape@2x~ipad.png2048x1496 px

icon
Icon.png57x57 px
Icon@2x.png114x114 px
Icon-72.png72x72 px
Icon-72@2x.png144x144 px
Icon-small.png29x29 px
Icon-small@2x.png58x58 px
Icon-small-50.png50x50 px
Icon-small-50@2x.png100x100 px

とりあえず以上のサイズを作成


参考

Multiple build commands for output file

xcodeで何度かIconを再登録していたらなんか上記のwarningが出た

[TARGETS]→[Build phases]→[Copy Bundle Resources]
で重複しているファイルを削除で解消


参考

SyntaxHighlighterでObjective-C

SyntaxHighlighterでObjective-Cをハイライトできなかったので以下のJSをヘッダに追加
<script src='https://raw.github.com/andrashatvani/shBrushObjC/master/shBrushObjC.js' type='text/javascript'/>
あとはエイリアスをocに設定
<pre class="brush: oc;">
    NSLog(@"hoge");
</pre>

参考

キーボード表示時にリサイズ

キーボード表示時にUITextViewをリサイズするテンプレ

Landscapeの場合keyboardRectのwidthとheightが逆になるので考慮する
self.viewのサイズを取得する場合はboundsを使用する。(frameの場合Landscapeになっても値が変わらない)

- (void)viewWillAppear:(BOOL)animated
{
 [super viewWillAppear:animated];
 
 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}

- (void)viewDidDisappear:(BOOL)animated
{
 [super viewDidDisappear:animated];
 
 [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
 [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}

:

- (void)keyboardWillShow:(NSNotification*)notification
{
 CGRect keyboardRect = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
 if (UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])) {
  CGRect rect = keyboardRect;
  rect.size.width = keyboardRect.size.height;
  rect.size.height = keyboardRect.size.width;
  keyboardRect = rect;
 }
 CGRect frame = self.textView.frame;
 frame.size.height = self.view.bounds.size.height - keyboardRect.size.height;
  
 NSTimeInterval duration = [[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
 
 UIViewAnimationCurve curve = [[[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue];
 
 [UIView animateWithDuration:duration delay:0.0f options:(curve << 16) animations:^{
  self.textView.frame = frame;
 } completion:nil];
}

- (void)keyboardWillHide:(NSNotification*)notification
{
 CGRect frame = self.textView.frame;
 frame.size.height = self.view.bounds.size.height;
 
 NSTimeInterval duration = [[[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
 
 UIViewAnimationCurve curve = [[[notification userInfo] objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue];
 
 [UIView animateWithDuration:duration delay:0.0f options:(curve << 16) animations:^{
  self.textView.frame = frame;
 } completion:nil];
}

Wednesday, February 6, 2013

Interface Builderで画像がキャッシュされる

XcodeのIntefaceBuilderで一度設定した画像を
同名の別の画像に変更した場合に
シミュレータで元の画像が表示されてしまう場合

Xcodeで[Product]→[Clean]する
iOSシミュレータで[iOSシミュレータ]→[コンテンツと設定をリセット...]して終了させる
Xcodeで再度Runで新しい画像が反映された

どういうタイミングで発生するのかは謎

Friday, February 1, 2013

Perlでのトランザクション

DBIを使用した場合のトランザクションはこんな感じ?
%attr = (RaiseError=>1, PrintError=>0);    # AutoCommit=1 (default)
$dbh = DBI->connect($dsn, $user, $pass, \%attr);
eval {
    $dbh->begin_work;    # begin tran
    $sth = $dbh->prepare($statement);
    $sth->bind_param($p_num, $bind_value);
    $sth->execute;
    $dbh->commit;    # commit tran
};
if ($@) {    # eval内でエラーが発生するとここへ
    warn "Transaction aborted because $@";
    $dbh->rollback;    # rollback tran
}
$dbh->disconnect;

AutoCommit=1の場合は明示的にbegin_workでトランザクションを開始する
AutoCommit=0の場合は
$dbh->{AutoCommit} = 0;
したタイミングで開始される?
明示的に指定したいのでそのまま(AutoCommit=1)で

RaiseError=1だとDBerrorの際にdieを発生させる
RaiseError=0だといちいち
$sth->bind_param($p_num, $bind_value) or die("sql bind error $!");
とする必要がある
die書くのが面倒なので(RaiseError =1)で

PrintError=1だとDBerror時にエラーメッセージを表示させる
RaiseError=1の場合、dieのメッセージを表示すると
同じものが表示されて鬱陶しいので(PrintError=0)


参考

PerlでURLEncode/Decode

PerlでURLEncodeとURLDecode
use URI::Escape;

$unescaped = uri_unescape($escaped);
$escaped = uri_escape($unescaped);
URI::Escapeってデフォで入ってるからパッケージ入れる必要なし?

参考

shellでの条件分岐

shellでのor表現
if [$hoge = "aaa" -o $fuga = "bbb"]; then
  # or
fi

shellでのand表現
if [$hoge = "aaa" -a $fuga = "bbb"]; then
  # and
fi

参考

動的ビュー

Bloggerの動的ビューやめました

以下理由
  • 表示が遅い&重い
  • 2回目の記事表示時にSyntaxHighlighterがうまく動かない
  • 画像をたくさん使うブログでは見栄えがいいけど、コードばかりだといまいち
  • そもそもコードをのせるのにあまり適してない

仕方ないね