2016-09-21 1 views
0

J'ai 2 View Controller Details Home and Home. Dans Home, j'ai une vue de table dans laquelle je montre la vignette et la durée d'une vidéo. Lorsque je clique sur une ligne particulière, ses détails sont affichés dans Détails de la maison. En revenant, je suis en train de mettre à jour la ligne sélectionnée. Donc, pour que viewWillDisappear Méthode d'accueil Détails J'ai écrit le code suivant:L'interface utilisateur est bloquée lors de l'extraction de la durée de la vidéo à partir de AVURLAsset dans dispatch_async

if ([self.delegate respondsToSelector:@selector(changeSelectedBucketData:)]) { 
     [self.delegate changeSelectedBucketData:_videoId]; 
    } 

maintenant dans la maison du contrôleur, j'ai défini cette méthode comme:

-(void)changeSelectedBucketData:(NSString*)videoId { 

    NSString *dataStr = [NSString stringWithFormat:@"%@bucket_id=%@",kGetBucketById,videoId]; 

    [[WebServiceCall sharedInstance] sendGetRequestToWebWithData:dataStr success:^(NSDictionary *json) { 

     if([[json valueForKey:@"ResponseCode"] integerValue] == 0) { 

     } else { 
      dispatch_async(dispatch_get_main_queue(), ^{ 

       [_arrayOfContent replaceObjectAtIndex:selectedIndex withObject:[json valueForKey:@"GetData"]]; 

       if (_arrayOfContent.count) { 

        TableViewCellHome *cell = [self.mTableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:selectedIndex inSection:0]]; 

        [self fillDataForIndexPath:[NSIndexPath indexPathForRow:selectedIndex inSection:0] forCell:cell]; 
       } 
      }); 
     } 
    } failure:^(NSError *error) { 
     dispatch_async(dispatch_get_main_queue(), ^{ 
     }); 
    }]; 
} 



-(void)fillDataForIndexPath:(NSIndexPath*)indexPath forCell:(TableViewCellHome*)cell{ 

    NSDictionary *dict = [_arrayOfContent objectAtIndex:indexPath.row]; 

    NSURL *url = [NSURL URLWithString:[[_arrayOfContent objectAtIndex:indexPath.row] valueForKey:@"video_URL"]]; 
      [self downloadDurationAtURL:url cellTag:indexPath]; 
} 

Maintenant, je l'ai utilisé le code suivant pour télécharger durée d'une vidéo:

- (NSUInteger)videoDuration:(NSURL *)videoURL { 

    AVURLAsset *videoAVURLAsset = [AVURLAsset assetWithURL:videoURL]; 

    CMTime durationV = videoAVURLAsset.duration; 

    return CMTimeGetSeconds(durationV); 
} 

- (NSString *)videoDurationTextDurationTotalSeconds:(NSUInteger)dTotalSeconds { 

    NSUInteger dHours = floor(dTotalSeconds/3600); 
    NSUInteger dMinutes = floor(dTotalSeconds % 3600/60); 
    NSUInteger dSeconds = floor(dTotalSeconds % 3600 % 60); 

    if (dHours > 0) { 

     return [NSString stringWithFormat:@"%i:%02i:%02i",dHours, dMinutes, dSeconds]; 

    } else { 

     return [NSString stringWithFormat:@"%02i:%02i",dMinutes, dSeconds]; 
    } 
} 


-(void)downloadDurationAtURL:(NSURL *)videoURL cellTag:(NSIndexPath*)indexPath { 

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
     //retrive image on global queue 

     NSUInteger dTotalSeconds = [self videoDuration:videoURL]; 

     NSLog(@"dTotalSeconds %i",dTotalSeconds); 

     if (dTotalSeconds > 0) { 

      NSString *videoDurationText = [self videoDurationTextDurationTotalSeconds:dTotalSeconds]; 

      dispatch_async(dispatch_get_main_queue(), ^{ 

       TableViewCellHome *cell = [self.mTableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:indexPath.row inSection:0]]; 
       [[_arrayOfContent objectAtIndex:indexPath.row] setObject : videoDurationText forKey:@"duration"]; 
       cell.labelDuration.text = videoDurationText; 
       cell.labelDuration.hidden = false; 
      }); 
     } 
     else { 

     dispatch_async(dispatch_get_main_queue(), ^{ 
      TableViewCellHome *cell = [self.mTableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:indexPath.row inSection:0]]; 
       [[_arrayOfContent objectAtIndex:indexPath.row] setObject : @"" forKey:@"duration"]; 
       cell.labelDuration.hidden = true; 
       cell.labelDuration.text = @""; 
      }); 
     } 
    }); 
} 

problème maintenant est que l'interface utilisateur est bloqué jusqu'à ce que se la durée est modifiée dans la cellule. Je ne suis pas en mesure de sélectionner une ligne particulière tant que la durée n'est pas affichée sur la cellule. Mais cela fonctionne bien lorsque j'affiche le contrôleur Home pour la première fois après avoir appelé l'API. Il est seulement bloqué quand je l'appelle des détails de la maison.

+0

La méthode 'changeSelectedBucketData' ressemble, il est appelé sur le thread principal, ce qui signifie que votre demande de get tient le fil de l'interface utilisateur. – Stonz2

+0

J'ai essayé mais ça n'aide pas. if ([self.delegate respondsToSelector: @selector (changeSelectedBucketData :)]) { dispatch_async (dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)^{ [self.delegate changeSelectedBucketData: _videoId]; }); } –

Répondre

0

Vous devez charger la durée de manière asynchrone, comme ceci:

- (void)videoDuration:(NSURL *)videoURL completion:(void (^)(CMTime))durationCallback { 
    AVURLAsset *videoAVURLAsset = [AVURLAsset assetWithURL:videoURL]; 

    [videoAVURLAsset loadValuesAsynchronouslyForKeys:@[ @"duration"] completionHandler:^{ 
     NSError *error; 
     if([videoAVURLAsset statusOfValueForKey:@"duration" error:&error]) { 
      NSLog(@"error getting duration: %@", error); 
      durationCallback(kCMTimeZero); // or something 
     } else { 
      durationCallback(videoAVURLAsset.duration); 
     } 
    }]; 
}