引越しました。 http://r-plus.github.io/
Archive for 2013
UIImageのappIcon取得メソッド
UIImage
のプライベートクラスメソッド。SpringBoardとIPCしてアイコンイメージ返してくれる。便利。iOS 5.0+
+ (id)_applicationIconImageForBundleIdentifier:(NSString *)bundleIdentifier format:(int)arg2; + (id)_applicationIconImageForBundleIdentifier:(NSString *)bundleIdentifier format:(int)arg2 scale:(float)arg3;
xpwnのdmgでDecrypt
以前書いたvfdecrypt
を使うとiOS 6.0からはバグったdmgファイルしか生成できなくなりました。代替としてxpwnのdmg
を使う事で正常にDecryptできます。
Xpwnからdmgをビルドする
xpwnのコードからビルドします。
git clone git://github.com/planetbeing/xpwn.git cd xpwn mkdir build cd build cmake .. make dmg-bin
warningが出ますが、dmg
はコンパイルできてます。dmg/dmg
がそれです。/usr/local/bin/
にでも入れときましょう。
dmgでDecrypt
dmg extract XXX-XXXX-XXX.dmg output.dmg -k <key>
RHEL6.xでファイル生成日時crtimeを確認する方法
ファイルには様々なメタデータがあり、代表的なのはmtime, atime, ctimeとかがあります。ext3ではこれらの情報はi-nodeの情報として格納されており、stat
コマンド等で確認する事ができます。ここでctimeはChange timeなので厳密にはファイルの生成時間ではありませんが、ext4からは嬉しい事にファイル生成時間がcrtimeとして拡張されています。
さて、今お仕事で触っているRHEL6.xですが、こいつのcoreutilsのバージョンが8.4です。stat
コマンドがcrtimeの表示をサポートする初めてのコミットを含むバージョンは8.6であるため、RHNのパッケージのstat
コマンドでは確認できません。RHEL 7.xではstat
で知ることができるでしょう。
この程度のために他のリポジトリからのパッケージの導入やコンパイルをするもの億劫ですし、頻繁に使うわけでもありません。情報自体はi-nodeに格納されているため、その情報を見ることができればcrtimeを知る事ができます。debugfs
コマンドはext2, 3, 4のデバッグ用のコマンドで、これを使ってファイルのi-nodeの情報を見ることができます。
debugfs -R "stat /root/test" /dev/mapper/vg01-lv02
ファイルシステムのマウントポイントをルートとしたPATH指定なので注意。<>でくくってi-node番号指定にする事もできます。これを打つと以下のようにi-nodeの情報が出力されます。
Inode: 133370 Type: regular Mode: 0644 Flags: 0x80000 Generation: 1995841318 Version: 0x00000000:00000001 User: 0 Group: 0 Size: 250 File ACL: 0 Directory ACL: 0 Links: 1 Blockcount: 8 Fragment: Address: 0 Number: 0 Size: 0 ctime: 0x4c080d16:0bf9435c -- Thu Jun 3 21:14:14 2010 atime: 0x4c3da303:c11dd858 -- Wed Jul 14 12:44:03 2010 mtime: 0x4c080d16:0bf9435c -- Thu Jun 3 21:14:14 2010 crtime: 0x4c080d16:0bf9435c -- Thu Jun 3 21:14:14 2010 ←これ Size of extra inode fields: 28 EXTENTS: (0): 557470
アプリのスタートアップ機能を搭載したInfinityTask v1.4
InfinityTaskの1.4をリリースしました。1.4では実験的な機能としてアプリのスタートアップを登録できる機能を追加しました。 「Startup Applications」の項目でアプリをオンにするとRespring後に自動でそのアプリが起動します。 SafariとChromeではこの起動時にOpenTabBackground++が動作するようにしました。
この起動は電話やメールと同様のサイレントな起動をしますので、通常のアプリ起動シーケンスとは異なる起動シーケンスになります。 このためアプリ側の各種初期化を行うメソッドの実装によっては望みの状態まで起動されない事もあります。(特にゲーム系はスタート画面まで行かない事が多いです)
本機能の主眼であるSafari, Chromeにおいては起動されてOTB++が動作する事を確認済みです。
iPadかどうか判別する
[[UIDevice currentDevice] isWildcat]でもいいんですが、無駄にPrivate API使うのも危険なので(とは言えAppleのコードではかなり使われているのでこれの仕様が変わったり無くなったりする事はほぼ無いんじゃないかとは思いますが)、最近良く見かける下記のやり方の方が良さそう。
static BOOL IsPad(void) { return UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad; }
これも安心のiOS 3.2+
画面が縦なのか横なのかを判別する
これまで色々なメソッド使ってみたりしましたが、これ以上ない正解に辿りついたのでメモ。
static BOOL IsLandscape(void) { return UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation); }
ちなみにステータスバーが非表示でも大丈夫みたいです。
Available in iOS 2.0 or higherの安心設計。
resizableImageWithCapInsets:(UIEdgeInsets)capInsets でちょっとハマった話
Capの左右(上下)の合計を画像の幅(高さ)と同じにした時のバグ(iOS 5)
ボタン用の下のような画像を背景に使った時にこんなコードを書いてハマったケース。
[button setBackgroundImage:[bgImage resizableImageWithCapInsets:UIEdgeInsetsMake(20.0f, 22.0f, 20.0f, 22.0f)] forState:UIControlStateNormal];こう書くとiOS 6ではうまくいくのだけど、iOS 5では通常時は普通の表示だけどボタンを押下すると何か欠ける。

これは元画像の幅44pxに対してUIEdgeInsetsMakeのleftとrightの合計が44pxで同一になっているのが原因だ。左右端が表示されているのは画像の高さが47pxでtop+bottomは40だからだろう。ちなみに同一になるように書いてもiOS 6では丁度境界の1pxを引き伸ばしているのか、いい具合に表示された。丁度にする必要はないので若干数値を減らせばOKだ。
[button setBackgroundImage:[bgImage resizableImageWithCapInsets:UIEdgeInsetsMake(20.0f, 20.0f, 20.0f, 20.0f)] forState:UIControlStateNormal];
Capの左右(上下)で片方だけ0指定した時のバグ(iOS 5)

_backgroundImageView.image = [bgImage resizableImageWithCapInsets:UIEdgeInsetsMake(43.0f, 0, 0, 0)];これはCap-topを43にして残りの下1pxを伸ばしてくれると思って書いたコードだ。これの原因はtopに1以上の値を指定したがbottomは0を指定しているためだ。どうやら左右(上下)の数値の組み合わせは0,0の組み合わせでなければ1以上を指定して引き伸ばす範囲を明確にしないとダメらしい。ちなみにこれもiOS 6ではイイカンジに引き伸ばして表示された。解決の為には1以上を指定すればいいので、引き伸ばすピクセルが一番下の1pxではなく下から2px目になってしまうが、以下のようにすれば良い。
_backgroundImageView.image = [bgImage resizableImageWithCapInsets:UIEdgeInsetsMake(42.0f, 0, 1.0f, 0)];

これでiOS 5でもちゃんと引き伸ばされる。
BundleIdentifierSearcher
あのアプリを買っていないのだけれど、tweak作成にあたってBundleIdentifierを知りたい・・・。そんな貴兄におくるBundleIdentifierSearcher!
検索してダブルクリックするとBundleIdentifierをコピーできます。NSJSONSerializationクラスとNSArray, NSDictionaryのModern Objective-C Literal Syntaxを使っているのでOS X 10.7+が必要です。
iOS 5からのTwitter連携用に作られたのでしょうけど、JSON扱えるクラスがFoundationにあって助かった。
バイナリはこちら
ソースはgithubに。
Sleipnizer 3.1が出ました
Sleipnizer 3.1が出ました!
新機能
■Improved FindOnPageアクション
独自のFindOnPageを呼ぶ出すアクションを追加しました。■Focus SearchBarアクション
検索バーにフォーカスするアクションを追加しました。■KeepTabBarオプション
タブを残してフルスクリーンにするフルスクリーンオプションを追加しました。
■SmartBannerKillerオプション
こいつを殺せます。
■iOS 6ネイティブのオーバーレイボタンを縦画面でも表示させる
■このオーバーレイボタンに長押しジェスチャー
こいつを縦画面でも表示させます+何故か標準では長押ししても履歴が出ないので、出るようにしました。
■L/R始まりのジェスチャーの安定性を向上
時にジェスチャーが効かない事をなくしました。■4.2でもインストール可に。
■いくつか不要と思うアクションを廃止
New tweak "InfinityTask"
InfinityTask
debut on Cydia Store!
This new tweak feature is...
OpenTabBackground++
background task to Safari and Chrome.Add to ReadingList
background task to SpringBoard for iOS 6+.■Infinite bgtask and change idle sleep behavior.
First, this is iOS original task completion and idle sleep behavior mechanism since iOS 4.

Then below image is InfinityTask
tweaked version of one.

If you lock the device then after 15s, iOS go idle sleep
mode for battery life(super power saving mode). Idle sleep mode stoped most HW and SW feature also TCP connection. But many background task required network connection; So system prevent idle sleep mode for background task during it running.
Although iOS restrict 600sec for battery. InfinityTask
unlock that mechanism! You can enable infinite background task one by one apps, that app's background task can prevent your selected time have passed after locking the device. I recommend enable to network connection not required bgtask type apps.
■Add OpenTabBackground++
background task to Safari and Chrome.
Added new background task for Safari and Chrome monitoring clipboard to open url as new tab in background.
■Add Add to ReadingList
background task to SpringBoard for iOS 6+.
Said OpenTabBackground++
is background task, so that app must running background. This feature isn't require Safari running in background. When you copy URL to clipboard, automatically add to ReadingList that URL.
Mac上でiOSバイナリをClassDump
「あのバージョンのバイナリ(SpringBoardとか)をClassDumpしたいけど稼働してる実機がないなぁ」って時の方法。
- vfdecrypt(Intel Mac) をDL。chmod +xして/usr/local/binにでも突っ込むといいでしょう。
- DumpしたいバージョンのipswをDL。
- ipswをunzip
mkdir dmg; unzip hogehoge.ipsw -d dmg; cd dmg
- 対象のVFDecrypt keyを調べる。Root Filesystemのやつね。
vfdecrypt -i hogehoge.dmg -k 対象のkey -o output.dmg
- output.dmgをマウントしてバイナリをコピる。
- class-dumpする。
以上。
Teratermのアノ挙動をvimに!
この記事はVim Advent Calendar 2012の61日目の記事です。
60日目は@KSuzukiiiさんの「はじめての unite source(unite-tig)」でした。
最近仕事で使うWindowsでもgvim(kaoriyaさん版)を使用しだしたのですが、コピペまわりで四苦八苦したのでそのあたりの事を書きます。
Windows gvimでのコピペ事情
Windowsのgvimですが、Windows標準の<C-c>
や<C-v>
でのコピペが初期設定ではできません。
これを実現するにはsource $VIMRUNTIME/mswin.vim
を書いてvimrcで有効にすればできるようになります!が、行選択ビジュアルモード<S-v>
時に<C-f>
や<C-b>
で画面移動すると選択が外れるバグがあります。
これが結構使う動作のため、泣く泣く無効化させてクリップボードの貼り付けは右クリックから行なっていました。
ある日気づいた!
gvimで右クリックするといくつかのメニューが出てきますが、クリップボードからの貼り付けにしか使用していない事に気づきました。唐突ですが皆さんはsshクライアントは何を使用していますか?私はMacではTerminal.appでWindowsではTeratermを使っています。
このTeratermのデフォルト設定に以下の2つの機能があります。
- 選択した文字列を自動でクリップボードに保存
- 右クリックするとクリップボードの文字列を挿入
この2つの機能をなかなか気に入っていまして、右クリックを貼り付けにしか使用していないならTeratermのこの挙動をVimにも設定したところなかなか便利!
vimrcに追加!
まずは「選択すると自動でクリップボードに文字列を保存する」設定から。下記の設定でビジュアルモードで選択すると自動でクリップボードに保存されます。(+clipboardでコンパイルされたvimである必要があります)
" GUI set guioptions+=a " CUI "set clipboard+=autoselect
次に「右クリックでクリップボードの文字列を挿入」ですが、ノーマルモードとインサートモードの両方でできるようにしました。こちらも*レジスタを利用するのでclipboardが有効なvimが必要です。
nnoremap <RightMouse> "*p inoremap <RightMouse> <C-r><C-o>*
完成ッ!
上記の設定でTeraterm風のキーバインドのVimを得られました。エクセルやらでコピーして右クリックでVimに貼り付けッ!今のところこの設定で快適に作業できています。このカスタマイズ性の高さがVimの醍醐味ですね。
明日の62日目は2回目の@thincaさんです。楽しみです。
自動retainされないNSMutableSet
addObjectしてもretainされないNSMutableSetを作る。使い所はグローバル変数のstatic NSMutableSet *でこれを使って特定クラスのオブジェクトを詰め込んでいって、あるタイミングで全インスタンスに対して何か処理をする為。retainさせないのはreleaseタイミングはデフォルトのままにするため。まぁaddObjectしたらすぐにreleaseするのと大差ないんだけどね(その場合もSEGVには注意しないといけない)。
CFSetCallBacks assignCallbacks = kCFTypeSetCallBacks; assignCallbacks.retain = NULL; assignCallbacks.release = NULL; NSMutableSet *assignSet = (NSMutableSet *)CFSetCreateMutable(kCFAllocatorDefault, 0, &assignCallbacks);
これで[assignSet addObject:obj];
してもobjのretainCountは増えない。解放されたオブジェクトを触るとSEGVになるので、以下のようにaddするオブジェクトのクラスにおけるdeallocの中で外す。
- (void)dealloc { if ([assignSet containsObject:self]) [assignSet removeObject:self]; [super dealloc]; // %orig; }上記のようにdeallocいじらないといけないので、単一のクラスのオブジェクトを詰め込む場合以外ぐらいに留めておくのがよさそう。
参考 http://decafish.blog.so-net.ne.jp/2010-10-27-1