UIWebView agit différemment dans la version de l'app store que la version dev

J'ai un problème avec une application qui fonctionne parfaitement dans le simulateur, ainsi qu'un iPhone 4 et un iPhone 3GS. L'application a été approuvée et est maintenant disponible sur l'App Store, mais la version de dissortingbution téléchargée depuis l'App Store présente un bogue qui n'a pas été détecté dans la version de développement / publication.

Ceci est une application gratuite, mais est pris en charge par la publicité locale. Lorsque l'application démarre (ou revient de l'arrière-plan), AppDelegate tente de download du code HTML à partir de notre server publicitaire et, en cas de succès, présente un controller de vue modale avec une UIWebView et transmet une variable NSData contenant le code HTML. Dans les versions de développement / publication, cela fonctionne PARFAITEMENT; l'application se lance, et après quelques secondes, une vue glisse et affiche l'annonce, qui peut être rejetée avec un button.

Cependant, la dissortingbution créée à partir de l'App Store est différente. Lorsque le controller de vue modale glisse, l'UIWebView ne se charge jamais. Rappelez-vous, je présente le controller de vue SEULEMENT si capable de download datatables de l'annonce – sinon, la vue n'est jamais présentée.

Heureusement, j'ai implémenté une timer dans le controller d'affichage des annonces, ce qui entraînera l'annulation de la vue modale si WebViewDidFinishLoad ne se triggers jamais (le minuteur étant invalidé), les users de l'application ne sont donc pas trop gênés. Mais il est toujours moche d'avoir un controller de vue vide qui glisse vers le haut et puis glisse loin pour apparemment aucune raison.

Voici les methods pertinentes dans AppDelegate:

- (void)launchAd { [NetworkActivity showFor:@"ad"]; if (!alreadyActive && [ServerCheck serverReachable:@"openx.freewave-wifi.com" hideAlert:YES]) { alreadyActive = YES; [self performSelectorInBackground:@selector(downloadAdData) withObject:nil]; } [NetworkActivity hideFor:@"ad"]; } - (void)downloadAdData { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSSsortingng *baseURL = @"http://appdata.freewave-wifi.com/ad/"; NSSsortingng *file = (IS_IPAD) ? @"ipad.php" : @"iphone.php"; NSURL *adURL = [NSURL URLWithSsortingng:[baseURL ssortingngByAppendingSsortingng:file]]; adData = [[NSData alloc] initWithContentsOfURL:adURL]; [self performSelectorOnMainThread:@selector(presentAdModal) withObject:nil waitUntilDone:NO]; [pool release]; } - (void)presentAdModal { if (adData) { AdViewController *adView = [[AdViewController alloc] initWithNibName:nil bundle:nil]; [adView setAdData:adData]; UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:adView]; [navController setModalPresentationStyle:UIModalPresentationFormSheet]; [navController setModalTransitionStyle:UIModalTransitionStyleCoverVertical]; [tabBarController presentModalViewController:navController animated:YES]; [navController release], navController = nil; [adView release], adView = nil; } else LogError(@"Not presenting ad; unable to create data object."); } 

D'ailleurs, adData est défini dans l'en-tête avec NSData *adData;

Le AdViewController contient simplement un UIWebView, qui est chargé avec

 [webView loadData:adData MIMEType:@"text/html" textEncodingName:@"utf-8" baseURL:nil]; 

Encore une fois, tout cela fonctionne PARFAITEMENT, CHAQUE FOIS avec dev / release construit dans les simulateurs et les dispositifs physiques – mais pas sur la construction de la dissortingbution à partir de l'App Store. J'ai même converti le NSData en NSSsortingng et je l'ai barrié avec NSLog () juste pour prouver que le HTML a été téléchargé avant de présenter l'AdView de manière modale.

[soupir…]

EDIT 1 : Dans le cas où mon article d'origine n'était pas clair, webViewDidFinishLoad n'est jamais appelé dans la construction de dissortingbution (mais dans la version de dev / release).

EDIT 2 : Aussi, juste avant d'appeler

 [webView loadData:adData MIMEType:@"text/html" textEncodingName:@"utf-8" baseURL:nil]; 

dans AdViewController, j'ai ajouté un NSLog() temporaire NSLog() et adData converti à NSSsortingng et l'ai connecté à la console, et le code HTML était là. Ainsi, l'UIWebView refuse simplement de charger le NSData?

SAINTE VACHE. Je le découvre.

D'accord, avant de dire ce que j'ai trouvé, j'ai voulu corriger ma propre formulation originale: la publicité modale n'a jamais fonctionné dans le simulateur, mais toujours sur les appareils. Je sais que le simulateur peut avoir ses bizarreries, donc je n'y ai jamais pensé, d'autant plus que ça fonctionnait toujours sur les appareils. Je sais que c'est un détail important qui manquait pour cette discussion, mais cela fait quelques semaines que j'ai travaillé sur ce projet, et j'avais oublié tout cela jusqu'à aujourd'hui.

Maintenant, alors … Tout en bricolant avec des choses, j'ai remarqué que AdView.xib n'était pas dans ma list de files de projet. J'ai développé quelques dossiers pensant peut-être qu'il a été accidentellement traîné dans l'un d'entre eux, mais il n'a pas été répertorié du tout. Cela m'a vraiment étonné, cependant – Xcode ne s'est jamais plaint d'une ressource manquante (pas d'avertissement ou d'erreur, toujours une compilation parfaite).

J'ai donc navigué vers l'location physique et ajouté AdView.xib dans le projet. Maintenant, l'annonce modale est affichée dans le simulateur, ce qui est une première. Je me dis que maintenant que l'application fonctionne correctement dans le simulateur, cela devrait fonctionner correctement dans la construction de la dissortingbution (corrélation étrange à faire, mais c'est tout ce que j'ai jusqu'à ce que ma mise à jour touche l'App Store).

Évidemment, je vais soumettre une mise à jour, donc je n'accepterai pas ma propre réponse tant que la mise à jour ne sera pas disponible sur l'App Store (en supposant que je l'ai corrigée).

Ok, c'est un tir extrêmement long, mais peut-être intéressant d'envisager.

Les documents pour NSData indiquent qu'en ce qui concerne initWithContentsOfURL "L'object returnné peut être différent du destinataire d'origine." Donc, s'il s'agissait d' un object différent, et qui était en fait auto-libéré, considérez cette ligne dans votre code:

 adData = [[NSData alloc] initWithContentsOfURL:adURL]; 

Cela n'appenda pas de count de retenue pour adData – vous n'avez pas écrit self.adData = ou similaire. Donc, en gardant à l'esprit le scénario mentionné par lequel le NSData returnné a été libéré: votre méthode downloadAdData enveloppe son contenu dans un NSAutoreleasePool. C'est une pratique correcte. Cependant, cela pourrait entraîner la publication d'adData AVANT que presentAdModal soit appelé sur le thread principal. Alors…

Dans presentAdModal vous vérifiez juste que adData n'est pas nul – mais il peut être non nul, et a toujours été désalloué de la memory à ce moment par votre NSAutoreleasePool – par conséquent, vous devriez dans ce cas triggersr le code "show web view" , mais essayez de charger un object NSData qui a été saccagé. Ce qui probablement contiendrait une poubelle complète, d'où l'absence d'appel "web view loaded" réussi.

Comme je l'ai dit, un long coup, mais la seule chose qui me saute dessus à ce stade.

METTRE À JOUR:

Une cause complètement différente de votre problème pourrait être ceci:

Votre environnement de test (c.-à-d. Non-App Store) effectue des requêtes à partir d'une certaine partie d'Internet (votre bureau) autorisée à accéder au server Web contenant des publicités, soit par blocage IP, soit par configuration réseau. vos versions de l'App Store tentent d'accéder au server de publicité à partir de parties d'Internet interdites. Encore une fois, probablement pas le cas, mais mérite d'être mentionné.