Swift function to interpret Roman numerals (ported from JavaScript)
Let's do this from inside out. temp.starts(with: glyph) is correct, but
there is also a dedicated method temp.hasPrefix(glyph) for strings.

The loop to find the first dictionary entry with a matching prefix
can be shortened to

guard let (glyph, quantity) = dict.first(where: { temp.hasPrefix($0.glyph) }) else {
    throw RomanNumericError.badInput(original: original, temp: temp)
}


(also making the var found obsolete.)

Mutating the temporary string can be avoided by working with a SubString (which is a kind of view into the original string) and
only updating the current search position:

var pos = original.startIndex
while pos != original.endIndex {
    let subString = original[pos...]
    // ...
    pos = original.index(pos, offsetBy: glyph.count)
}


Naming: This is very opinion-based, here are my opinions:


Declare the function as func romanToInt(_ roman: String),
so that it is called without (external) argument name:
romanToInt("MMXIV").
Rename var int to var value.
dict is also a non-descriptive name (and it is not even a dictionary), something like glyphsAndValues might be a better choice.


Summarizing the suggestions so far, we have

func romanToInt(_ roman: String) throws -&gt; Int {
    var value = 0
    var pos = roman.startIndex
    while pos != roman.endIndex {
        let subString = roman[pos...]
        guard let (glyph, quantity) = glyphsAndValues.first(where: { subString.hasPrefix($0.glyph) }) else {
            throw RomanNumericError.badInput(roman: roman, at: subString)
        }
        value += quantity
        pos = roman.index(pos, offsetBy: glyph.count)
    }
    return value
}




Now the error handling. Yes, throwing an error is a good and Swifty
way to report a failure to the caller. (An alternative is to return an
optional value which is nil in the error case, but that does not
allow to provide additional error information.)

The creation of the error message however should be done in the
error class, by adopting the LocalizedError protocol:

enum RomanNumericError: Error {
    case badInput(roman: String, at: Substring)
}

extension RomanNumericError: LocalizedError {
    public var errorDescription: String? {
        switch self {
        case .badInput(let roman, let at):
            return "Error parsing roman numeral '\(roman)' at '\(at)'"
        }
    }
}


The big advantage is that the caller does not need to know which
error the function throws, and can catch a generic Error:

do {
    try print(romanToInt("MMXIV"))
    try print(romanToInt("MMYXIV"))
} catch {
    print(error.localizedDescription)
}

// Output:
//   2014
//   Error parsing roman numeral 'MMYXIV' at 'YXIV'