Fatal error: String index is out of bounds

Hi there,

I have a function on my app which sets a schedule for an audio recording to happen automatically. The recording successfully starts and stops at the given times. However, I get a runtime error when I hit the button “recordings” to check for the created recording file.

Would you happen to know why that’s the case?

I didn’t think it should be a problem as I’m only automating a pre-existing function. I initially have a function which sucessfully records when start and stop button for the function is manually pressed and the file is created within the folder “recordings”

Here’s my code:

    /*
     This will change recordings to fileitmes and add to an array, this array is used by the table view, which will then show the recordings
     */
    func addToRecordings(folder: String) {
        let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
        let path = documentsDirectory.appendingPathComponent(folder).absoluteURL
        do {
            let directoryContents = try FileManager.default.contentsOfDirectory(at: path, includingPropertiesForKeys: nil, options: [])
            //only want the wav files
            let wavFiles = directoryContents.filter{ $0.pathExtension == "wav" }
            for file in wavFiles{
                let fileName = file.lastPathComponent
                let start = fileName.index(fileName.startIndex, offsetBy: 26)
                let end = fileName.index(fileName.endIndex, offsetBy: -4)
                let range = start..<end
                //create id to help sort the wav files 
                let id = Int(fileName[range]) ?? 0
                if let fileAttributes = try? FileManager.default.attributesOfItem(atPath: file.path) {
                    if let bytes = fileAttributes[.size] as? Int64 {
                        let fileSize = fileByteCountFormatter.string(fromByteCount: bytes)
                        let recording = FileItem(id: id, fileName: fileName, fileSizeSpecific: fileSize, fileSizeBytes: bytes, fileLocation: folder+fileName)
                        self.recordings.append(recording!)
                    }
                }
            }
            self.recordings = self.recordings.sorted(by: {$0.id < $1.id})
            self.tableView.reloadData()
        } catch {
            print(error)
        }
        if recordings.isEmpty{
            recordingsActionButton.isHidden = true
            self.selectAllButton.isHidden = true
            progressBar.isHidden = true
        }else {
            recordingsActionButton.isHidden = false
            self.selectAllButton.isHidden = false
        }
    }

The error is here:

let start = fileName.index(fileName.startIndex, offsetBy: 26)

Many thanks in advance!

From the documentation for the index(_:offsetBy:) function:

The value passed as distance must not offset i beyond the bounds of the collection.

Clearly this is what’s causing your error. You shouldn’t be assuming that this is a valid index for every fileName you might have. You will need to code defensively around those lines to ensure you don’t crash. It’s almost never a good idea to rely on hardcoded indices like that.

1 Like