Как получить путь к файловой системе для ресурса на iPhone?

На iPhone мне нужно получить путь к ресурсу. Хорошо, сделал это, но когда дело доходит до CFURLCreateFromFileSystemRepresentation, я просто не знаю, как это решить. Почему возникает эта ошибка? Любое решение или обходной путь будут высоко оценены. Заранее спасибо.

Я рассмотрел следующие примеры воспроизведения звука с помощью AudioQueue на iPhone: SpeakHere, AudioQueueTools (из каталога SimpleSDK) и AudioQueueTest. Я пробовал делать то и это, пытаясь сложить пазлы. Прямо сейчас я застрял в этом. Программа аварийно завершилась из-за исключения, выброшенного из sndFile выше.

Я использую AVAudioPlayer для воспроизведения каждого звука в играх для iPhone. На реальном устройстве iPhone оказалось очень медленным, когда нужно воспроизвести звук, поэтому я решил, что мне нужно использовать AudioQueue.

- (id) initWithFile: (NSString*) argv{

    if (self = [super init]){
        NSString *soundFilePath = [[NSBundle mainBundle]
                                    pathForResource:argv
                                             ofType:@"mp3"];
        int len = [soundFilePath length];
        char* fpath = new char[len];

        //this is for changing NSString into char* to match
        //CFURLCreateFromFileSystemRepresentation function's requirement.
        for (int i = 0; i < [soundFilePath length]; i++){
            fpath[i] = [soundFilePath characterAtIndex:i];
        }

        CFURLRef sndFile = CFURLCreateFromFileSystemRepresentation
                           (NULL, (const UInt8 *)fpath, strlen(fpath), false);
        if (!sndFile) {
            NSLog(@"sndFile error");
            XThrowIfError (!sndFile, "can't parse file path");
        }
}

person Karl    schedule 24.07.2009    source источник
comment
Что вы пытаетесь достичь. Мне не нравятся вопросы, которые спрашивают, как использовать метод фреймворка, а не как я могу решить эту настоящую проблему. Кроме того, что с лишним многоточием?   -  person Brock Woolf    schedule 24.07.2009
comment
Хорошо, извините за это. Я немного устал. Во всяком случае, я пытался следовать всем примерам для AudioQueue, а также прочитал документ Apple для этого. Учитывая, что я не очень опытен, я не знаю, как правильно обращаться с CFURLRef. Все, что я понимаю из всех примеров и документов, это то, что мне нужно использовать CFURLCreateFromFileSystemRepresentation, чтобы получить CFURLRef, чтобы я мог использовать этот CFURLRef в качестве аргумента в методе AudioFileOpenURL. Но я получил сообщение об ошибке: завершение вызывается после создания экземпляра «CAXException». Я не знаю, как бороться с этой ошибкой.   -  person Karl    schedule 24.07.2009


Ответы (2)


Зачем вам нужен CFURL?

Если у вас есть метод в другом месте, для которого требуется CFURL, вы можете просто использовать NSURL благодаря бесплатному мосту. Итак, чтобы создать NSURL, вам нужно сделать следующее:

  NSString * soundFilePath = [[NSBundle mainBundle]
                                 pathForResource:argv
                                          ofType:@"mp3"];

  NSURL *soundURL = [NSURL fileURLWithPath:soundFilePath];

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

person Kendall Helmstetter Gelner    schedule 24.07.2009
comment
Что означает КФ? Я чувствую себя глупо, спрашивая, но слишком много возможностей. - person Sneakyness; 26.07.2009
comment
Core Foundation, вызовы NS основаны на вызовах более низкого уровня — обычно существует более чистый и простой способ использования метода NS, чем метод CF. - person Kendall Helmstetter Gelner; 26.07.2009
comment
Не совсем так. В общем, если вы обнаружите, что используете объекты CF, вы, вероятно, делаете что-то не так. Классы Core Foundation могут быть полезны, если: 1) Вы пытаетесь прочитать exif/метаданные в изображении 2) Если вам нужен, например, размер изображения, и вы не хотите загружать в память большое изображение (фрагмент карты), например 2048x2048. 3) И так далее.... - person Roman Safin; 03.03.2015
comment
1) Вы используете вызовы CG, а не CF для чтения метаданных изображения. Вызовы CoreGraphics — это другое дело, так как часто нет лучших методов более высокого уровня. 2) Вы уверены, что UIImage загружает данные изображения в память перед доступом к ним? Возможно, вы можете создать UIImage из файла, а затем проверить свойства размера, не запуская загрузку данных изображения из хранилища. - person Kendall Helmstetter Gelner; 06.03.2015

Я не уверен, что это избавит вас от исключения, но есть более простой способ преобразовать NSString в массив char. Вот как я бы написал этот метод:

- (id) initWithFile:(NSString*) argv
{
    if ((self = [super init]) == nil) { return nil; }

    NSString * soundFilePath = [[NSBundle mainBundle]
                                 pathForResource:argv
                                          ofType:@"mp3"];
    CFURLRef sndFile = CFURLCreateFromFileSystemRepresentation
                       (NULL, [soundFilePath UTF8String],
                        [soundFilePath length], NO);

    if (!sndFile) { NSLog(@"sndFile error"); }
    XThrowIfError (!sndFile, "can't parse file path");

    ...
}

Или, поскольку CFURL является «бесплатным мостом» с NSURL, вы можете просто сделать:

- (id) initWithFile:(NSString*) argv
{
    if ((self = [super init]) == nil) { return nil; }

    NSString * soundFilePath = [[NSBundle mainBundle]
                                 pathForResource:argv
                                          ofType:@"mp3"];
    NSURL * sndFile = [NSURL URLWithString:[soundFilePath
                       stringByAddingPercentEscapesUsingEncoding:
                         NSUTF8StringEncoding]];
    if (!sndFile) { NSLog(@"sndFile error"); }
    XThrowIfError (!sndFile, "can't parse file path");

    ...
}
person e.James    schedule 24.07.2009