なんでもいいから書くブログ。iPhoneアプリやAndroidアプリといったスマートフォンアプリを開発していこうと考えてはいるが、はたしてどこまでできるか、、とにかく記録していこうと思い書いているブログである。有益な情報はあるかもしれないし、ないかもしれない。
iPhoneアプリ「Best Bowling」の無料お試し版である「Best Bowling Free」を申請していたのだが、残念ながら Reject されてしまった。。
指摘事項と思われる箇所を修正して、本日、再度申請したので、レビューされるのが、約1週間後、、だから、10日以内にはリリースされるでしょう。(また Rejectされるかもしれないが。)
Reject理由は、
... because it is a feature-limited version. Any reference to trial needs to be removed from the metadata.
トライアルのどんな参照も取り除けと。。
うーん、いまいいちわからん。
フルバージョンでしか使えない機能を参照している箇所を取り除けってことかな??
【追記】
本当のReject理由 は紹介文で、「お試し版」のような表記は取り除いてねってことでした。
下の対応は全く無意味でした。(2回目のリジェクトも同じ内容だったので、
問い合わせたところ判明。)紹介文を直したらすぐにリリースされた。
よく読めば、from the metadata. って書いてあるし。。
他にも、「新しいバイナリは必要ないよ」てきなことが。。。英語力ねぇなぁ。。
------------------
たしかに、フルバージョンでは「バックアップ/復元」で両方できるが、
無料版は「バックアップ/復元」としていて、復元はできないよーと書いている。
これかな。とりあえず、復元機能は無料版にはないので、この箇所の文言を修正。
あと、ヘルプもフルバージョンのそのままだから、これもあやしいのでヘルプ自体を削除。
なんか「無料版」「お試し版」って表記は全面にだしては行けないらしい。。
でも、タイトルにFree ってつけちゃったし、Freeとしている他のアプリもいっぱいあるのでここはそのままいってみよう。
Rejectされると、1週間以上リリースが遅れる。。新規と再申請と別々の順番にしてほしいものだ。
だって修正なんてすぐ終わるのに、レビュー待ちで1週間。。しょうがないか。
指摘事項と思われる箇所を修正して、本日、再度申請したので、レビューされるのが、約1週間後、、だから、10日以内にはリリースされるでしょう。(また Rejectされるかもしれないが。)
Reject理由は、
... because it is a feature-limited version. Any reference to trial needs to be removed from the metadata.
トライアルのどんな参照も取り除けと。。
うーん、いまいいちわからん。
フルバージョンでしか使えない機能を参照している箇所を取り除けってことかな??
【追記】
本当のReject理由 は紹介文で、「お試し版」のような表記は取り除いてねってことでした。
下の対応は全く無意味でした。(2回目のリジェクトも同じ内容だったので、
問い合わせたところ判明。)紹介文を直したらすぐにリリースされた。
よく読めば、from the metadata. って書いてあるし。。
他にも、「新しいバイナリは必要ないよ」てきなことが。。。英語力ねぇなぁ。。
------------------
たしかに、フルバージョンでは「バックアップ/復元」で両方できるが、
無料版は「バックアップ/復元」としていて、復元はできないよーと書いている。
これかな。とりあえず、復元機能は無料版にはないので、この箇所の文言を修正。
あと、ヘルプもフルバージョンのそのままだから、これもあやしいのでヘルプ自体を削除。
なんか「無料版」「お試し版」って表記は全面にだしては行けないらしい。。
でも、タイトルにFree ってつけちゃったし、Freeとしている他のアプリもいっぱいあるのでここはそのままいってみよう。
Rejectされると、1週間以上リリースが遅れる。。新規と再申請と別々の順番にしてほしいものだ。
だって修正なんてすぐ終わるのに、レビュー待ちで1週間。。しょうがないか。
PR
ようやく、記念すべき第1作目のiPhoneアプリがAppStoreにリリースされた。
(すでに1週間経ってしまったが。。)
「Best Bowling」ボウリングのスコアを管理するアプリだ。
AppStore へ
ついでに、ホームページも作った。ここ
AppStoreに表示されたときは、すごく嬉しかった。
なんせ、自分の作ったアプリが世界に出回るのだから(このアプリは日本と英語圏のみ)。
まぁひどいレビューが書かれたら、へこむだろうなぁ。
完成まで3ヶ月ちょっと。申請で1度リジェクトされたので、リリースまで2週間と少しかかった。
(リジェクト理由は、wi-fi接続を自宅の環境でしか試せなかったので、
環境によってはIPアドレスが取得できなかったらしく、null表示されてしまい、
この表示ではユーザが混乱するからダメとのこと。再現はできなかったのだが、
IPアドレスの取得方法を変更し、取得できないときは、この機能は使えないよーてきな
表示にしたら、無事通過した。)
開発期間は思ったより長くなってしまったかな(C言語は学生時代に勉強した程度で、Objective-Cは初心者、Macも初めて使ったので、まぁ上出来か。。)
リリースから1週間たったが、少しでも売れているので嬉しいかぎり。毎日、ダウンロード数を見るのが楽しみ。
無料お試し版と第2作目が近日リリースされるので、非常に楽しみだ!
第2作目は3週間くらいで完成したので(規模は違うけど)、確実にできるようになってきている、俺。
1ヶ月に1つペースでリリースしていきたい。
(すでに1週間経ってしまったが。。)
「Best Bowling」ボウリングのスコアを管理するアプリだ。
AppStore へ
ついでに、ホームページも作った。ここ
AppStoreに表示されたときは、すごく嬉しかった。
なんせ、自分の作ったアプリが世界に出回るのだから(このアプリは日本と英語圏のみ)。
まぁひどいレビューが書かれたら、へこむだろうなぁ。
完成まで3ヶ月ちょっと。申請で1度リジェクトされたので、リリースまで2週間と少しかかった。
(リジェクト理由は、wi-fi接続を自宅の環境でしか試せなかったので、
環境によってはIPアドレスが取得できなかったらしく、null表示されてしまい、
この表示ではユーザが混乱するからダメとのこと。再現はできなかったのだが、
IPアドレスの取得方法を変更し、取得できないときは、この機能は使えないよーてきな
表示にしたら、無事通過した。)
開発期間は思ったより長くなってしまったかな(C言語は学生時代に勉強した程度で、Objective-Cは初心者、Macも初めて使ったので、まぁ上出来か。。)
リリースから1週間たったが、少しでも売れているので嬉しいかぎり。毎日、ダウンロード数を見るのが楽しみ。
無料お試し版と第2作目が近日リリースされるので、非常に楽しみだ!
第2作目は3週間くらいで完成したので(規模は違うけど)、確実にできるようになってきている、俺。
1ヶ月に1つペースでリリースしていきたい。
iPhone開発ネタ。
UIImagePickerController を使用して、写真を撮れるようにしたのだが、(実機の動作確認で)メモリ警告が発生して落ちまくった。。
それまで、メモリ警告は特に意識していなかったが、UIImagePickerController はメモリをいっぱい使うのだろう。(あと、iOS4にしてからマルチタスクなのでアプリ残骸が多々あるせいでもある。。きっと。)
まずハマったのが、なぜ落ちるのか。当然、既に存在しないアドレスにアクセスしてるからだろうが、どこだ??
地道にコールスタックでどこまで処理が呼ばれているか確認していき、ようやく発見。
これは単純なミスだった。release し過ぎて、dealloc でコケていただけ。
次に、カメラ起動後、メモリ警告のせいで、ビューが初期化されてしまい、設定していた値が初期値に戻ってしまう問題。
考えた対処方法は、didReceiveMemoryWarning で値をファイルに書き込んでおき、
viewDidLoadでその一時ファイルがあれば、その値を設定するという方法。
で、値を保存しようと思ってdidReceiveMemoryWarning で拾っても、あれ、、すでにnilじゃん。。
LOGを吐いて呼ばれる順番を確認したら、viewDidUnloadのあとにdidReceiveMemoryWarning が呼ばれている。うーん。viewDidUnloadですでに解放しているし。。
この辺がややこしや。実際は、上の階層のViewControllerのdidReceiveMemoryWarning で下の階層のviewDidUnload が呼ばれているようだった。(ナビゲーションコントローラね。)
しょうがないので、上の階層のViewControllerのdidReceiveMemoryWarning でviewControllersをぐるぐる参照しながら、目的のコントローラに設定されている値をファイルに書き込むように修正。
ふー。
新アプリを作り始めた段階だったので、メモリ警告も考慮して作っていこう。
前作は修正無理だな。まだ申請中だけど。まぁテスト時に一回もメモリ警告でていないので、大丈夫なんじゃないかなぁ。。写真撮影使っていないし。
メモリ警告のデバッグポイントは、AppDelegateのapplicationDidReceiveMemoryWarning
から、順に呼ばれるdidReceiveMemoryWarning と viewDidUnload を追っていくこと。
コールスタックでどこで落ちているかつきとめること。
まぁだいたいはあれだ、既に解放されてやんのってやつだ。
UIImagePickerController を使用して、写真を撮れるようにしたのだが、(実機の動作確認で)メモリ警告が発生して落ちまくった。。
それまで、メモリ警告は特に意識していなかったが、UIImagePickerController はメモリをいっぱい使うのだろう。(あと、iOS4にしてからマルチタスクなのでアプリ残骸が多々あるせいでもある。。きっと。)
まずハマったのが、なぜ落ちるのか。当然、既に存在しないアドレスにアクセスしてるからだろうが、どこだ??
地道にコールスタックでどこまで処理が呼ばれているか確認していき、ようやく発見。
これは単純なミスだった。release し過ぎて、dealloc でコケていただけ。
次に、カメラ起動後、メモリ警告のせいで、ビューが初期化されてしまい、設定していた値が初期値に戻ってしまう問題。
考えた対処方法は、didReceiveMemoryWarning で値をファイルに書き込んでおき、
viewDidLoadでその一時ファイルがあれば、その値を設定するという方法。
で、値を保存しようと思ってdidReceiveMemoryWarning で拾っても、あれ、、すでにnilじゃん。。
LOGを吐いて呼ばれる順番を確認したら、viewDidUnloadのあとにdidReceiveMemoryWarning が呼ばれている。うーん。viewDidUnloadですでに解放しているし。。
この辺がややこしや。実際は、上の階層のViewControllerのdidReceiveMemoryWarning で下の階層のviewDidUnload が呼ばれているようだった。(ナビゲーションコントローラね。)
しょうがないので、上の階層のViewControllerのdidReceiveMemoryWarning でviewControllersをぐるぐる参照しながら、目的のコントローラに設定されている値をファイルに書き込むように修正。
ふー。
新アプリを作り始めた段階だったので、メモリ警告も考慮して作っていこう。
前作は修正無理だな。まだ申請中だけど。まぁテスト時に一回もメモリ警告でていないので、大丈夫なんじゃないかなぁ。。写真撮影使っていないし。
メモリ警告のデバッグポイントは、AppDelegateのapplicationDidReceiveMemoryWarning
から、順に呼ばれるdidReceiveMemoryWarning と viewDidUnload を追っていくこと。
コールスタックでどこで落ちているかつきとめること。
まぁだいたいはあれだ、既に解放されてやんのってやつだ。
ログはNSLog を使って簡単に出力できるが、リリース構成では入れておきたくないもの。
いちいちコメントアウトするのも面倒だし。
そんなときマクロが記述できるCはいいよね。コンパイル時に置き換えてくれるので、無駄な処理も入らないし。
こんな感じ。(適当に共通のヘッダーファイルに書き込んでおけばオッケーだよね。)
#ifdef DEBUG
#define LOG(...) NSLog(__VA_ARGS__)
#else
#define LOG(...)
#endif
で、プロジェクトの情報から「ビルド」のプリプロセッサマクロに "DEBUG"と追加してやれば、
DEBUG とそうでない場合で、置き換えてくれる。
使い方は NSLog が LOG になっただけ。
LOG(@"hogehoge: %d", intValue);
のような感じで。
いちいちコメントアウトするのも面倒だし。
そんなときマクロが記述できるCはいいよね。コンパイル時に置き換えてくれるので、無駄な処理も入らないし。
こんな感じ。(適当に共通のヘッダーファイルに書き込んでおけばオッケーだよね。)
#ifdef DEBUG
#define LOG(...) NSLog(__VA_ARGS__)
#else
#define LOG(...)
#endif
で、プロジェクトの情報から「ビルド」のプリプロセッサマクロに "DEBUG"と追加してやれば、
DEBUG とそうでない場合で、置き換えてくれる。
使い方は NSLog が LOG になっただけ。
LOG(@"hogehoge: %d", intValue);
のような感じで。
久々のブログ更新。ようやく1つiPhoneアプリが完成したので、申請中。
勉強含め3ヶ月かかってしまった。
1、2ヶ月でできるかと思ったが、つまずくとピタっと開発が止まってしまう。1人だから。。
申請中にボーとしているわけにもいかないので、次の開発を始めます。
今回は、1つずつ整理しながら進めようかな。要領もわかったことだし。
まず、Interface Builder を使わない開発手法をやってみたいと思います。
1. "Resources" のMainWindow.xib を削除します。
2. XXX-Info.plist の "Main nib file base name" 項目を削除します。(XXXはプロジェクト名)
3. main.mを次のように修正します
int retVal = UIApplicationMain(argc, argv, nil, @"XXXDelegate");
4.XXXDelegate.mで次のようにコードを追加し、自前でwindowを作成します。
また、ルートビューとなるビューを window のサブウィンドウとして追加します。
(この例ではラベルビューとしています。)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
CGRect frameWindow = [[UIScreen mainScreen] bounds];
window = [[UIWindow alloc] initWithFrame:frameWindow];
//
CGRect rect = [window frame];
UILabel *label = [[UILabel alloc] initWithFrame:rect];
label.text = @"Hello, world!";
[window addSubview:label];
[label release];
// Override point for customization after application launch.
[window makeKeyAndVisible];
return YES;
}
よし、できた。
今仮にラベルにしているところを必要なViewにしてやればいいわけだ。
勉強含め3ヶ月かかってしまった。
1、2ヶ月でできるかと思ったが、つまずくとピタっと開発が止まってしまう。1人だから。。
申請中にボーとしているわけにもいかないので、次の開発を始めます。
今回は、1つずつ整理しながら進めようかな。要領もわかったことだし。
まず、Interface Builder を使わない開発手法をやってみたいと思います。
1. "Resources" のMainWindow.xib を削除します。
2. XXX-Info.plist の "Main nib file base name" 項目を削除します。(XXXはプロジェクト名)
3. main.mを次のように修正します
int retVal = UIApplicationMain(argc, argv, nil, @"XXXDelegate");
4.XXXDelegate.mで次のようにコードを追加し、自前でwindowを作成します。
また、ルートビューとなるビューを window のサブウィンドウとして追加します。
(この例ではラベルビューとしています。)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
CGRect frameWindow = [[UIScreen mainScreen] bounds];
window = [[UIWindow alloc] initWithFrame:frameWindow];
//
CGRect rect = [window frame];
UILabel *label = [[UILabel alloc] initWithFrame:rect];
label.text = @"Hello, world!";
[window addSubview:label];
[label release];
// Override point for customization after application launch.
[window makeKeyAndVisible];
return YES;
}
よし、できた。
今仮にラベルにしているところを必要なViewにしてやればいいわけだ。
久々にブログ更新だ。続けるのって大変だね。
iPhone開発ネタ。
NSUserDefaultsに値をセットするとファイルに書き出されるので、
アプリケーションを終了しても、データを維持できる。
しか〜し、すぐに保存されるわけではないらしい。
値を変更し、すぐにアプリを終了すると、保存されていないのだ。
けっこうハマッた。ブレークポイントでステップ実行すると確かに値が変わっている。
で、ステップ実行している分、時間が立っているので、保存してくれている。
ブレークポイントを外して、実行すると、保存されていない。
だから、何がおかしい?となったわけだ。
ようはキャッシュからファイルに書き出すタイミングがずれているので、NSUserDefaults のsynchronize メソッドで、同期してやればオッケー。ただし、毎回はやるなとドキュメントには書いてある(っぽい)。アプリ終了時にやるのがよいでしょう。
iPhone開発ネタ。
NSUserDefaultsに値をセットするとファイルに書き出されるので、
アプリケーションを終了しても、データを維持できる。
しか〜し、すぐに保存されるわけではないらしい。
値を変更し、すぐにアプリを終了すると、保存されていないのだ。
けっこうハマッた。ブレークポイントでステップ実行すると確かに値が変わっている。
で、ステップ実行している分、時間が立っているので、保存してくれている。
ブレークポイントを外して、実行すると、保存されていない。
だから、何がおかしい?となったわけだ。
ようはキャッシュからファイルに書き出すタイミングがずれているので、NSUserDefaults のsynchronize メソッドで、同期してやればオッケー。ただし、毎回はやるなとドキュメントには書いてある(っぽい)。アプリ終了時にやるのがよいでしょう。
iPhone3GS端末をiPhoneOS4にアップグレードしてみた。
まず気が付くのが壁紙。背景が壁紙になっている。壁紙なんだから、これが自然だ。
次にアプリをフォルダ分けできる。これでスッキリした。とっても便利。
はじめやり方がわからなかった。。設定とかにないし、どうやるんだ?
結局わからず、アップルのHPをみて解決。ブルブル状態でアイコンを重ねればオッケーね。
あとは、カメラにズームがついたこと。これでカメラアプリを使う必要もなくなる。
マルチタスクとかはアプリが対応していないとダメなのかな?試していない。
まぁのんびり使ってみよう。
あればいいなと思う機能、、写真をフォルダ分けしたい。iTunesで同期すればできるけど、PCとつなぐのは面倒だ。
なお、開発中のアプリは問題なくOS4で動く。当たり前か。
またiPod Touch16GB(第2世代?)を後輩から入手。テスト機として活躍中。
こちらはOS3.1.3、アップしたらテスト機の意味なしだからね。
ダウングレードできるのかなぁ??できないよなぁふつう。
まず気が付くのが壁紙。背景が壁紙になっている。壁紙なんだから、これが自然だ。
次にアプリをフォルダ分けできる。これでスッキリした。とっても便利。
はじめやり方がわからなかった。。設定とかにないし、どうやるんだ?
結局わからず、アップルのHPをみて解決。ブルブル状態でアイコンを重ねればオッケーね。
あとは、カメラにズームがついたこと。これでカメラアプリを使う必要もなくなる。
マルチタスクとかはアプリが対応していないとダメなのかな?試していない。
まぁのんびり使ってみよう。
あればいいなと思う機能、、写真をフォルダ分けしたい。iTunesで同期すればできるけど、PCとつなぐのは面倒だ。
なお、開発中のアプリは問題なくOS4で動く。当たり前か。
またiPod Touch16GB(第2世代?)を後輩から入手。テスト機として活躍中。
こちらはOS3.1.3、アップしたらテスト機の意味なしだからね。
ダウングレードできるのかなぁ??できないよなぁふつう。
iPhone開発
3桁以上の数字はカンマを入れたほうが見やすい。
次の方法で解決。1234567 → 1,234,567 になる。
NSNumber *number = [[NSNumber alloc] initWithInt:1234567];
NSNumberFormatter *fmt = [[NSNumberFormatter alloc] init];
[fmt setNumberStyle:NSNumberFormatterDecimalStyle];
[fmt setGroupingSeparator:@","];
[fmt setGroupingSize:3];
NSLog(@"%@", [fmt stringForObjectValue:number]);
[number release];
[fmt release];
(最初は setNumberStyle をしていなくて、ハマった。。)
なお、setNumberStyle、setGroupingSeparator、setGroupingSize、を使わなくても、
次の書式でもできる。
[fmt setPositiveFormat:@"#,##0"];
NumberStyleもいろいろあるので、自前で関数作らなくてもフォーマットしてくれるぞ。
3桁以上の数字はカンマを入れたほうが見やすい。
次の方法で解決。1234567 → 1,234,567 になる。
NSNumber *number = [[NSNumber alloc] initWithInt:1234567];
NSNumberFormatter *fmt = [[NSNumberFormatter alloc] init];
[fmt setNumberStyle:NSNumberFormatterDecimalStyle];
[fmt setGroupingSeparator:@","];
[fmt setGroupingSize:3];
NSLog(@"%@", [fmt stringForObjectValue:number]);
[number release];
[fmt release];
(最初は setNumberStyle をしていなくて、ハマった。。)
なお、setNumberStyle、setGroupingSeparator、setGroupingSize、を使わなくても、
次の書式でもできる。
[fmt setPositiveFormat:@"#,##0"];
NumberStyleもいろいろあるので、自前で関数作らなくてもフォーマットしてくれるぞ。
iPhone開発。
リストをテーブルで表示した際、特定の行を自動で選択(というより、その行に移動)してほしいケースがある。
例えば、日付毎にリストを表示していたら、画面が表示された時に、今日(もしくはその直近)を表示してくれたら、うれしい。
行番号を指定して、行を選択、移動するには、次のメソッドが使える。
- (void)selectRowAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated scrollPosition:(UITableViewScrollPosition)scrollPosition;
indexPathで行を指定しなくてはならないので、次のメソッドで行番号から生成しよう。
+ (NSIndexPath *)indexPathForRow:(NSUInteger)row inSection:(NSUInteger)section;
scrollPosition はスクロール位置だから、目的に応じて指定すべし。
例)tblViewというテーブルの 0セクションの10行目を真ん中位置へ アニメ効果なし
[tblView selectRowAtIndexPath: [NSIndexPath indexPathForRow:10 inSection:0] animated:NO scrollPosition:UITableViewScrollPositionMiddle];
こんな感じか。
リストをテーブルで表示した際、特定の行を自動で選択(というより、その行に移動)してほしいケースがある。
例えば、日付毎にリストを表示していたら、画面が表示された時に、今日(もしくはその直近)を表示してくれたら、うれしい。
行番号を指定して、行を選択、移動するには、次のメソッドが使える。
- (void)selectRowAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated scrollPosition:(UITableViewScrollPosition)scrollPosition;
indexPathで行を指定しなくてはならないので、次のメソッドで行番号から生成しよう。
+ (NSIndexPath *)indexPathForRow:(NSUInteger)row inSection:(NSUInteger)section;
scrollPosition はスクロール位置だから、目的に応じて指定すべし。
例)tblViewというテーブルの 0セクションの10行目を真ん中位置へ アニメ効果なし
[tblView selectRowAtIndexPath: [NSIndexPath indexPathForRow:10 inSection:0] animated:NO scrollPosition:UITableViewScrollPositionMiddle];
こんな感じか。
文字列内の特定の文字をある文字に置換する。よくあることだ。
SQLiteを使うアプリだが、Like句による検索をしたい。変数は?でバインドするので、
部分一致させるには、%hoge% のように%パーセントをつける必要がある。
そうすると、'%'の文字が使えなくなるので、今度はエスケープ文字を指定する必要がでてくる。
で、'%'を→'$%'のように置換したい。というのが本題。
SELECT * FROM tablename WHERE colname LIKE '%a$%1%' ESCAPE '$'
(colnameに a%1 を含む行を抽出するSQL)
文字列の置換はこんな感じ
NSMutableString *var = [[NSMutableString alloc]initWithString:@"a%1"];
[var replaceOccurrencesOfString:@"%" withString:@"$%" options:0 range:NSMakeRange(0, [var length])];
a%1 → a$%1 になる
(戻り値は置換回数なので、いらないから指定していない。optionもいらないので0)
バインド変数にかます為には、次のように、元の文字列を加工すればいいかな(エスケープ文字に$を指定した場合)
[var replaceOccurrencesOfString:@"$" withString:@"$$" options:0 range:NSMakeRange(0, [var length])];
[var replaceOccurrencesOfString:@"%" withString:@"$%" options:0 range:NSMakeRange(0, [var length])];
[var replaceOccurrencesOfString:@"_" withString:@"$_" options:0 range:NSMakeRange(0, [var length])];
[var insertString:@"%" atIndex:0];
[var appendString:@"%"];
$→$$, %→$%, _→$_ に置換して、両端に% をつける。これで部分一致の検索用に加工完了!
SQLiteを使うアプリだが、Like句による検索をしたい。変数は?でバインドするので、
部分一致させるには、%hoge% のように%パーセントをつける必要がある。
そうすると、'%'の文字が使えなくなるので、今度はエスケープ文字を指定する必要がでてくる。
で、'%'を→'$%'のように置換したい。というのが本題。
SELECT * FROM tablename WHERE colname LIKE '%a$%1%' ESCAPE '$'
(colnameに a%1 を含む行を抽出するSQL)
文字列の置換はこんな感じ
NSMutableString *var = [[NSMutableString alloc]initWithString:@"a%1"];
[var replaceOccurrencesOfString:@"%" withString:@"$%" options:0 range:NSMakeRange(0, [var length])];
a%1 → a$%1 になる
(戻り値は置換回数なので、いらないから指定していない。optionもいらないので0)
バインド変数にかます為には、次のように、元の文字列を加工すればいいかな(エスケープ文字に$を指定した場合)
[var replaceOccurrencesOfString:@"$" withString:@"$$" options:0 range:NSMakeRange(0, [var length])];
[var replaceOccurrencesOfString:@"%" withString:@"$%" options:0 range:NSMakeRange(0, [var length])];
[var replaceOccurrencesOfString:@"_" withString:@"$_" options:0 range:NSMakeRange(0, [var length])];
[var insertString:@"%" atIndex:0];
[var appendString:@"%"];
$→$$, %→$%, _→$_ に置換して、両端に% をつける。これで部分一致の検索用に加工完了!
YamaTatsuのiPhoneアプリ
iTunes Store でみる
Light Off Hot New
点いたライトを素早く消そう!
誰でも遊べるシンプルなゲームです
めいろであそぼう New
かわいいイラストのめいろ、ぬり絵もできる
子供向けの迷路あそびです。※iPad専用
運試し NEW
15連続の確率は0.0001%
操作は簡単 好きなパネルを選ぶだけ。どこまで進めるか運試し!
連打! まだまだ人気
16連射に挑戦
10秒間で何回ボタンを押せるか競うゲームです。
うちメモ ★大人気★
買い物中に 「まだあったかな?」 と思った経験 ありませんか? 「うちメモ」していれば大丈夫!!
Best Bowling
マイボウラーに大人気! ボウリングのスコアを管理するアプリです。
イメージ貯金
貯金はモチベーションが重要! 目標を設定して毎日楽しく貯金しよう!
Mine Escape
聴力は優れていますか? 音で機雷の位置を判断する新感覚のアクションゲーム!
Rank Checker
だって気になるじゃないですか、、 アプリ開発者必須! AppStoreのランキングをチェックツールです。
点いたライトを素早く消そう!
誰でも遊べるシンプルなゲームです
めいろであそぼう New
かわいいイラストのめいろ、ぬり絵もできる
子供向けの迷路あそびです。※iPad専用
運試し NEW
15連続の確率は0.0001%
操作は簡単 好きなパネルを選ぶだけ。どこまで進めるか運試し!
連打! まだまだ人気
16連射に挑戦
10秒間で何回ボタンを押せるか競うゲームです。
うちメモ ★大人気★
買い物中に 「まだあったかな?」 と思った経験 ありませんか? 「うちメモ」していれば大丈夫!!
Best Bowling
マイボウラーに大人気! ボウリングのスコアを管理するアプリです。
イメージ貯金
貯金はモチベーションが重要! 目標を設定して毎日楽しく貯金しよう!
Mine Escape
聴力は優れていますか? 音で機雷の位置を判断する新感覚のアクションゲーム!
Rank Checker
だって気になるじゃないですか、、 アプリ開発者必須! AppStoreのランキングをチェックツールです。
カレンダー
Twitter
プロフィール
最新記事
(05/22)
(04/30)
(03/16)
(03/07)
(02/08)
最新トラックバック
ブログ内検索
忍者アド
アクセス解析