FacebookSDK for iOSの簡単投稿クラスFBWebDialogsの画面が読み込まれない

iOSでFacebook SDKを使用して投稿するときに簡単に使えるクラスFBWebDialogsで、
画面が表示されない不具合がありましたので、その対応を共有します。
(2015/3/18現在のFacebook SDK for iOS v3.23.1 の環境です。)

#FBWebDialogsの画面が読み込まれない
FBWebDialogs -presentFeedDialogModallyWithSession...を実行すると、
FacebookSDKで用意されている投稿画面が表示されるはずが、
いつまで経っても読み込まれない状態になることがあります。

![FBWebDialogsが表示されない.png](https://qiita-image-store.s3.amazonaws.com/0/34488/bf77bf43-7823-d487-41a8-f0f55bb9d6a3.png)


※成功してるときは以下のように投稿画面が表示されます。

![FBWebDialogsの投稿画面.png](https://qiita-image-store.s3.amazonaws.com/0/34488/6c31e991-2fcf-bf9a-311c-006ecea0fde3.png)

#原因：UserAgentの変更
UIWebViewを開くときのUserAgentを独自のものにしたいときに、
NSUserDefaultを使用した以下の方法がよく使用されます。

```objc:UserAgentの変更

//UserAgent設定
NSDictionary *dictionary = @{@"UserAgent": @"設定したいUA"};
[[NSUserDefaults standardUserDefaults] registerDefaults:dictionary];

```

WebViewのUserAgentを変更するには簡単で楽な方法ですが、
これによってFBWebDialogsは読み込まれなくなります。

直接の原因はおそらくFBWebDialogsが内部でアクセスしているであろう、
https://m.facebook.com/dialog/
がUserAgentによる判定を行っているために弾かれているのでしょう。

#対策：UserAgent登録の削除
変更しているUserAgentの設定を削除すれば、正常に機能します。
FBWebDialogsを表示する直前でUserAgentの削除を行い、投稿完了後のhandlerの中で

```objc:UserAgentの削除

- (void)presentFBWebDialogs {
    // 投稿画面をWebViewで表示する前にUserAgentの設定を削除
    [self removeUserAgentSetting];

    // 投稿画面を表示
    [FBWebDialogs presentFeedDialogModallyWithSession:nil
                  parameters:nil
                  handler:^(FBWebDialogResult result, NSURL *resultURL, NSError *error) {
                      // 投稿後にUserAgentを再登録
                      [self resetUserAgentSetting];
                      if (error) {
                          NSLog(@"エラー: %@", error.description);
                      }
                  }];
}

// UserDefaultから@"UserAgent"の設定を削除
- (void)removeUserAgentSetting {
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    NSDictionary *registeredDefaults = [userDefaults volatileDomainForName:NSRegistrationDomain];
    if ([registeredDefaults objectForKey:@"UserAgent"] != nil) {
        NSMutableDictionary *mutableCopy = [NSMutableDictionary dictionaryWithDictionary:registeredDefaults];
        [mutableCopy removeObjectForKey:@"UserAgent"];
        [self replaceRegisteredDefaults:[mutableCopy copy]];
        [userDefaults setVolatileDomain:dictionary forName:NSRegistrationDomain];
    }
}

// UserDefaultに@"UserAgent"の設定を登録
- (void)resetUserAgentSetting {
    NSDictionary *dictionary = @{@"UserAgent":@"設定したいUA"};
    [[NSUserDefaults standardUserDefaults] registerDefaults:dictionary];
}

```

#対策２：UserAgentの変更方法の見直し
UIWebViewのUserAgentを変更する方法はNSUserDefaultを使用する以外にも可能です。

```objc
NSString *urlAddress = @"http://www.google.com";
NSURL *url = [NSURL URLWithString:urlAddress];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setValue:@"設定したいUserAgent" forHTTPHeaderField:@"User_Agent"];
[webView loadRequest:request];

```

#まとめ
自前で投稿画面を作らなくても投稿画面を表示できる簡単で便利なFBWebDialogsですが、
意外な落とし穴がありました。
エラーも出てくれなくて原因の調査に困りましたが、上記の対策を行えば快適なFacebookSDK開発が送れます。

#参考
（未解決なstackoverflow達。。）
・http://stackoverflow.com/questions/16236340/facebook-ios-sdk-3-5-modal-feed-dialog-loads-empty-in-iphone
・http://stackoverflow.com/questions/21870753/fbwebdialogs-presentdialogmodallywithsession-opening-blank-modal