iOS: Facebook Comments Plugin mobile continue de recharger

Récemment, j'ai essayé d'intégrer Facebook Social Plugins dans un UIWebView personnalisé dans iOS pour commenter une page Web. J'ai ajouté le button J'aime ainsi que le plugin Commentaires. Voici le code HTML que je charge dans la vue Web:

<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> 

La première implémentation de lundi a été réussie sur 4 plates-forms, à la fois les simulateurs (iOS 4 et iOS 5), iPhone 3G iOS4 et iPhone 4 iOS 5. Mardi, j'ai continué à développer cela et je me suis retrouvé avec mon UIWebView personnalisé les trois premiers. Mais sur l'iPhone 4 (iOS 5), la vue Web continuait de recharger la même page encore et encore, ce qui faisait que la boîte de commentaires ne s'affichait jamais. Cette URL est la suivante:

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% 26domaine% 3Dwww.heretheweb.com% 26relation% 3Dparent.parent & href = http% 3A% 2F% 2Fwww.heretheweb.com & locale = en_US & mobile = true & numposts = 5 & sdk = joey & width = 470

Je ne sais pas ce que je fais vraiment mal, j'ai nettoyé les methods de délégué uiWebView, j'ai vérifié avec les points d'arrêt TOUTES les methods que je pourrais replace. Rien … La page Web est chargée au début, puis elle boucle en essayant de charger l'URL ci-dessus …

Il y a un bug dans le plugin de commentaires facebook qui provoque une boucle de chargement infinie lorsque le plugin de commentaires est en train d'être chargé sur des périphériques compatibles Retina.

Il y a une ligne dans l'un des scripts fb js qui va comme suit:

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

Donc, si vous accédez à la page sur un appareil avec un écran haute densité, vous êtes condamné.

J'ai signalé le problème ici

Je suis venu avec un hack sale pour le réparer mais réfléchir à deux fois avant de l'utiliser, il pourrait cesser de travailler à tout moment.

Notez que cette approche ne fonctionne que lorsque vous intégrez le plugin dans UIWebView, si vous avez un problème lorsque vous accédez à une page dans Safari, il n'y a pas d'autre choix que d'attendre une solution de facebook.

Mon idée était de "réparer" le code js à la volée car il est chargé par un UIWebView.

Pour traiter les requêtes à la volée, j'ai créé ma propre implémentation de NSURLProtocol:

 <FBCommentsFixingURLProtocol.h> #import <Foundation/Foundation.h> @interface FBCommentsFixingURLProtocol : NSURLProtocol @end <FBCommentsFixingURLProtocol.m> #import "FBCommentsFixingURLProtocol.h" static NSSsortingng *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 isEqualToSsortingng:@"https"] || [request.URL.scheme isEqualToSsortingng:@"http"]) && [request.URL.absoluteSsortingng rangeOfSsortingng:@"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 { NSSsortingng *dataAsSsortingng = [[NSSsortingng alloc] initWithData:data encoding:NSUTF8SsortingngEncoding]; //Just modify the script to prevent it from execution on Retina devices. //window.devicePixelRatio = 2 for the Retina Display NSSsortingng* modified = [dataAsSsortingng ssortingngByReplacingOccurrencesOfSsortingng:@"if(window.devicePixelRatio>1)document.location.reload();" withSsortingng:@""]; NSData* dataMod=[modified dataUsingEncoding:NSUTF8SsortingngEncoding]; [[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 

Et puis je l'ai enregistré dans le délégué de l'application didFinishLaunchingWithOptions:

 [NSURLProtocol registerClass:[FBCommentsFixingURLProtocol class]]; 

Je suis conscient que c'est un bidouillage sale mais ça marche quand même.

Ok … résolu. Pour une raison étrange et étrange, parfois lors du chargement de la partie web de commentaires SEULEMENT dans l'iPhone 4 (pas simulateur, iPhone 3G ou iPad 2) il essaie de recharger une fois et encore (l'en-tête Cache-Control est réglé sur max-age = 0 , donc ça continue de forcer le rechargement)

La solution consistait à vérifier UIWebViewNavigationType, si elle est égale à UIWebViewNavigationTypeReload, shouldStartLoadWithRequest: renvoie NO.

C'était VRAIMENT difficile ¬¬

J'ai ce même problème sous safari / ios mobile, sur une application web développée sur sencha touch 1, elle fonctionne sous d'autres browsers et SO, mais sur ce, elle continue à charger et charger. Je ne peux pas find l'indice.

Le code ci-dessous fonctionne bien pour moi

 UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 300, 400)]; NSSsortingng *html = @"<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 = \"https://connect.facebook.net/en_GB/sdk.js#xfbml=1&version=v2.5\";fjs.parentNode.insertBefore(js, fjs);}(document, 'script', 'facebook-jssdk'));</script><div class=\"fb-comments\" data-href=\"URL_OF_YOUR_PAGE\" data-numposts=\"5\"></div>"; [webView loadHTMLSsortingng:html baseURL:[NSURL URLWithSsortingng:@"https://facebook.com"]]; [self.view addSubview:webView];