Сбой приложения при импорте песен из библиотеки Ipod в iPhone для iOs 5.0 - PullRequest
7 голосов
/ 10 ноября 2011

Здравствуйте, я использую ниже framworks,

#import <MediaPlayer/MediaPlayer.h>
#import <AudioToolbox/AudioToolbox.h>
#import <AVFoundation/AVFoundation.h>

В одном из событий кнопки я реализовал код ниже, чтобы открыть библиотеку.

        MPMediaPickerController *mediaPicker = [[MPMediaPickerController alloc] initWithMediaTypes:MPMediaTypeMusic];
    mediaPicker.delegate = self;
    mediaPicker.allowsPickingMultipleItems = YES; // this is the default   
    [self presentModalViewController:mediaPicker animated:YES];
    [mediaPicker release];

И в методах делегатов MPMediaPickerController реализовал кодкак показано ниже

#pragma mark MPMediaPickerController delegate methods

- (void)mediaPicker: (MPMediaPickerController *)mediaPicker didPickMediaItems:(MPMediaItemCollection *)mediaItemCollection {

    // We need to dismiss the picker
    [self dismissModalViewControllerAnimated:YES];

    // Assign the selected item(s) to the music player and start playback.

    counterIpod = [mediaItemCollection.items count];
    totalcollection = counterIpod;
    if (totalcollection > 10) {
        NSString *str = [NSString stringWithFormat:@"App Only supports importing 10 songs at a time"];
        UIAlertView *connectionAlert = [[UIAlertView alloc] initWithTitle:@"Message !" message:str delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [connectionAlert show];
        [connectionAlert release];
    }
    else {
        [self performSelector:@selector(saveMediaItem:) withObject:mediaItemCollection afterDelay:0.1];
        //[self saveMediaItem:mediaItemCollection];
        //[self showLoadingView];       
    }
}

- (void)mediaPickerDidCancel:(MPMediaPickerController *)mediaPicker {
    // User did not select anything
    // We need to dismiss the picker
    [self dismissModalViewControllerAnimated:YES];
}

#pragma mark Sace Item Collection to documentsDirectory
-(void)saveMediaItem:(MPMediaItemCollection *)mediaItemCollection {

    for (int i = 0; i < [mediaItemCollection.items count]; i++) {

        [self exportAssetAsSourceFormat:[[mediaItemCollection items] objectAtIndex:i]];

        NSLog(@"for loop : %d", i);
    }

    NSArray *itemsArray1 = appDelegate.mediaItemCollection1.items;
    MPMediaItemCollection *mediaItemCollection2;

    if ([itemsArray1 count] != 0) {
        mediaItemCollection2 = [self collectionByAppendingCollection:mediaItemCollection];
    }
    else {
        mediaItemCollection2 = mediaItemCollection;
    }

    [self saveMediaItemAfterDeletting:mediaItemCollection2];
}

-(void)saveMediaItemAfterDeletting:(MPMediaItemCollection *)mediaItemCollection {

    NSMutableData* data = [[NSMutableData alloc] init];

    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
    [archiver encodeObject:mediaItemCollection forKey:@"my_playlist"];
    [archiver finishEncoding];

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];

    NSString *filePath = [NSString stringWithFormat:@"%@/playlist.data", documentsDirectory];
    NSLog(@"file path = %@", filePath);

    [data writeToFile:filePath atomically:YES];

    if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]){
        NSLog(@"file exists : ===========>>>>>>>>>>>");
    } else {
        NSLog(@"file doesn't exist");
    }

    //NSLog(@"archiving playlist success = %d", success);

    [archiver release];
    [data release];

    [self UpdateMediaCollection];
}

-(NSString*) getExtension:(MPMediaItem *)item {

    //  [self showLoadingView];

    NSURL *assetURL = [item valueForProperty:MPMediaItemPropertyAssetURL];
    AVURLAsset *songAsset = [AVURLAsset URLAssetWithURL:assetURL options:nil];

    // JP
//  AVAssetExportSession *exportSession = [[AVAssetExportSession alloc]
//                                         initWithAsset:songAsset
//                                         presetName:AVAssetExportPresetPassthrough];

    NSArray *tracks = [songAsset tracksWithMediaType:AVMediaTypeAudio];
    AVAssetTrack *track = [tracks objectAtIndex:0];

    id desc = [track.formatDescriptions objectAtIndex:0];
    const AudioStreamBasicDescription *audioDesc = CMAudioFormatDescriptionGetStreamBasicDescription((CMAudioFormatDescriptionRef)desc);
    FourCharCode formatID = audioDesc->mFormatID;

    //exportAudioMix.inputParameters = [NSArray arrayWithObject:exportAudioMixInputParameters]; 
    //exportSession.audioMix = exportAudioMix;

    NSString *fileType = nil;
    NSString *ex = nil;

    switch (formatID) {

        case kAudioFormatLinearPCM:
        {
            UInt32 flags = audioDesc->mFormatFlags;
            if (flags & kAudioFormatFlagIsBigEndian) {
                fileType = @"public.aiff-audio";
                ex = @"aif";
            } else {
                fileType = @"com.microsoft.waveform-audio";
                ex = @"wav";
            }
        }
            break;

        case kAudioFormatMPEGLayer3:
            fileType = @"com.apple.quicktime-movie";
            ex = @"mp3";
            break;

        case kAudioFormatMPEG4AAC:
            fileType = @"com.apple.m4a-audio";
            ex = @"m4a";
            break;

        case kAudioFormatAppleLossless:
            fileType = @"com.apple.m4a-audio";
            ex = @"m4a";
            break;

        default:
            break;
    }   

    return ex;

}


#pragma mark Covert Item separate item collection and store songs into directory 
- (void)exportAssetAsSourceFormat:(MPMediaItem *)item {

    //  [self showLoadingView];

    NSLog(@"export asset called");
    NSURL *assetURL = [item valueForProperty:MPMediaItemPropertyAssetURL];
    NSLog(@"\n>>>> assetURL : %@",[assetURL absoluteString]);
    AVURLAsset *songAsset = [AVURLAsset URLAssetWithURL:assetURL options:nil];

    // JP
    AVAssetExportSession *exportSession = [[AVAssetExportSession alloc]
                                           initWithAsset:songAsset
                                           presetName:AVAssetExportPresetPassthrough];

    NSArray *tracks = [songAsset tracksWithMediaType:AVMediaTypeAudio];
    AVAssetTrack *track = [tracks objectAtIndex:0];

    id desc = [track.formatDescriptions objectAtIndex:0];
    const AudioStreamBasicDescription *audioDesc = CMAudioFormatDescriptionGetStreamBasicDescription((CMAudioFormatDescriptionRef)desc);
    FourCharCode formatID = audioDesc->mFormatID;

    //exportAudioMix.inputParameters = [NSArray arrayWithObject:exportAudioMixInputParameters]; 
    //exportSession.audioMix = exportAudioMix;

    NSString *fileType = nil;
    NSString *ex = nil;

    switch (formatID) {

        case kAudioFormatLinearPCM:
        {
            UInt32 flags = audioDesc->mFormatFlags;
            if (flags & kAudioFormatFlagIsBigEndian) {
                fileType = @"public.aiff-audio";
                ex = @"aif";
            } else {
                fileType = @"com.microsoft.waveform-audio";
                ex = @"wav";
            }
        }
            break;

        case kAudioFormatMPEGLayer3:
            fileType = @"com.apple.quicktime-movie";
            ex = @"mp3";
            break;

        case kAudioFormatMPEG4AAC:
            fileType = @"com.apple.m4a-audio";
            ex = @"m4a";
            break;

        case kAudioFormatAppleLossless:
            fileType = @"com.apple.m4a-audio";
            ex = @"m4a";
            break;

        default:
            break;
    }

    exportSession.outputFileType = fileType;     

    NSString *fileName = nil;

    fileName = [NSString stringWithString:[item valueForProperty:MPMediaItemPropertyTitle]];
    fileName = [[fileName stringByAppendingString:@"-"] stringByAppendingString:[item valueForProperty:MPMediaItemPropertyArtist]];
    NSArray *fileNameArray = nil;
    fileNameArray = [fileName componentsSeparatedByString:@" "];
    fileName = [fileNameArray componentsJoinedByString:@""];

    NSLog(@">>>>> fileName = %@", fileName);

    NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString *filePath = [[docDir stringByAppendingPathComponent:fileName] stringByAppendingPathExtension:ex];

    NSLog(@"filePath = %@", filePath);  

    if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
        //NSLog(@"file exist::::::::::==============>>>>>>>>>>>>>>>>>");
        counterIpod--;

        if(counterIpod == 0) {
            //[self showAlertView];
            //[self hideLoadingView];
        }

        NSString *str = [NSString stringWithFormat:@"Loading %d of %d Beats", totalcollection - counterIpod ,totalcollection];
        [lbl performSelectorOnMainThread:@selector(setText:) withObject:str waitUntilDone:NO];
        //NSLog(@"loading string : %@", str);

        return;
    }

    //NSLog(@"file not exist  ===========>>>>>>>>>");
    // -------------------------------------
    int fileNumber = 0;
    NSString *fileNumberString = nil;
    NSString *fileNameWithNumber = nil;
    while ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
        fileNumber++;
        fileNumberString = [NSString stringWithFormat:@"-%02d", fileNumber];
        fileNameWithNumber = [fileName stringByAppendingString:fileNumberString];
        filePath = [[docDir stringByAppendingPathComponent:fileNameWithNumber] stringByAppendingPathExtension:ex];
        //NSLog(@"filePath = %@", filePath);        
    }   

    // -------------------------------------    
    myDeleteFile(filePath);
    exportSession.outputURL = [NSURL fileURLWithPath:filePath];

    [exportSession exportAsynchronouslyWithCompletionHandler:^{

        if (exportSession.status == AVAssetExportSessionStatusCompleted) {
            NSLog(@"export session completed");
            counterIpod--;

            NSString *str = [NSString stringWithFormat:@"Loading %d of %d Beats", totalcollection - counterIpod ,totalcollection];

            //[self performSelector:@selector(setLabelText:) withObject:str afterDelay:0.02];
            [lbl performSelectorOnMainThread:@selector(setText:) withObject:str waitUntilDone:NO];
            NSLog(@"loading string : %@", str);

            if(counterIpod == 0) {
                //[self showAlertView];
                //[self hideLoadingView];
            }
        } else {
            NSLog(@"export session error");
            counterIpod--;
            NSString *str = [NSString stringWithFormat:@"Loading %d of %d Beats", totalcollection - counterIpod ,totalcollection];
            [lbl performSelectorOnMainThread:@selector(setText:) withObject:str waitUntilDone:NO];
            //return NO;
            if(counterIpod == 0) {
                //[self showAlertView];
                //[self hideLoadingView];
            }
        }

        [exportSession release];
    }];

    //[appDelegate hideLoadingView];
}

#pragma mark method to delete file from document directory 
void myDeleteFile (NSString* path) {
    //  NSLog(@"file path delete file :::::::::: %@", path);
    if ([[NSFileManager defaultManager] fileExistsAtPath:path]) {
        NSError *deleteErr = nil;
        [[NSFileManager defaultManager] removeItemAtPath:path error:&deleteErr];
        if (deleteErr) {
            NSLog (@"Can't delete %@: %@", path, deleteErr);
        }
    }
}

Над кодом работает без ошибок на iOS 4.0 или более ранней версии, но для iOS 5.0 происходит сбой на устройстве, я не могу решить эти проблемы с последних 15 дней.

Заранее спасибо за помощь.

Ответы [ 2 ]

4 голосов
/ 19 марта 2012

Я решил эту проблему,

просто закомментируйте эту строку

 fileName = [[fileName stringByAppendingString:@"-"] stringByAppendingString:[item valueForProperty:MPMediaItemPropertyArtist]];

потому что для некоторых песен есть нулевой исполнитель, поэтому это сбой ...................

2 голосов
/ 12 июня 2012

Это потому, что вы используете некоторые песни с именем исполнителя, а некоторые с пустым именем исполнителя, поэтому вы пытаетесь добавить пустое имя в строку, поэтому приложение может аварийно завершить работу.

Надеюсь, вы понимаете, что я говорю ...

...