Как получить описание ошибки при неудачном воспроизведении MPMoviePlayerController

Я хочу показать UIAlert, если проигрывание видео проинится. Итак, я зарегистрировал MPMoviePlayerPlaybackDidFinishNotification для моего Movie Player:

[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector (myMovieFinishedCallback:) имя: MPMoviePlayerPlaybackDidFinishNotification object: self.moviePlayer];

В моем myMovieFinishedCallback: я проверяю, является ли в словаре пользовательской информации объектом Object с именем error. На моем реальном устройстве я не получаю эту ошибку (без сетевой ошибки, ошибка 404 для файла). На iPhone Simulator я получаю сообщение об ошибке.

Как правильно проверить аргументы, когда я получаю MPMoviePlayerPlaybackDidFinishNotification?

Ответ 1

К сожалению, MPMoviePlayerController (вплоть до iOS 4.3) до сих пор не содержит подробной информации о проблемах из того, что доступно в документации. Он просто возвращает MPMovieFinishReasonPlaybackError в случае каких-либо проблем в UserInfo этого MPMoviePlayerPlaybackDidFinishNotification.

С iOS 4.3 мы наконец получили свойства errorLog и accessLog, содержащие расширенную и довольно полезную информацию. См. Справка MPMoviePlayerController.

В iOS 5.0 есть ключ error, который приходит с этим уведомлением также в строках устройства, а не только в симуляторе. Это error является экземпляром NSError и предоставляет очень полезную информацию. К сожалению, это не было зарегистрировано Apple, поэтому оно может измениться при любой выпуске iOS. Кроме того, похоже, что никаких пояснений по данным кодам ошибок нет. Например, HTTP-Status: 404 приведет к ошибке-код -1100 в пределах данного экземпляра ошибки. Однако это будет пример того, как правильно обрабатывать это уведомление.

[[NSNotificationCenter defaultCenter] addObserver:self 
                                         selector:@selector(handleMPMoviePlayerPlaybackDidFinish:)
                                            name:MPMoviePlayerPlaybackDidFinishNotification
                                          object:nil];

Это будет правильный обработчик уведомлений:

- (void)handleMPMoviePlayerPlaybackDidFinish:(NSNotification *)notification
{
    NSDictionary *notificationUserInfo = [notification userInfo];
    NSNumber *resultValue = [notificationUserInfo objectForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey];
    MPMovieFinishReason reason = [resultValue intValue];
    if (reason == MPMovieFinishReasonPlaybackError)
    {
        NSError *mediaPlayerError = [notificationUserInfo objectForKey:@"error"];
        if (mediaPlayerError) 
        {
            NSLog(@"playback failed with error description: %@", [mediaPlayerError localizedDescription]);
        }
        else
        {
            NSLog(@"playback failed without any given reason");
        }
    }
}

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

[[NSNotificationCenter defaultCenter] removeObserver:self
                                                name:MPMoviePlayerPlaybackDidFinishNotification
                                              object:nil];

Ответ 2

У меня была та же проблема. хотя я регистрировал функцию обратного вызова MPMoviePlayerLoadStateDidChangeNotification и получал ошибку из переменной userInfo, она не показывала ошибку. Я потратил много времени на поиск в форумах, и после игры с кодом я понял, в чем проблема.

Сначала вам нужно зарегистрировать функцию обратного вызова:

 // Register that the did finish notification (movie stopped)
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(myMovieFinishedCallback:) name:MPMoviePlayerPlaybackDidFinishNotification object:self.moviePlayer];

В функции MovieFinished callback вам необходимо:

NSDictionary *notice = [paramNotification userInfo];

if (notice != nil)
{
    NSError *errorInfo = [notice objectForKey:@"error"];

    if ( errorInfo != nil ) {
        UIAlertView *notice = [[UIAlertView alloc] initWithTitle:@"Error" message:[errorInfo localizedDescription] delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];   
        [notice show];
        [notice release];            
    }
}

Этот код покажет любую ошибку, связанную с moviecontroller. Итак, в чем проблема в моем коде?.. Я использовал метод [moviecontroller play] в неправильных местах, поэтому проверьте это в своем.

Удачи!

Ответ 3

Вы можете посмотреть значение позади словаря userinfo MPMoviePlayerPlaybackDidFinishReasonUserInfoKey. Если значение MPMovieFinishReasonPlaybackError, вы можете предположить, что некоторые вещи пошли не так. Этот метод довольно надежный.