Как уже отмечали другие, невозможно быть абсолютно уверенным, что вы сможете отправить это, но есть способы помочь.
Как отмечает Кен, на практике вы получаете несколько секунд между "willTerminate" и принудительным завершением, поэтому обычно есть время сделать то, что вам нужно.
Проблема, с которой вы почти наверняка столкнетесь, связана с CocoaAsyncSocket. Когда вы получаете сообщение «willTerminate», вы находитесь в последнем цикле выполнения основного потока. Поэтому, если вы заблокируете основной поток, а CocoaAsyncSocket работает в основном потоке, он никогда не будет обработан. Насколько я помню, CocoaAsyncSocket не будет отправлять все данные до следующего цикла событий.
Поэтому один из подходов заключается в том, чтобы продолжать прокачивать цикл событий самостоятельно:
- (void)applicationWillTerminate:(UIApplication *)application
{
// ...Send your message with CocoaAsyncSocket...
while (! ...test to see if it sent...)
{
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
}
Я также рассмотрел вопрос о том, чтобы поместить эту работу в фоновый поток и позволить завершить основной поток, теоретически позволяя нам вернуться к Springboard, продолжая работу в течение нескольких секунд. Мне не сразу понятно, будет ли это работать правильно с помощью NSThread (которые отключены). Использование потоков POSIX (которые по умолчанию являются присоединяемыми) может работать, но, вероятно, позволяет обойти любые преимущества фонового потока. Во всяком случае, это что-то посмотреть, если полезно. В моих приложениях мы использовали подход «пост в следующий раз, когда мы запускаем», поскольку он всегда работает (даже в случае сбоя).