4

I have a AVMetadataItem which has fields encoded in CP1251 (Cyrillic). After reading item.stringValue I get garbage - incorrectly encoded string. I've tried converting that string to raw UTF8 and then creating a new string using the CP1251 encoding - no luck, result is nil. Tried taking the item.dataValue - no dice, it contains a raw list data (starting with bplist...).

Any ideas are very appreciated.

Thanks in advance.

reflog
  • 7,587
  • 1
  • 42
  • 47
  • Tried comparing at the actual bytes of the utf8 decoded item.stringValue with the bytes of the original CP1251-decoded metadata string? Since it didn't work for you they probably won't be the same, but maybe you can find some hint. – Danra Mar 16 '12 at 23:45
  • Does it work if you do the decoding yourself, getting the item's dataValue instead of stringValue and decoding it with [[NSString alloc] initWithData:encoding:]? If that doesn't do it, can you add the garbage string to this question so that we can sort out what encodings it's been mangled with? – davehayden Mar 20 '12 at 05:12
  • No it didn't work for me. But I'll try to post the hex values of the data I get from dataValue. – reflog Mar 20 '12 at 13:57

4 Answers4

3

Swift 2.0 solution:

let origTitleMeta: NSData = (<AVMetadataItem>.timedMetadata?.first?.stringValue?.dataUsingEncoding(NSISOLatin1StringEncoding, allowLossyConversion: true))!

let convertedTitleMeta: String = String(data: origMeta, encoding: NSUTF8StringEncoding)!
Mugurel
  • 1,829
  • 3
  • 17
  • 26
2

I have AVMetadataItem extension for this:

extension AVMetadataItem {

    /// stringValue: ISO-8859-1 → UTF-8
    var utf8String: String? {
        guard let data = stringValue?.data(using: String.Encoding.isoLatin1, allowLossyConversion: true) else {
            return nil
        }
        return String(data: data as Data, encoding: String.Encoding.utf8)
    }
}
Victor Do
  • 2,237
  • 1
  • 13
  • 9
2

I've ended up using Mike Ash's NSPropertyListReader_binary1 and getting the raw data and then mangling it so that NSString would it it's encoding.

Horrible - but worked.

reflog
  • 7,587
  • 1
  • 42
  • 47
  • Ah, interesting. Does it look like it was just an error in decoding the string, or was it mangling the data somehow? – davehayden Mar 21 '12 at 04:40
  • There's the thing - inside the MP3 the ID3 tag was CP1251 encoded (I checked the binary file), but after reading it using the AVAsset - the data is interpreted as UTF16 - thus mangling the data. I used the custom plist reader to get the actual data and de-mangle it manually. – reflog Mar 21 '12 at 08:16
  • @reflog - Could you please post the solution you've found using NSPropertyListReader_binary1 or have a quick look at my question (http://stackoverflow.com/questions/16001847/correct-encoding-for-id3-tags-in-ios)? I've faced the same problem and spent a lot of time trying to solve it. Thanks in advance! – NikGreen Apr 17 '13 at 03:45
1

Swift 3.0 solution:

let data: Data = item.timedMetadata!.first!.stringValue.data(using: String.Encoding.isoLatin1, allowLossyConversion: true)!

let title: String = String(data: data as Data, encoding: String.Encoding.utf8)!
nullproduction
  • 576
  • 3
  • 18