2011/05/29

NSURLConnectionで自己認証証明書回避について

アプリとサーバを組み合わせたシステムを開発するとき、
まだSSLの証明書が正式なものではないことがよくある。
この場合は自己認証証明書を使用するのだが、普通にNSURLConnectionとかでアクセスするとエラーで取得できない。
↓こんなエラー
Error Domain=NSURLErrorDomain Code=-1202

そのための回避方法は以下の通り
- (void) httpRequest:(NSURL*)url
{
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    [NSURLConnection connectionWithRequest:request delegate:self]; 
}

#pragma mark - NSURLConnectionDelegate
// 以下 SSL回避 ...
- (BOOL) connection:(NSURLConnection *)connection 
canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
    return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}
- (void)connection:(NSURLConnection *)connection 
didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]){
        [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] 
             forAuthenticationChallenge:challenge];
    }
    [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}

あと、よく見かける方法はNSURLRequestをオーバーライドする方法。
@implementation NSURLRequest(SSL)
+ (BOOL)allowsAnyHTTPSCertificateForHost:(NSString *)host {
    // do some filter based off of "host" here
    return YES;
}
@end
/*NSURLRequestをオーバーライドする方法は正直よく分からない。。
何故かうまくいかないんだよね(´・ω・`)*/

ちなみに、アプリ申請時にはこのあたりはコメントアウトするなりして無効にすること。

2011/05/14

Twitterやfacebookを簡単に導入できるShareKitが思いのほか便利な件

Twitterとかfacebookとか自分でいちいち作るのはけっこう面倒だったんだけども、
いいのがあるよと教えてもらったのがこのShareKit
「3行で簡単実装できる!」が売りらしいです。
実装はこんな感じ
SHKItem *item = [SHKItem URL:[NSURL URLWithString:@"http://getsharekit.com"]
                                                  title:@"ShareKit is Awesome!"];
SHKActionSheet *actionSheet = [SHKActionSheet actionSheetForItem:item];
[actionSheet showFromToolbar:navigationController.toolbar];
これでOK(設定ファイルでいろいろ設定する必要があるけど)
アクションシートでTwitterだったりfacebookだったりが選択できる。

でもこの場合だ必ずアクションシートが表示される。
まぁ、ソースを見ればわかるけど、
「このボタン押したらTwitterの投稿画面が表示したいよー」という場合は
SHKItem *item = [SHKItem URL:[NSURL URLWithString:@"http://getsharekit.com"]
                                                  title:@"ShareKit is Awesome!"];
[SHKTwitter performSelector:@selector(shareItem:) withObject:item];
とすればOK
facebookとかも同様にできる。。が、itemのところはtextで設定しないとデフォルトで表示させたい文字がはいらなかった。
また今度ちょっと時間がある時に見てみる。
あと、環境によっては
#import </usr/include/objc/objc-class.h>
でエラーがでる。
その場合
#import <objc/objc-class.h>
とするとか
#import <objc/runtime.h>
とするといいらしい。

※追記
一度表示した後閉じて、表示していたViewControllerを閉じて再度表示するとEXE_BAD_ACCESSになっていた。
どうやら「currentHelper」がリリースされていないのが原因らしい。
適当に「- (void)hideCurrentViewControllerAnimated:(BOOL)animated」の中でリリースするようにしてみたら
とりあえず、エラーはでなくなったけど。
元のコードを変えることなく、修正できないものか・・・うーん。
でも便利なようで不便なShareKit....

2011/04/30

Interface Builderを使わない方法

仕事上Interface Builder(以下IB)を使うとソースコードの管理がしにくくなるのとXcode4になってからは統合されたけど3までは別アプリになってたので開発しにくい・・という事でIBは使わない方針でした。けっこうIB使わないやり方って忘れやすいので覚え書き。


まず、ターゲット設定の"Main Interface"を消す




IBのファイル(拡張子が.xib)を削除

AppDelegate.hの修正
#import 
@class SampleViewController;
@interface SampleAppDelegate : NSObject  {
    UIWindow *window;
    UIViewController *viewController;
}
@property (nonatomic, retain) UIWindow *window;
@end

AppDelegate.mの修正
#import "SampleAppDelegate.h"
#import "SampleViewController.h"
@implementation SampleAppDelegate
@synthesize window;
- (BOOL)application:(UIApplication *)application 
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    viewController = [[SampleViewController alloc] init];
    window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
    [window addSubview:viewController.view];
    [window makeKeyAndVisible];
    return YES;
}
- (void)dealloc
{
    [window release];
    [viewController release];
    [super dealloc];
}
@end

main.mの修正
int retVal = UIApplicationMain(argc, argv, nil, @"SampleAppDelegate");

で、よし。

IBは楽だし便利だけど、私としてはがしがしコードを書きたいな。
そう思うのはIB全く使ってないからかもしれないけど、、ね。

2011/04/29

UIWebViewでURL取得

UIWebView内で表示しているURLやタイトルを取得したいときは・・・
NSString *subject = [_webView stringByEvaluatingJavaScriptFromString:@"document.title"];
NSString *currentURL = [_webView stringByEvaluatingJavaScriptFromString:@"document.URL"];

で、取得できる。
なんかほかにも色々取得できそうだな。

UIColorの色変換

UIColorであらかじめ用意されている色以外を使用する場合、ちょっとめんどくさい。
HTMLで使用するような指定はできないものかと調べたらすぐでてきた。
iPhone UIColorの色変換 from 袖触れ合うも多少の縁
上記サイトより引用
#define HEXCOLOR(c) [UIColor colorWithRed:((c>>16)&0xFF)/255.0 \
green:((c>>8)&0xFF)/255.0 \
blue:(c&0xFF)/255.0 \
alpha:1.0];
で、使うときは
UIColor *color = HEXCOLOR(0xff00ff);


これは便利!
Prefix.pchかなんかに定義しておくとどこでも使えて便利!

文字列の高さを取得する

//取得したい文字列
NSString *text = @"ここにテキストここにテキストここにテキストここにテキストここにテキスト";
//最大の表示領域のCGSize
CGSize maxSize = CGSizeMake(300.0, 1000.0);
//使用するUIFont
UIFont* font = [UIFont boldSystemFontOfSize:[UIFont labelFontSize]];

//文字列のCGSizeを取得する
CGSize size = [ text sizeWithFont: font
constrainedToSize: maxSize
lineBreakMode: UILineBreakModeCharacterWrap];

NSLog(@" width: %f , height : %f", size.width, size.height);

可変文字列をセルに全文表示したい時など、UILabelを使用する場合に便利。
UITextViewだとあまり気にはしないけど・・・UITextViewのスクロールを使いたくないときとかいいかな。