2014年10月22日水曜日

[iOS][Objective-C]NSDateの比較


どうも。

NSDate同士の比較。
これまで機会がありそうでなかったので、
どうやるんだろうかと...。

もうObjective-Cに関わって何年にもなって、
Swiftも出てきたというのに、
こういうことがちょいちょいありますw

ググれば即出てきますが、
こんなカンジです。

 
    NSDate *date1;
    NSDate *date2;

         (中略)

    NSComparisonResult result = [date compare:date2];
 
    switch (result) {
        case NSOrderedSame:
            // date1 == date2
            break;
        case NSOrderedAscending:
            // date1 < date2
            break;
        case NSOrderedDescending:
            // date1 > date2
            break;
    }


NSComparisonResultはNSNumberの比較でも使いますね。
NSNumberの比較というのも、
個人的にあまりしたことがありませんが...。

NSDateはNSDateFormatter使って、
文字列から生成することもあります。
元になる文字列が、
・フォーマット違反
・日付として無効な数値
になっているなどの場合はnilが返ってきます。
まぁ、ここまでは合点がいきます。

問題なのは、
その後のcompareです。
nilとのcompareは、
NSOrderedSameが返ってきてしまう...。

文字列が信用できるならいいんですが、
今回は文字列が人の手による入力で、
しかも事前にはチェックすらできない状況だったりします。

仕方ないので、
ある程度泥くさいチェックを書かなきゃいけませんね...。

それでは。
ちゃお☆

まこぴー。

2014年10月16日木曜日

[iOS][Objective-C]NSStringからの変換とチェック


どうも。

ひさびさにiOSというか、
Objective-C...。

Swiftの覚え書きはまだもうちょっと先になりそう。
まだまだ仕事ではObjective-Cが現役なんでw

今回は、NSStringです。
NSStringからintやBOOLに変換できます。
plistに設定値を書いといて、
読み出してプログラム内で使うときなんかに重宝します。

NSString *aStr = @"123";
int a = [aStr intValue];
とすると、
aには123が代入されます。

NSString *bStr = @"YES";
BOOL b = [bStr boolValue];
とすると、
bにはYESが代入されます。

まぁ、
当たり前の話ですw
当たり前に使っているが、
実は仕組みを詳しく知らなかったりする。

まずはint変換から。
数値でない文字列の場合どうなる?
Javaで同じようなことをするときは、
NumberFormatExceptionで受けたりしますが、
そういう作法が存在しない以上、
何かしらよしなに値を返してくれるはずです。

NSString *aStr = @"aaa";
int a = [aStr intValue];
とすると、
aには0が代入されます。

@"aaa" → 0
@"123aaa" → 123
@"aaa123" →  0
@"123aa4" → 123

なるほど、
数値文字で始まっていれば、
それが続く限りは数値として認識してくれるみたい。
@"123aaa"を許容しないような場合には、
自力でチェックが必要になります。

チェックについては、
ConvertCheckというカテゴリにして実装してみた。

[NSString+ConvertCheck.m]

- (BOOL)canBeConvertedToInt {
 
    return [self isEqualToString:
            [NSString stringWithFormat:@"%d", [self intValue]]];
}

他にもNSScannerとかNSCharacterSetや正規表現も使えますが、
先に文字列チェックしてしまうとintの範囲を超えたりを気にしたりしなかったり、
コードもちょっと複雑になるんで...。

あと、
これだと@"0000"や@"000009"みたいなのは変換不可になってしまいます。
今回書いたコードの用途上はそれを弾いちゃっていいので構いませんが、
その辺は仕様や実情に合わせたコードを書く必要があろうかと思います。

さて、
今度はBOOL変換。

試してみる前に、
NSString.hを覗いてみると、
こんなコメントがあります。
/*
Skips initial space characters (whitespaceSet), or optional -/+ sign followed by zeroes.
Returns YES on encountering one of "Y", "y", "T", "t", or a digit 1-9. 
It ignores any trailing characters.
*/

つまり、
@"Yeah"でもYESですw
まぁ、
BOOLに関しては、
厳密なチェックが必要なケースってほとんどないと思うんで、
チェックするメソッドも実装しません。
なるほどねーっていうだけですw


それでは。
ちゃお☆


まこぴー。