Parse data into an array of structs
This

let filePath = Bundle.main.path(forResource: "test", ofType: "dat")
guard filePath != nil else { return }
let fileURL = URL(fileURLWithPath: filePath!)


is an anti-pattern in Swift, see also When should I compare an optional value to nil? on Stack Overflow. Instead of testing a value against nil and then force-unwrapping it, you should use optional binding:

guard let filePath = Bundle.main.path(forResource: "test", ofType: "dat") else { return }
let fileURL = URL(fileURLWithPath: filePath)


This can be further simplified by retrieving an URL in the first place, instead of getting a file path and converting that to an URL:

guard let fileURL = Bundle.main.url(forResource: "test", withExtension: "dat")
    else { return }


But actually this is a situation where I would prefer force-unwrapping: A missing resource file in the application bundle is a programming error and there is no way of recovering from that situation in a sensible way. It should be detected early during development:

let fileURL = Bundle.main.url(forResource: "test", withExtension: "dat")!


The same reasoning applies to reading and decoding the file:

let file = try! String(contentsOf: fileURL, encoding: .utf8)


Using split() here

let arrayOfLines = file.split { $0.isNewline }


is good: It creates an array, but the array elements are substrings, i.e. they contain references into the character storage of the original file string. The same method can be applied to split each line to avoid data duplication:

for line in arrayOfLines {
    let arrayOfItems = line.split(separator: ",")
    // ...
}


This

let tempPerson = Person(id: Int(arrayOfItems[0])!,
                        first: arrayOfItems[1].replacingOccurrences(of: "\"", with: ""),
                        last: arrayOfItems[2].replacingOccurrences(of: "\"", with: "")


would crash if a line has less than 3 comma-separated items, or if the first item is not an integer. However, as mentioned above, this is acceptable if the data is read from your own resource file (and not from some external resource): We can rely on the data to be well-formed.

It is a bit difficult to read though, and I would split the single statement into parts:

let id = Int(arrayOfItems[0])!
let firstName = arrayOfItems[1].replacingOccurrences(of: "\"", with: "")
let lastName = arrayOfItems[2].replacingOccurrences(of: "\"", with: "")
let tempPerson = Person(id: id, first: firstName, last: lastName)


With respect to removing the delimiters: What you do is fine if the data file has exactly the format from your example, and there are no embedded quotation marks or commas in the fields. An alternative is

let firstName = String(arrayOfItems[1].dropFirst().dropLast())
let lastName = String(arrayOfItems[2].dropFirst().dropLast())


which might be slightly more efficient because it does not need bridging to NSString. (But I did not measure it.)

Finally note that your code does not parse all valid CSV files. Problems are for example


embedded commas: 4,"Sammy","Davis, Jr."
embedded quotation  marks: 5,"John","Foo""Bar"
or embedded newlines.


Before you try to implement all those features yourself I would suggest to have a look at some existing Swift CSV parsing libraries.