2011-02-25 2 views
1

J'ai un problème avec une application qui fonctionne parfaitement dans le simulateur, ainsi qu'un iPhone 4 et un iPhone 3GS physiques. L'application a été approuvée et est maintenant disponible sur l'App Store, mais la version de distribution 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.UIWebView agit différemment dans la version de l'application que la version de développement

Ceci est une application gratuite, mais est soutenu par la publicité locale. Lorsque l'application démarre (ou revient de l'arrière-plan), AppDelegate tente de télécharger du code HTML à partir de notre serveur publicitaire et, en cas de succès, présente un contrôleur 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 bouton. Cependant, la distribution construite à partir de l'App Store est différente. Lorsque le contrôleur de vue modale glisse, l'UIWebView ne se charge jamais. Rappelez-vous, je présente le contrôleur de vue SEULEMENT si capable de télécharger les données de l'annonce - sinon, la vue n'est jamais présentée. Heureusement, j'ai implémenté une minuterie dans le contrôleur d'affichage des annonces, ce qui a pour conséquence que la vue modale se ferme si WebViewDidFinishLoad ne se déclenche jamais (le minuteur est invalidé), au moins les utilisateurs d'applications ne sont pas trop ennuyés. Mais il est toujours moche d'avoir un contrôleur de vue vide qui glisse vers le haut et puis glisse loin pour apparemment aucune raison.

Voici les méthodes pertinentes du 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]; 

    NSString *baseURL = @"http://appdata.freewave-wifi.com/ad/"; 

    NSString *file = (IS_IPAD) ? @"ipad.php" : @"iphone.php"; 

    NSURL *adURL = [NSURL URLWithString:[baseURL stringByAppendingString: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."); 
} 

Par ailleurs, adData est définie 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 des builds de dev/release dans les simulateurs et les périphériques physiques - mais pas sur la construction de la distribution du magasin d'applications. J'ai même converti le NSData à un NSString et l'ai échangé avec NSLog() juste pour prouver que le HTML a été téléchargé avant de présenter l'AdView modalement.

[soupir ...]

EDIT 1: Dans le cas où mon message d'origine n'a pas été clair, la webViewDidFinishLoad ne sera jamais appelé dans la construction de la distribution (mais il en dev/release build).

EDIT 2: Aussi, juste avant d'appeler

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

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

+0

Comment IS_IPAD est-il défini? – occulus

+0

Je suis curieux à propos de celui-ci! J'ai téléchargé l'application et utilisé Wireshark pour renifler la connexion, mais je n'ai rien trouvé d'anormal au premier coup d'œil. Remarquez-vous que le titre UIWebView est défini sur Annulé avant qu'il ne ressorte de la vue? Où cela se passe-t-il? – Rog

+0

@occulus.'IS_IPAD' est défini comme suit:' #define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) ' –

Répondre

2

HOLY VACHE. Je le découvre. Ok, avant de dire ce que j'ai trouvé, j'ai voulu corriger ma propre formulation: 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 liste de fichiers 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é jusqu'à l'emplacement 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 distribution (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 avant que la mise à jour ne touche l'App Store (en supposant que je l'ai corrigée).

+0

App a été approuvé hier, et le problème est parti. Toujours vexé qu'un XIB manquant passait inaperçu tout ce temps. –

0

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

L'état docs for NSData en ce qui concerne initWithContentsOfURL "L'objet retourné peut être différent du destinataire d'origine."Donc, si elle était un autre objet, et qui était en fait autoreleased, considérer cette ligne dans votre code:

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

Ce ne sera pas ajouter un compte pour conserver adData - vous ne l'avez pas écrivez self.adData = ou similaire, donc, en gardant à l'esprit le scénario mentionné par lequel le NSData retourné a été libéré: votre méthode downloadAdData enveloppe son contenu dans un NSAutoreleasePool.Ceci est correct, mais cela pourrait entraîner la publication d'adData AVANT que presentAdModal soit appelé sur le threads principal ...

Dans presentAdModal vous vérifiez juste que adData n'est pas nul - mais il peut être non nul, et toujours h a été libéré de la mémoire à ce moment par votre NSAutoreleasePool - par conséquent, dans cette situation déclencherait le code "show web view", mais tenterait de charger un objet NSData qui avait é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 plan, mais la seule chose qui me saute dessus à ce stade.

MISE À JOUR:

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

Votre environnement de test (non App-Store construit) est de faire des demandes d'une certaine partie de l'Internet (à savoir votre bureau) qui a l'autorisation d'accéder au serveur Web contenant des publicités, en raison du blocage IP ou de toute autre configuration réseau, alors que les versions de votre App Store tentent d'accéder au serveur publicitaire à partir de certaines parties d'Internet interdites. Encore une fois, probablement pas le cas, mais mérite d'être mentionné.

+0

Il n'y a jamais eu de problème pour télécharger l'annonce HTML. Mais, pour tester votre première idée, j'ai converti l'adData en une chaîne et l'ai imprimée juste avant le 'if (adData)' dans 'presentAdModal', et le HTML était dans la console, mais l'UIWebView ne s'est pas chargé. Bonne réflexion, cependant! Ça valait le coup. –

Questions connexes