Zac
Zac

Reputation: 831

How can I convert a string, such as "iso-8859-1", to it's String.Encoding counterpart?

After sending a HTTP request from Swift, I get a field in the response called textEncodingName.

I want to convert the data object I also received into a string containing its contents, and to do this, I'm using String(data: data!, encoding: .utf8). This works most of the time, because most websites are UTF-8 encoded. But with, for example, https://www.google.co.uk, the response.textEncodingName == "iso-8859-1".

I guess other websites would use even more obscure encodings, so my question is this: how can I find the right encoding to convert my data object to the correct string.

Upvotes: 3

Views: 5410

Answers (4)

virantporwal
virantporwal

Reputation: 987

In Swift You can use:

guard let string =  String(data: data, encoding: .isoLatin1) else {return}

guard let perfectData = string.data(using: .utf8, allowLossyConversion: true) else {return}

Upvotes: 1

rmaddy
rmaddy

Reputation: 318774

You can simply try String.Encoding.windowsCP1250 for iso-8859-1. Please refer https://en.wikipedia.org/wiki/Windows-1250

String(data: data, encoding: .windowsCP1250)

OR..

I found a few steps that will take you from the textEncodingName to the corresponding String.Encoding value:

let estr = "iso-8859-1"
let cfe = CFStringConvertIANACharSetNameToEncoding(estr as CFString)
let se = CFStringConvertEncodingToNSStringEncoding(cfe)
let encoding = String.Encoding(rawValue: se)

This is largely based on the documentation for URLResponse.textEncodingName:

You can convert this string to a CFStringEncoding value by calling CFStringConvertIANACharSetNameToEncoding(:). You can subsequently convert that value to an NSStringEncoding value by calling CFStringConvertEncodingToNSStringEncoding(:).

Here's an update that checks to see if the original text encoding string is valid or not:

let estr = "XXX"
let cfe = CFStringConvertIANACharSetNameToEncoding(estr as CFString)
if cfe != kCFStringEncodingInvalidId {
    let se = CFStringConvertEncodingToNSStringEncoding(cfe)
    let sse = String.Encoding(rawValue: se)
    print("sse = \(sse)")
} else {
    print("Invalid")
}

Upvotes: 8

Anton Belousov
Anton Belousov

Reputation: 1141

In swift you can use:

func getTextFrom(_ url: URL) -> String?  {
    guard let data = try? Data(contentsOf: url) else {
        return nil
    }
    return String(data: data, encoding: .utf8) ??
        String(data: data, encoding: .isoLatin1)
}

Upvotes: 0

jscs
jscs

Reputation: 64002

I would write an enum with a String raw value and a computed property to return the appropriate String.Encoding value. Then you can use its init(rawValue:) to create an instance.

import Foundation

enum APITextEncoding : String
{
    case iso8859_1 = "iso-8859-1"
    // etc.

    var encoding: String.Encoding
    {
        switch self
        {
            case .iso8859_1:
                return .isoLatin1
            // etc.
        }
    }
}

let receivedEncoding = APITextEncoding(rawValue: encodingDescription)
let receivedText = String(data: receivedData, encoding: receivedEncoding.encoding)

Upvotes: 1

Related Questions