UIWebView在app store版本中的行为与开发版本不同

我有一个在模拟器中完美工作的应用程序的问题,以及物理iPhone 4和iPhone 3GS。 该应用程序已获批准,现在已在App Store中,但从App Store下载的发行版本具有dev / release版本中未显示的错误。

这是一个免费的应用程序,但由本地广告支持。 当应用程序启动(或从后台返回)时,AppDelegate会尝试从我们的广告服务器下载一些HTML,如果成功,则使用UIWebView呈现模式视图控制器,并传递包含HTML的NSDatavariables。 在开发/发布版本,这工作完美; 该应用程序启动,几秒钟后,一个视图向上滑动,并显示广告,这可以用一个button解散。

但是从App Store发布版本是不同的。 当模式视图控制器向上滑动时,UIWebView不会加载。 请记住,只有在能够下载广告数据的情况下,我才展示视图控制器 – 否则视图将永远不会呈现。

值得庆幸的是,我在广告视图控制器中实现了一个定时器,如果webViewDidFinishLoad从不触发(定时器失效),将导致模式视图自行closures,所以至less应用程序用户不会太恼火。 但有一个空的视图控制器向上滑动,然后滑动显然没有理由仍然是丑陋的。

以下是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."); } 

顺便说一句,adData在NSData *adData;标题中定义NSData *adData;

AdViewController只包含一个UIWebView,它被加载

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

同样,这一切都完美的工作,开发/发行每一次都build立在模拟器和物理设备 – 只是从应用程序商店的分布build设。 我甚至已经将NSData转换为NSString,并用NSLog()将其删除,以certificate在下载HTML之前模态地呈现AdView。

[叹…]

编辑1 :如果我原来的post不清楚, webViewDidFinishLoad永远不会在发布版本中调用(但它在开发/发行版本中)。

编辑2 :另外,就在我打电话之前

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

在AdViewController中,我添加了一个临时NSLog()并将adData转换为NSString并将其logging到控制台,并且HTML在那里。 所以,UIWebView只是拒绝加载NSData?

天啊。 我知道了。

好的,在我说出所发现的内容之前,我确实想纠正自己原来的措辞:模式广告从来没有在模拟器中工作过,但总是在设备上工作。 我知道模拟器可能有它的怪癖,所以我从来没有想过什么,特别是因为它始终在设备上工作。 我知道这是这个讨论中缺less的重要细节,但是自从我开始这个项目之后已经过去了几个星期,直到今天我都忘记了这一切。

现在,然后……在修补东西的同时,我注意到AdView.xib不在我的项目文件列表中。 我扩大了几个文件夹,可能是因为偶然地将其拖入了其中一个文件夹中,但却没有列出。 这真的让我困惑,虽然 – Xcode从来没有抱怨缺less资源(没有警告或错误;总是一个完美的编译)。

所以,我导航到物理位置,并将AdView.xib添加到项目中。 现在,模拟广告显示在模拟器中,这是第一个。 我认为,从现在的应用程序在模拟器中正常工作,它应该在分布构build(奇怪的相关性,但这是所有我得到,直到我的更新命中应用程序商店)工作正常。

显然,我会提交一个更新,所以我不会接受我自己的答案,直到更新命中App Store(假设我已经修复了它)。

好吧,这是一个非常长的镜头,但也许值得考虑。

关于initWithContentsOfURL的NSData文档声明:“返回的对象可能与原始接收者不同。 所以,如果它一个不同的对象,并且实际上是自动释放的,那么在代码中考虑这一行:

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

这不会为adData添加保留计数 – 您没有写self.adData =或类似的。 所以,要记住所提到的场景,即返回的NSData是自动发布的:你的方法downloadAdData把它的内容包装在一个NSAutoreleasePool中。 这是正确的做法。 但是,这可能会导致AdData在主线程上被调用之前被释放。 所以…

在现在的AdModal中,您只需检查adData是否为零 – 但不能为零,并且您的NSAutoreleasePool仍然从内存中释放 – 因此,您在这种情况下触发“显示Web视图”代码,但是试图加载一个已经被丢弃的NSData对象。 这可能会包含完整的垃圾,因此没有成功的“Web视图加载”调用。

正如我所说的那样,这是一个远射,但是在这一点上,这个东西突然跳出来了。

更新:

你的问题的一个完全不同的原因可能是这样的:

您的testing环境(即非App-Store构build)正在从互联网的某个部分(即您的办公室)发出请求,该部分有权访问包含广告的Web服务器(由于IP阻止或任何networking设置)您的App Store发布版本试图从禁止的互联网部分访问广告服务器。 再一次,可能不是这样,但值得一提的是。