4

I have a swift app and I'm trying to use rich links.

I first detect a link in some dynamic text using the following:

do {
    let detector = try NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue)
    let matches = detector.matches(in: text, options: [], range: NSRange(location: 0, length: text.utf16.count))
    if let match = matches.first {
        guard let range = Range(match.range, in: text) else { return }
        let uRLString = text[range]
        // .. use
    }
} catch {
    print(error)
}

This works fine and I'm able to get all the links in the text. But sometimes the links are in the form example.com instead of https://example.com or http://example.com etc..

In order to use rich text, I need to pass the link to the following method to get the metadata:

func fetchMetadata(for link: String, completion: @escaping (Result<LPLinkMetadata, Error>) -> Void) {

    guard let uRL = URL(string: link.lowercased()) else { return }
    let metadataProvider = LPMetadataProvider()
    metadataProvider.startFetchingMetadata(for: uRL) { (metadata, error) in
        if let error = error {
            print(error)
            completion(.failure(error))
            return
        }

        if let metadata = metadata {
            completion(.success(metadata))
        }
    }
}

This function only works if the link is provided with http or https. So I decided to add http to the link using the following:

extension URL {
    
    var sanitise: URL {
        if var components = URLComponents(url: self, resolvingAgainstBaseURL: false) {
            if components.scheme == nil {
                components.scheme = "https"
            }
            return components.url ?? self
        }
        return self
    }
}

and now it works if I use uRL.sanitize instead of uRL.

Now I have two problems. The first is for those sites that use http this will not work and if I use https as scheme then those sites that don't forward http to https will not work.

And second in the rich link the link appears as: http:example.com without the slashes (//).

I wonder if there is a better way of going about this. I suppose I can resolve the http / https part by sanitizing for the other one if an error is returned. But I feel like I'm going about this all wrong.

alionthego
  • 8,508
  • 9
  • 52
  • 125

0 Answers0