6

最近、Web ページにコメントするために、Facebook ソーシャル プラグインを iOS のカスタム UIWebView に統合しようとしています。いいねボタンとコメントプラグインを追加しました。Web ビューに読み込む HTML コードは次のとおりです。

  <html>
    <body>
<div id="fb-root"></div>
<script>(function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s); js.id = id;
js.src = "//connect.facebook.net/en_US/all.js#xfbml=1";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));</script>
<div class="fb-like" data-href="http://www.heretheweb.com" data-send="false" data-layout="button_count" data-width="240" data-show-faces="false"></div>
<div class="fb-comments" data-href="http://www.heretheweb.com" data-num-posts="5" data-width="470"></div>
<body>
</html>

月曜日の最初の実装は、シミュレーター (iOS 4 および iOS 5)、iPhone 3G iOS4 および iPhone 4 iOS 5 の 4 つのプラットフォームで成功しました。最初の 3 つ。しかし、iPhone 4 (iOS 5) では、Web ビューが同じ Web ページを何度もリロードし続け、コメント ボックスが表示されませんでした。その URL は次のとおりです。

https://m.facebook.com/plugins/comments.php?channel_url=http%3A%2F%2Fstatic.ak.facebook.com%2Fconnect%2Fxd_arbiter.php%3Fversion%3D4%23cb%3Df28c738848%26origin%3Dhttp% 253A%252F%252Fwww.heretheweb.com%252Ff3fdf142e8%26domain%3Dwww.heretheweb.com%26relation%3Dparent.parent&href=http%3A%2F%2Fwww.heretheweb.com&locale=en_US&mobile=true&numposts=5&sdk=joey&width=470

本当に何が間違っているのかわかりません。uiWebView デリゲート メソッドをクリーンアップし、オーバーライドできるすべてのメソッドをブレークポイントでチェックしました。何もありません...最初にWebページが読み込まれ、次に上記のURLを読み込もうとしてループします...

4

4 に答える 4

5

Facebook のコメント プラグインにはバグがあり、コメント プラグインが Retina 対応デバイスに読み込まれているときに無限の読み込みループが発生します。

fb js スクリプトの 1 つに、次のような行があります。

if(window.devicePixelRatio>1)document.location.reload()

そのため、高密度画面を備えたデバイスでページにアクセスしている場合、あなたは運命づけられています.

ここで問題を報告しました

私はそれを修正するための汚いハックを思いつきましたが、それを使用する前によく考えてください。いつでも機能しなくなる可能性があります。

このアプローチは、UIWebView にプラグインを埋め込んだ場合にのみ機能することに注意してください。サファリでページにアクセスしているときに問題が発生した場合は、Facebook からの修正を待つ以外に選択肢はありません。

私のアイデアは、UIWebView によってロードされているときに、その場で js コードを「修正」することでした。

その場でリクエストを処理するために、NSURLProtocol の独自の実装を作成しました。

<FBCommentsFixingURLProtocol.h>

#import <Foundation/Foundation.h>

@interface FBCommentsFixingURLProtocol : NSURLProtocol

@end

<FBCommentsFixingURLProtocol.m>
#import "FBCommentsFixingURLProtocol.h"


static NSString *FBCommentsFixingHeader = @"X-FBFix";

@interface FBCommentsFixingURLProtocol () 
@property (nonatomic, readwrite, strong) NSURLRequest *request;
@property (nonatomic, readwrite, strong) NSURLConnection *connection;
@property (nonatomic, readwrite, strong) NSURLResponse *response;

@end

@implementation FBCommentsFixingURLProtocol
@synthesize request = request_;
@synthesize connection = connection_;
@synthesize response = response_;


+ (BOOL)canInitWithRequest:(NSURLRequest *)request
{
    if (([request.URL.scheme isEqualToString:@"https"] || [request.URL.scheme     isEqualToString:@"http"]) && [request.URL.absoluteString rangeOfString:@"facebook.com/plugins/comments.php"].location != NSNotFound &&
    [request valueForHTTPHeaderField:FBCommentsFixingHeader] == nil)
{
    return YES;
}
return NO;
}

+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request
{
    return request;
}

- (id)initWithRequest:(NSURLRequest *)request
       cachedResponse:(NSCachedURLResponse *)cachedResponse
           client:(id <NSURLProtocolClient>)client
{
    // Modify request so we don't loop
    NSMutableURLRequest *myRequest = [request mutableCopy];
    [myRequest setValue:@"" forHTTPHeaderField:FBCommentsFixingHeader];
    self = [super initWithRequest:myRequest
               cachedResponse:cachedResponse
                       client:client];
    if (self)
    {
       [self setRequest:myRequest];
    }
    return self;
}


- (void)startLoading
{
    NSURLConnection *connection = [NSURLConnection connectionWithRequest:[self request]
                                                            delegate:self];
    [self setConnection:connection];

}

- (void)stopLoading
{
    [[self connection] cancel];
}


- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    NSString *dataAsString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
     //Just modify the script to prevent it from execution on Retina devices.
    //window.devicePixelRatio = 2 for the Retina Display
    NSString* modified =  [dataAsString stringByReplacingOccurrencesOfString:@"if(window.devicePixelRatio>1)document.location.reload();" withString:@""];
    NSData* dataMod=[modified dataUsingEncoding:NSUTF8StringEncoding];
    [[self client] URLProtocol:self didLoadData:dataMod];
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    [[self client] URLProtocol:self didFailWithError:error];
    [self setConnection:nil];
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    [self setResponse:response];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    [[self client] URLProtocolDidFinishLoading:self];
    [self setConnection:nil];
}


@end

そして、アプリのデリゲート didFinishLaunchingWithOptions に登録しました。

[NSURLProtocol registerClass:[FBCommentsFixingURLProtocol class]];

これが汚いハックであることは承知していますが、それでも機能します。

于 2012-08-01T13:07:30.250 に答える
1

わかりました...解決しました。いくつかの奇妙で奇妙な理由により、コメント Web パーツを iPhone 4 (シミュレーター、iPhone 3G、または iPad 2 ではない) でのみ読み込むと、何度もリロードしようとすることがあります (Cache-Control ヘッダーは max-age=0 に設定されています)。 、したがって、リロードを強制し続けます)

解決策は、UIWebViewNavigationType をチェックすることでした。UIWebViewNavigationTypeReload と等しい場合、shouldStartLoadWithRequest: は NO を返します。

本当にトリッキーでした ¬¬

于 2012-04-19T13:06:26.387 に答える
0

sencha touch 1で開発されたWebアプリでは、safari / ios mobileでも同じ問題があり、他のブラウザやSOでも動作しますが、これでは読み込みと読み込みが続けられます。手がかりが見つからない。

于 2012-07-13T17:38:07.113 に答える