Possible solution:
let str:String = "<a href=\"https://stackoverflow.com/1\"> @username1 </a><a href=\"https://stackoverflow.com/2\"> @username2 </a><a href=\"https://stackoverflow.com/3\"> @username3 </a><a href=\"https://stackoverflow.com/4\" >@username4 </a>"
Create AttributedString from the HTML String
let attributedString = try NSAttributedString(data: str.data(using: .utf8)!,
                                              options: [.documentType: NSAttributedString.DocumentType.html],
                                              documentAttributes: nil)
I used URL objects for the key, but could be String (then in the closure you have to change it, using result.append([link.absoluteString:subStr]) instead)
var result = [[URL:String]]()
attributedString.enumerateAttribute(.link, in: NSRange(location: 0, length: attributedString.string.count), options: []) { (value, range, pointer) in
    if let link = value as? URL {
        let subStr = (attributedString.string as NSString).substring(with: range)
        result.append([link:subStr])
    }
}
print("result: \(result)")
Output:
$>result: [["https://stackoverflow.com/1": "@username1 "], ["https://stackoverflow.com/2": "@username2 "], ["https://stackoverflow.com/3": "@username3 "], ["https://stackoverflow.com/4": "@username4 "]]