0

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

Моя наивным предположение, что все, что я должен был сделать позвонить MPAdView.loadAd из фонового потока через dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ и обновление пользовательского интерфейса с dispatch_async(dispatch_get_main_queue() в методе adViewDidLoadAd делегата (который вызывается, когда объявление было нагружено MoPubSDK) ,

Но, как оказалось, это не сработало - метод делегата никогда не называется.

Я проследил проблему обратно в MoPubSDK, где NSURLConnection инициализируется через:

self.connection = [NSURLConnection connectionWithRequest:[self adRequestForURL:URL] delegate:self]; 

но NSURLConnectionDelegate методы (например, connectionDidFinishLoading) сами по себе никогда не вызывается, когда выполняется на фоне потока. Он работает, когда вызов выполняется в основном потоке.

Я заметил, что «текущий режим» [NSRunLoop currentRunLoop] «нет» «при выполнении в фоновом потоке, но« kCFRunLoopDefaultMode »при выполнении в основном потоке.

Документы NSURLConnection упомянуть

Для подключения к правильной работе цикл выполнения вызывающего потока должен работать в режиме по умолчанию цикла выполнения.

поэтому я попытался установить его в явном виде с помощью

[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[[NSDate alloc] initWithTimeIntervalSinceNow:60]]; 

, но это не имело никакого эффекта.

Итак, что мне нужно сделать для обеспечения вызова методов делегата NSURLConnection при инициализации соединения в фоновом потоке?

ответ

0

Ok, после нескольких часов поисков, я писал, что вопрос - и, конечно же, 15 минут спустя, я считаю, один из возможных вариантов решения по SO ...

self.connection = [[NSURLConnection alloc] initWithRequest:[self adRequestForURL:URL] delegate:self startImmediately:NO]; 

NSRunLoop* runLoop = [NSRunLoop currentRunLoop]; 
[self.connection scheduleInRunLoop:runLoop forMode:NSRunLoopCommonModes]; 
[self.connection start]; 
[runLoop run]; 

Это гарантирует, что делегат метода NSURLConnection является называется.

(У меня теперь есть другая проблема «Это может быть результатом вызова UIKit из вторичного потока». - но это не связано с исходным вопросом).

0

Возможно, вам следует планировать объект соединения в цикле основного запуска вместо текущего. Это позволит не только избежать планирования его работы в нефункциональном цикле выполнения (что такое heck?), Но также будет гарантировать, что при завершении запроса платформа объявлений не будет пытаться выполнять операции пользовательского интерфейса в неправильном потоке.