hachinoBlog

hachinobuのエンジニアライフ

NSDateで取得したGMT時間のままNSStringに変換する方法

背景

NSDateのdateメソッドで時刻を取得すると日本時間とは9時間差のGMT時間が返されることは知っていたのだがNSDateFormatterで取得した時間をNSString型に変換したらGMT時間でなく現地時間に変換されてしまっていたので調べた。

現象

NSDate *now = [NSDate date];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
NSString* dateString = [formatter stringFromDate:now];
NSLog(@"now:%@", now); //now:2014-04-04 11:16:16 +0000
NSLog(@"dateString:%@", dateString); //dateString:2014-04-04 20:16:16

GMT時間のままNSStringに変換されない。

解決方法

NSDate *now = [NSDate date];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
[formatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
NSString* dateString = [formatter stringFromDate:now];
NSLog(@"now:%@", now); //2014-04-04 11:22:48 +0000
NSLog(@"dateString:%@", dateString); //dateString:2014-04-04 11:22:48

このようにNSDateFormatterにタイムゾーンを設定してやることでGMT時間でNSStringに変換できる。 タイムゾーンはNSTimeZoneクラスのtimeZoneForSecondsFromGMTというGMT時間からの経過秒数を引数にもつメソッドに0を指定したタイムゾーンをセットしてあげる。

NSDictionaryの配列からNSPredicateを使って該当のNSDictionaryを抜き出す方法

背景

NSDictionaryの配列から該当のNSDictionaryを取得する際に今まではforループで1つ1つ判定して取得していたのだが速度が遅いのでNSPredicateを使って該当のNSDictionaryを取得する方法を調べた。

やり方

NSArrayのfilteredArrayUsingPredicateで取得したいNSDictionaryのKeyとValueを検索条件に入れて抽出できる。

NSDictionary *personDic1 = @{@"name": @"hachinobu", @"age": @28};
NSDictionary *personDic2 = @{@"name": @"suzuki", @"age": @40};
NSDictionary *personDic3 = @{@"name": @"honda", @"age": @27};
NSDictionary *personDic4 = @{@"name": @"samuragochi", @"age": @50};
NSArray *personArray = @[personDic1, personDic2, personDic3, personDic4];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == %@", @"name", @"hachinobu"];
NSDictionary *resultDic = [[personArray filteredArrayUsingPredicate:predicate] firstObject];
NSLog(@"results:%@", resultDic);

出力

results:{ age = 28; name = hachinobu; }

関連記事

配列からNSPredicate条件を使ってデータを抽出する方法

16進数のカラーコードをもとにUIColorを作成する

背景

カラーコードは大体16進数表記なのでiOSのUIcolorを作る際に16進数表記のカラーコードを10進数に変換してUIColorを作成したかったので調べた。

やり方

下記メソッドをUIColorのカテゴリに追加した。

+ (UIColor *)colorWithHexString:(NSString *)hex
{
    //先頭に#がついていた場合は#を削除
    if ([hex hasPrefix:@"#"]) {
        hex = [hex substringFromIndex:1];
    }

    unsigned int rgb[3];
    for (int i = 0; i < 3; i++) {
        NSString *component = [hex substringWithRange:NSMakeRange(i * 2, 2)];
        NSScanner *scanner = [NSScanner scannerWithString:component];
        [scanner scanHexInt:&rgb[i]];
    }
    return [self colorWithRed:rgb[0]/255.0 green:rgb[1]/255.0 blue:rgb[2]/255.0 alpha:1.0f];
}

これで16進数のカラーコードに対応したUIColorを取得することができる。

WebViewで表示しているHTMLのソースを表示する方法

背景

プログラム内で動的に生成したHTMLをWebViewで表示した際にデバッグ目的としてHTMLのソースを表示したくて調べた。

やり方

表示終わりのwebViewDidFinishLoad:メソッドあたりに下記コードを追加。

- (void)webViewDidFinishLoad:(UIWebView *)webView 
{
  //全文表示
  NSString *fullHtml = [webView stringByEvaluatingJavaScriptFromString:@"document.getElementsByTagName('html')[0].outerHTML"];
  NSLog(@"html:%@", fullHtml);

 
  //bodyタグ内のみ
  NSString *bodyHtml = [webView stringByEvaluatingJavaScriptFromString:@"document.body.innerHTML"];
  NSLog(@"html:%@", bodyHtml);
}

これでHTMLのソースを表示することができます。

WebViewでHTMLを読み込んだ際に画像が表示されない現象

背景

久しぶりにHTMLつくってWebViewで表示させたらHTML内で表示するはずの画像が表示されなかった。

問題のコード

  NSString* htmlFileName = @"sample.html";
  NSString *filePath = [[NSBundle mainBundle] pathForResource:filename ofType:nil];
  NSString *html = [NSString stringWithContentsOfFile:filepath encoding:NSUTF8StringEncoding error:NULL];
  [_webView loadHTMLString:html baseURL:nil];

原因

原因はloadHTMLString:の第二引数であるbaseURLをnilにしていたため。

ここには画像とかリソースのパスを指定してあげなくてはならない。

解決コード

  NSString* htmlFileName = @"sample.html";
  NSString *filePath = [[NSBundle mainBundle] pathForResource:filename ofType:nil];
  NSString *html = [NSString stringWithContentsOfFile:filepath encoding:NSUTF8StringEncoding error:NULL];
  NSURL *resourceURL = [[NSBundle mainBundle] URLForResource:@"sample" withExtension:@"html"];
  [_webView loadHTMLString:html baseURL:resourceURL];

初歩的なことなのだけれど忘れてしまっていたのでメモ。

UIImageのリサイズ

背景

画像の大きさをコードでリサイズしたかったのでUIImageのリサイズ方法を調べた。

やり方

//UIImageのリサイズメソッド
- (UIImage *)resizeImage:(UIImage *)image rect:(CGRect)rect
{
    UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0.0);
    [image drawInRect:rect];
    UIImage *resizedImage = UIGraphicsGetImageFromCurrentImageContext();
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
    UIGraphicsEndImageContext();
    return resizedImage;
}

//使う側
UIImage *image = [UIImage imageNamed:@"imageName"]; //100x100の画像とする
CGRect imageRect = (CGRect){ CGPointZero, CGSizeMake(50.0f, 50.0f) }; //50x50にリサイズ
image = [self resizeImage:image rect:imageRect];

UIGraphicsBeginImageContextWithOptions(サイズ, 透過有無(NOで透過有), スケール指定(0でデバイス固有));

※0でデバイス固有というのはRetinaディスプレイであれば100x100は200x200の解像度になるよ。という意味です。

Xcode5.1で今まで使っていたプラグインが使えなくなってしまった場合の対処方法(暫定版)

背景

Xcodeを5.1にしたら便利なプラグインが使えなくなって発狂した。

解決方法

~/Library/Application Support/Developer/Shared/Xcode/Plug-ins/[各プラグインフォルダ]/Contents/Info.plist を開いて DVTPlugInCompatibilityUUIDsキーの値に A2E4D43F-41F4-4FB9-BB94-7177011C9AED を追加してXcodeを再起動。

Info.plist

f:id:hachinobu:20140312102445p:plain

これで私の使用しているプラグイン達は再び動き始めました。

ちなみにA2E4D43F-41F4-4FB9-BB94-7177011C9AED という値はXcode5.1のDVTPlugInCompatibilityUUIDのこと。

どうやらXcode5.1でDVTPlugInCompatibilityUUIDに変更があったようです。

XcodeのDVTPlugInCompatibilityUUIDは

open /Applications/Xcode.app/Contents/Info.plist

で確認できます。

参考文献

stackoverflow