Help us understand the problem. What is going on with this article?

UIWebViewでhttpなURLにアクセスしようとしたら代わりにSFSafariViewControllerで開くようにする

More than 3 years have passed since last update.

ATS対応におけるホワイトリスト問題

iOS 9からATSが導入され、UIWebViewで http:// で始まるURLにアクセスしようとすると、以下のようなエラーメッセージが出てしまいサイトを表示することができなくなりました。

App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.

これに対応するには

  1. https:// も用意する
  2. httpしか用意されていないドメインをATSのホワイトリストに入れる
  3. ATSを無効にする

といった手が考えられるのですが、3はやりたくないし、管理下にない外部のサイトを表示している場合は1はできないし、消去法で2になるかと思います。

でも、外部のサイトがそこから先どんなURLへリンクしているかをすべて把握できるはずもなく、表示する可能性があるけどhttpしか用意されていないサイトをすべてリストアップできない、という問題があります。

解決策

まずATSは有効にします。その上で、UIWebViewで https:// 以外のURLにアクセスしようとした場合、エラーが出る前にUIWebViewDelegateの webView:shouldStartLoadWithRequest: で捕まえられるので、そこでSFSafariViewControllerを開いてしまいます。

以下のコードを実行して、GoogleからHTTPS対応していないサイト(例えば http://bricklife.com/ とか…)へ行ってみると挙動を確認できます。ここではiOS 9未満ではSafariを開くようにしましたが、この辺はアプリの要件に応じて工夫するとよいでしょう。

#import "ViewController.h"

#import <SafariServices/SafariServices.h>

@interface ViewController () <UIWebViewDelegate>

@property (weak, nonatomic) IBOutlet UIWebView *webView;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.webView.delegate = self;

    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://www.google.co.jp/"]];
    [self.webView loadRequest:request];
}

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
    NSURL *url = request.URL;
    NSLog(@"%@", url);

    if ([url.scheme isEqualToString:@"https"]) {
        return YES;
    }

    if ([SFSafariViewController class]) {
        SFSafariViewController *vc = [[SFSafariViewController alloc] initWithURL:url];
        [self presentViewController:vc animated:YES completion:nil];
    } else {
        [[UIApplication sharedApplication] openURL:url];
    }

    return NO;
}

@end

「表示UIをデザインしたい」「ネイティブ側と連携させたい」などの理由から自サイトはUIWebViewで表示したいけど、そこからリンクを貼られている外部のサイトは必ずしもUIWebViewで表示する必要がない場合、これが解決策としては簡単でいいかなと思います。特に既存アプリをiOS 9対応する場合、ネイティブ側もHTML側も実装をほとんど変えずに対応できますよ。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした