Search code examples
swiftnsattributedstring

How can I append value if NSAttributedstring contains external link?


Hi I'm trying to get html from a website. It has internal and external links. How can I append string if link is external link. By the way internal links has applewebdata:// and I check those ones as internal. But I couldn't understand how can I detect external links. I want just add something like that » .

Internal link href: applewebdata:// External link href contains http:// or https://

An example in here


Solution

  • Here what you could do:
    Enumerate the link attribute.
    Check for each value if it's the one you want (the one that starts with "applewebdata://").
    Modify either the rest of the string and/or the link (your question is unclear on that part, I made both).

    attributedString needs to be mutable (NSMutableAttributedString).

    attributedString.enumerateAttribute(.link, in: NSRange(location: 0, length: attributedString.length), options: [.reverse]) { (attribute, range, pointee) in
        if let link = attribute as? URL, link.absoluteString.hasPrefix("applewebdata://") {
            var replacement = NSMutableAttributedString(attributedString: attributedString.attributedSubstring(from: range))
    
            //Use replaceCharacters(in range: NSRange, with str: String) if you want to keep the same "effects" (attributes)
            replacement.replaceCharacters(in: NSRange(location: replacement.length, length: 0), with: "~~>")
    
            //Change the link if needed
            let newLink = link.absoluteString + "2"
            replacement.addAttribute(.link, value: newLink, range: NSRange(location: 0, length: replacement.length))
    
            //Replace
            attributedString.replaceCharacters(in: range, with: replacement)
        }
    }
    

    Code for Playground to put before if needed:

    let htmlString = "Hello this <a href=\"http://stackoverflow.com\">external link</a> and that's an <a href=\"applewebdata://myInternalLink\">internal link</a> and that's it."
    let htmlData = htmlString.data(using: .utf8)!
    let attributedString = try! NSMutableAttributedString(data: htmlData,
                                                          options: [.documentType : NSAttributedString.DocumentType.html],
                                                          documentAttributes: nil)