UIWebView действует по-разному в версии магазина приложений, чем версия dev - PullRequest
1 голос
/ 26 февраля 2011

У меня проблема с приложением, которое отлично работает в симуляторе, а также на физическом iPhone 4 и iPhone 3GS. Приложение было одобрено и теперь находится в App Store, но в сборке дистрибутива, загруженной из App Store, обнаружена ошибка, не замеченная в сборке dev / release.

Это бесплатное приложение, но поддерживается местной рекламой. Когда приложение запускается (или возвращается из фона), AppDelegate пытается загрузить некоторый HTML-код с нашего рекламного сервера и в случае успеха представляет контроллер модального представления с UIWebView и передает переменную NSData, содержащую HTML-код. В сборках разработки / выпуска это работает ОТЛИЧНО; приложение запускается, и через несколько секунд открывается вид и показывается реклама, которую можно закрыть кнопкой.

Однако сборка дистрибутива из App Store отличается. Когда модальный контроллер представления скользит вверх, UIWebView никогда не загружается. Помните, что я представляю контроллер представления ТОЛЬКО в том случае, если он может загружать рекламные данные, иначе представление никогда не отображается.

К счастью, я реализовал таймер в контроллере просмотра рекламы, который заставит модальное представление закрывать себя, если webViewDidFinishLoad никогда не срабатывает (когда таймер отключен), так что, по крайней мере, пользователи приложения не слишком раздражены. Но все-таки некрасиво, что пустой контроллер представления скользит вверх, а затем скользит без видимой причины.

Вот соответствующие методы в 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;

AdViewController просто содержит UIWebView, который загружается с

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

Опять же, все это работает ОТЛИЧНО, КАЖДЫЙ ВРЕМЯ со сборками dev / release в симуляторе и на физических устройствах - только не при сборке дистрибутива из магазина приложений. Я даже преобразовал NSData в NSString и отключил его с помощью NSLog (), чтобы доказать, что HTML был загружен до модального представления AdView.

[Вздох ...]

EDIT 1 : В случае, если мой оригинальный пост был неясен, webViewDidFinishLoad никогда не вызывается при сборке дистрибутива (но это происходит при сборке dev / release).

РЕДАКТИРОВАТЬ 2 : Кроме того, непосредственно перед тем, как я позвоню

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

в AdViewController я добавил временный NSLog(), преобразовал adData в NSString и зарегистрировал его в консоли, и HTML-код был там. Итак, UIWebView просто отказывается загружать NSData?

Ответы [ 2 ]

2 голосов
/ 26 февраля 2011

СВЯТАЯ КОРОВА.Я понял это.

Хорошо, прежде чем сказать, что я нашел, я действительно хотел исправить свою оригинальную формулировку: модальное объявление никогда не работало в симуляторе, но всегда на устройствах.Я знаю, что у симулятора могут быть свои причуды, поэтому я никогда не думал об этом, тем более что он всегда работал на устройствах.Я знаю, что это важная деталь, которая отсутствовала в этом обсуждении, но прошло несколько недель с тех пор, как я работал над этим проектом, и я забыл все об этом до сегодняшнего дня.

Теперь тогда ...Работая с вещами, я заметил, что AdView.xib не было в моем списке файлов проекта.Я развернул несколько папок, думая, что, возможно, он был случайно перетащен в одну из них, но его не было в списке.Это действительно меня озадачило - Xcode НИКОГДА не жаловался на отсутствующий ресурс (без предупреждений или ошибок; всегда идеальная компиляция).

Итак, я перешел на физическое местоположение и добавил AdView.xib впроект.Теперь модальное объявление отображается в симуляторе, который является первым.Я полагаю, что поскольку теперь приложение работает корректно в симуляторе, оно должно нормально работать в сборке дистрибутива (странная корреляция, но это все, что я получаю, пока мое обновление не появится в App Store).

Очевидно, яЯ буду отправлять обновление, поэтому я не приму мой собственный ответ до тех пор, пока обновление не появится в App Store (при условии, что я действительно исправил его).

0 голосов
/ 26 февраля 2011

Хорошо, это очень длинный выстрел, но, возможно, его стоит рассмотреть.

Документы для NSData утверждают, что в отношении initWithContentsOfURL "Возвращенный объект может отличаться от исходного получателя.«.Итак, если был другим объектом и объектом, который фактически был автоматически освобожден, рассмотрите следующую строку в вашем коде:

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

Это не добавит счет сохранения для adData -- вы не написали self.adData = или подобное.Итак, учитывая упомянутый сценарий, при котором возвращенные NSData были автоматически освобождены: ваш метод downloadAdData оборачивает свое содержимое в NSAutoreleasePool.Это правильная практика.Однако это может привести к освобождению adData ДО того, как presentAdModal вызывается в главном потоке.Итак ...

В presentAdModal вы просто проверяете, что adData не ноль - но он может быть не ноль и все же был освобожден из памяти в этот момент вашим NSAutoreleasePool - следовательно, вы в этом случае вызовет код "Показать веб-представление", но попытается загрузить объект NSData, который был удален.Который, вероятно, содержал бы полный мусор, следовательно, не успешный вызов «загружен веб-просмотр».

Как я уже сказал, длинный выстрел, но единственная вещь, которая выскакивает у меня в этот момент.

ОБНОВЛЕНИЕ:

Совершенно другая причина вашей проблемы может быть такой:

Ваша тестовая среда (то есть не из сборок App-Store) делает запросы от определенной частиИнтернет (т. е. ваш офис), у которого есть разрешение на доступ к веб-серверу, содержащему рекламу, либо из-за блокировки IP-адреса, либо из-за каких-либо настроек сети, в то время как в сборках вашего выпуска App Store предпринимаются попытки доступа к рекламному серверу из частей Интернета,запрещено.Снова, вероятно, не тот случай, но стоит упомянуть.

...