Be a Engineer.

社会人からWEBエンジニアになった人間の備忘録的勉強記録

iOSアプリの実装 - オレオレ証明書と戦う(webview、Alamofire)

iOSアプリを作る過程で、webview や Alamofire などを使って、Webサイトを表示させたり、APIを叩いたりすることは当たり前のようにあると思います。
ただ実装過程では、サーバーを立てて仮想的にHTTPS通信にするためにオレオレ証明書を作ってテストすることがままあると思うのですが、アプリ側の実装をそのままにしていると基本以下のようなエラーが表示されたりします。

2016-01-16 21:36:19.940 Webview[8069:1398803] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)

調べた記事内容とその参考記事を簡単にまとめました。
(あまり深いことはわかっていません、すみません。)

オレオレ証明書なサイトをWebviewで閲覧する時

  1. 新しく.swiftのファイルを作る
  2. 以下のコードを書くだけ
import Foundation

// NSURLRequestの非公開APIをオーバーライド
extension NSURLRequest {
    static func allowsAnyHTTPSCertificateForHost(host: String) -> Bool {
        return true
    }
}

(参考)
SwiftでHTTPS通信時に自己認証証明書の警告によるエラーを無視させる - Steel Dragon 14106

オレオレ証明書なサーバーとAlamofireを使って通信する時

Aalamofireを使う画面のviewDidLoad() などで、実際にAlamofireで通信させる前に、以下のコードを実行させるだけで良い。

let manager = Alamofire.Manager.sharedInstance
        
manager.delegate.sessionDidReceiveChallenge = { session, challenge in
    var disposition: NSURLSessionAuthChallengeDisposition = .PerformDefaultHandling
    var credential: NSURLCredential?

    if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
        disposition = NSURLSessionAuthChallengeDisposition.UseCredential
        credential = NSURLCredential(forTrust: challenge.protectionSpace.serverTrust!)
    } else {
        if challenge.previousFailureCount > 0 {
            disposition = .CancelAuthenticationChallenge
        } else {
            credential = manager.session.configuration.URLCredentialStorage?.defaultCredentialForProtectionSpace(challenge.protectionSpace)
            if credential != nil {
                disposition = .UseCredential
            }
        }
    }
    return (disposition, credential)
}

(参考)
[iOS]Alamofireでオレオレ証明書なSSLサーバへの接続を可能にする | 開発メモ

注意

非公開APIを書き換えているために、App Store提出時のReleaseビルドに含めてしまうとAppleの審査でリジェクトを食らう可能性が高いので、Releaseビルドには含めないように注意!