繁体   English   中英

Bundle.main.path(forResource:ofType:inDirectory:) 返回 nil

[英]Bundle.main.path(forResource:ofType:inDirectory:) returns nil

尽量不要笑或哭——我在 20 年后才重新开始编码......

我花了 4 个多小时查看参考资料并尝试使用代码片段来获取 Bundle.main.path 以打开我的文本文件,以便我可以读取我的应用程序的数据(我的下一步是适当地解析它)。

if let filepath = Bundle.main.path(forResource: "newTest", ofType: "txt")
{
    do
    {
        let contents = try String(contentsOfFile: filepath)
        print(contents)

    }
    catch
    {
        print("Contents could not be loaded.")
    }
}
else
{
    print("newTest.txt not found.")
}

结果是:“找不到newTest.txt”。 无论我如何尝试将文件拖放到项目中,在 Xcode 中创建文件或使用 File -> Add Files to... 菜单项。

问题是该文件没有被复制到您的应用程序包中。 要解决这个问题:

  • 单击您的项目
  • 点击你的目标
  • 选择构建阶段
  • 展开复制包资源
  • 单击“+”并选择您的文件。

add files时,请仔细检查add files菜单中的Options 必须勾选Add to targets才能将其添加到包中:

如果您实际上在另一个包中(例如测试),请使用:

guard let fileURL = Bundle(for: type(of: self)).url(forResource: fileName withExtension:"txt") else {
        fatalError("File not found")
}

单击导航面板上的文件并打开右侧面板/属性检查器。

在此处输入图片说明

确保您添加到目标成员资格

斯威夫特 3.0

let fileNmae = "demo"
        
let path = Bundle.main.path(forResource: fileName, ofType: "txt")
    do {
        let content = try String(contentsOfFile:path!, encoding: String.Encoding.utf8)
        print(content)
    } catch {
        print("nil")
    }

斯威夫特 2.0

do{
      if let path = NSBundle.mainBundle().pathForResource("YOURTXTFILENAME", ofType: "txt"){
             let data = try String(contentsOfFile:path, encoding: NSUTF8StringEncoding)
             let myStrings = data.componentsSeparatedByCharactersInSet(NSCharacterSet.newlineCharacterSet())
              print(myStrings)
       }
  } catch let err as NSError {
            //do sth with Error
            print(err)
  }

输出 :

Hello Hems
Good Morning
I m here for you dude.
Happy Coding.

这么简单的问题要花费多少时间,真是太疯狂了。

这里的一些答案对我有帮助,但我总是尝试:

Bundle.main.url(forResource: selectedTitle, withExtension: "mp3")

出于某种原因,这不起作用,但获取路径并将其转换为 URL 之后可以工作:

let path = Bundle.main.path(forResource: selectedTitle, ofType: "mp3")
let url = URL(fileURLWithPath: path!)

啊,所以刚刚发现自己正在处理与 OP 完全相同的问题。

问题是当代码在操场上执行时,这里这里给出的解决方案不起作用,因为add filesOptions菜单看起来不同,因为它没有显示Add to targets字段:

在此处输入图片说明

.playground文件中时,请按 Xcode 窗口右上角的Hide or show the Navigator按钮(视觉印象)--> 在此处输入图片说明

然后,一旦导航器在 Xcode 窗口的左侧折叠打开,只需将您的文件拖放到您的 Playground 的Resources目录中即可。

如果您的设置如下所示,您应该没问题:

在此处输入图片说明

这对我很有帮助: xcode - 将文件夹结构复制到我的应用程序包中

在嵌套文件夹中创建资产时,标记“创建文件夹引用”选项。

然后像这样找到文件的路径:

let path = Bundle(for: type(of : self)).path(forResource: "some_folder_a/some_folder_b/response.json", ofType: nil)

同样的问题,情况和解决方案略有不同。 我正在关注一个教程,该教程说使用以下代码:

    // Start the background music:
    if let musicPath = Bundle.main.path(forResource:
        "Sound/BackgroundMusic.m4a", ofType: nil) {
        print("SHOULD HEAR MUSIC NOW")
        let url = URL(fileURLWithPath: musicPath)

        do {
            musicPlayer = try AVAudioPlayer(contentsOf: url)
            musicPlayer.numberOfLoops = -1
            musicPlayer.prepareToPlay()
            musicPlayer.play()
        }
        catch { print("Couldn't load music file") }
    }
}

我和其他人有同样的问题,但没有一个解决方案解决了这个问题。 经过试验,我所做的就是在以下调用中从路径中删除Sound并且一切正常:

Bundle.main.path(forResource: "BackgroundMusic.m4a", ofType: nil)

通过告诉我在路径中包含声音,教程似乎是错误的。

我将file.txt添加到我的项目中,它会自动添加到我的项目的Copy Bundle Files中。 对我来说,我必须从forResource删除扩展名并且它起作用了。

let path = Bundle.main.path(forResource: "file", ofType: "txt") // not forResource: "file.txt"

我认为您不想要inDirectory:方法。 试试这个:

if let filepath = Bundle.main.path(forResource: "newTest", ofType: "txt") {

我的问题出在一个用 Cocoapods 创建的模块中。 每个 pod 安装/更新,文件(json 文件)都在项目中,但从未在 Bundle 中找到。 在 pod install/update 之后,我删除了(删除了引用)文件并再次添加到项目中。

始终注意添加文件的目标。

答案很简单,不要使用 Assets.xcassets 来存储您的音频文件,而将您的音频文件,即)BeTheFirstAudio.m4a(使用 QuickTime 制作)直接添加到 PROJECT NAVIGATOR(圆圈、粉红色)文件列表中(照片 1)

在此处输入图片说明

警告! 在从 Finder 窗口拖动音频文件后出现弹出窗口时,请务必选中“创建组”和“添加到目标”复选框。

在此处输入图片说明

之后,您的代码应该可以播放音频(包括来自 QuickTime 的 .m4a 扩展名)

 import AVFoundation

 class AudioPlayer: NSObject {


     private var audioPlayer: AVAudioPlayer!

     override init() {
         super.init()
    
         // get URL for the default audio
         let audioURL = Bundle.main.url(forResource: "BeTheFirstAudio", withExtension: "m4a")

         audioPlayer = try! AVAudioPlayer(contentsOf: audioURL!)
     }

苹果工程师应该感到羞耻的是,这个问题甚至是 StackOverflow 中的一个问题; 开发人员应该能够将音频文件添加到 Assets.xcassets 并且 Bundle.main.url 应该能够找到它。 这个简单的概念很困难,这一事实可能让开发人员花费了大量时间。 注意@Apple

如果你使用R.swift试试这个:

我仍然遇到特别是在构建期间更改的 plist 文件的问题,并且由于我的项目使用的是 R.swift,因此我将代码更改为

Bundle.main.path(forResource: R.file.myplistfile)

这就像一个魅力。

值得一提

如果您正在运行单元测试或 ui 测试,请使用它们的包 ID。 因为他们没有使用主包,所以你永远不会通过调用Bundle.main.path(forResource: "newTest", ofType: "txt")找到你的文件。

使用您的测试目标包 ID。 就我而言,我正在尝试从 CSV 文件中读取数据。 TestReadFileUITests替换为从XCTestCase扩展的 class 名称。

这是我运行 UI 测试用例时使用的实际捆绑包 ID。 您可以看到它不是来自主捆绑包。

(lldb) po testBundle
NSBundle </Users/zhouhaibo/Library/Developer/CoreSimulator/Devices/448D1FCB-8311-4D3F-BEEF-934052C3470F/data/Containers/Bundle/Application/905C2326-8313-410F-9DC2-9D84B9C6D757/TestReadFileUITests-Runner.app/PlugIns/TestReadFileUITests.xctest> (loaded)

(lldb) po filePath
"/Users/zhouhaibo/Library/Developer/CoreSimulator/Devices/448D1FCB-8311-4D3F-BEEF-934052C3470F/data/Containers/Bundle/Application/905C2326-8313-410F-9DC2-9D84B9C6D757/TestReadFileUITests-Runner.app/PlugIns/TestReadFileUITests.xctest/Patients_2022-09-02.csv"
let testBundle = Bundle(for: TestReadFileUITests.self)
guard let filePath = testBundle.path(forResource: fileName, ofType: fileType) else {
    print("CSV file not found.")
    return [:]
}
class TestReadFileUITests: XCTestCase {

    func testDemo() {
        let _ = DataManager.readData()
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM