Как я могу загрузить элемент из пакета swift, который находится в папке?

#swift

Вопрос:

Я пытаюсь загрузить файл a в режиме «звук по умолчанию». Вот как это выглядит в пакете. введите описание изображения здесь

Я попытался загрузить с a / , чтобы найти папку, как вы сделали бы с обычной структурой каталогов.

 import Foundation
import AVFoundation

struct TtsPronounciationError: Error {
    enum ErrorKind {
        case loadingError
    }
    
    let kind: ErrorKind
    let path: String;
    let char: Character
    
    init(kind: ErrorKind, path: String, char: Character) {
        self.path = path;
        self.kind = kind
        self.char = char
    }
}

struct TtsPronounciation {
    var char: Character;
    var audioFile: AVAudioPlayer
    
    static func fromBundle(char: Character, bundleFileName: String) throws -> TtsPronounciation {
        Bundle.main.load()
        
        if let path = Bundle.main.path(forResource: bundleFileName, ofType: nil) {
            let url = URL(fileURLWithPath: path)
            do {
                let sound = try AVAudioPlayer(contentsOf: url)
                return self.init(char: char, audioFile: sound)
            } catch let e {
                print(#function, "error", e)
                throw TtsPronounciationError(kind: .loadingError, path: bundleFileName, char: char)
            }
        } else {
            print(#function, " - error", "could not find (bundleFileName)")
            throw TtsPronounciationError(kind: .loadingError, path: bundleFileName, char: char)
        }
    }
}

do {
    var a = try TtsPronounciation.fromBundle(char: "a", bundleFileName: "default-sound/a")
}
catch {
    print("could not find the file in bundle")
}
 

Во-вторых, я попытался использовать косвенный параметр функции Bundle.main.path , поскольку я думаю, что он используется для поиска файлов, которые хранятся в каталоге пакета.

 import Foundation
import AVFoundation

struct TtsPronounciationError: Error {
    enum ErrorKind {
        case loadingError
    }
    
    let kind: ErrorKind
    let path: String;
    let char: Character
    
    init(kind: ErrorKind, path: String, char: Character) {
        self.path = path;
        self.kind = kind
        self.char = char
    }
}

struct TtsPronounciation {
    var char: Character;
    var audioFile: AVAudioPlayer
    
    static func fromBundle(char: Character, bundleFileName: String, inDirectory: String?) throws -> TtsPronounciation {
        Bundle.main.load()
        
        if let path = inDirectory != nil ? Bundle.main.path(forResource: bundleFileName, ofType: nil, inDirectory: inDirectory) : Bundle.main.path(forResource: bundleFileName, ofType: nil) {
            let url = URL(fileURLWithPath: path)
            do {
                let sound = try AVAudioPlayer(contentsOf: url)
                return self.init(char: char, audioFile: sound)
            } catch let e {
                print(#function, "error", e)
                throw TtsPronounciationError(kind: .loadingError, path: bundleFileName, char: char)
            }
        } else {
            print(#function, " - error", "could not find (bundleFileName)")
            throw TtsPronounciationError(kind: .loadingError, path: bundleFileName, char: char)
        }
    }
}

do {
   var a = try TtsPronounciation.fromBundle(char: "a", bundleFileName: "a", inDirectory: "default-sound")
}
catch {
    print("could not locate the sound")
}
 

Комментарии:

1. Элементы в каталоге активов недоступны path(forResource . Пожалуйста, посмотрите developer.apple.com/library/archive/qa/qa1913/_index.html Кстати, есть еще url(forResource:withExtension:

Ответ №1:

Проблема здесь не в том, что он находится в папке. Это есть в каталоге активов. Вы получаете доступ к ресурсам данных (таким как аудио) с помощью NSDataAsset. Этот конкретный пример описан в QA1913 Доступ к аудиофайлам в каталогах активов:

 if let asset = NSDataAsset(name:"Sound"){

   do {
         // Use NSDataAsset's data property to access the audio file stored in Sound.
          player = try AVAudioPlayer(data:asset.data, fileTypeHint:"caf")
         // Play the above sound file.
         player?.play()
   } catch let error as NSError {
         print(error.localizedDescription)
   }
}
 

В вашем случае вы бы заменили «Звук» на «а».

Комментарии:

1. есть ли способ, которым я все еще могу использовать структуру каталогов?

2. Для этого вам нужно будет удалить это из каталога активов. Каталоги активов оптимизированы таким образом, чтобы не допускать прямого доступа по URL-адресу. Чтобы сохранить структуру каталогов, убедитесь, что папка в Xcode создана как ссылка на папку, а не как группа (в противном случае структура папок будет выровнена).

3. (Обратите внимание, что вы можете назвать это, "default-sound/a" а не » "a" если хотите», если вы это имеете в виду. Для получения более подробной информации см. developer.apple.com/library/archive/documentation/Xcode/… ) Тогда это было бы NSDataAsset(name: "default-sound/a")

4. В чем разница между каталогом активов и пакетом?

5. В комплекте содержится каталог активов. Это оптимизированный способ хранения различных видов активов. Они часто предварительно обрабатываются, чтобы быть наиболее эффективными на целевом устройстве, и поддерживают такие функции, как автоматическое управление разрешениями.