1

Exactly as explained here, https://stackoverflow.com/a/30624755/294884

[It is a mistake to think that] the JPEG representation of an image is a UTF-8-encoded string. It's not. It's arbitrary binary data. UTF-8 strings aren't arbitrary sequences of bytes; there are rules about what bytes can follow other bytes.

In fact, how do you best make a utf8 data from an image, in the Data era?

The everyday use case is in a http form.

I do something like this,

    formData.append( "Content-Disposition etc".(using: .utf8)! )
    formData.append( "Content type etc".(using: .utf8)! )

    // now let's add a #@@%$%$% image

    let trueBinary = UIImageJPEGRepresentation(i, 0.10)!
    print("the size seems to be \(trueBinary.count)")
    
    let mystere = trueBinary.base64EncodedString(
                  options: .lineLength76Characters)
    
    formData.append( mystere.data(using: .utf8)! )

But

A, that seems poxy, and probably doesn't work anyway.

B, the "lineLength" concept means nothing to me, so I just guess stuff, and type something in there.

Note that, incredibly confusingly, if you have a Data x and you add to x a few strings as utf8 using append ..... And then you add a 'real' binary data, such as a jpeg representation to x ...... in fact it nils "x" - ouch! (It doesn't just "not add the binary one", it scratches x to nothing.)

Community
  • 1
  • 1
Fattie
  • 27,874
  • 70
  • 431
  • 719
  • As a curiosity, the latest version of AlamoFire seems to "make this mistake": if you use (as most people would) their convenience routine where you pass a file name, it seems to convert it the correct way. But if you pass in an image, my initial investigations are that they "forget", as it were, to make it a utf8 data, and you get nothing. – Fattie May 05 '17 at 15:31
  • 2
    Just convert your data to base64 string – Leo Dabus May 05 '17 at 15:36
  • but how, master Jedi? – Fattie May 05 '17 at 15:40
  • 2
    What do you mean ? `data.base64EncodedString().utf8` – Leo Dabus May 05 '17 at 15:42
  • 3
    Or just `data.base64EncodedData()` – Hamish May 05 '17 at 15:45
  • For any googlers: what Hamish's excellent tip means is, you can just **yourData.append( what Hamish said )**, rather than getting the image as a string S, and then **yourData.append( S converted to utf8 using what Leo said )** – Fattie May 05 '17 at 16:03
  • @Hamish Do you know since when this was implemented ? http://stackoverflow.com/a/43811912/2303865 – Leo Dabus May 05 '17 at 18:50
  • 1
    @LeoDabus You mean concrete same-type requirements? (i.e `extension ConcreteType where X == Y {...}`). It was indeed introduced in Swift 3.1 (you can find it listed in [the Xcode release notes](https://developer.apple.com/library/content/releasenotes/DeveloperTools/RN-Xcode/Chapters/Introduction.html)). – Hamish May 05 '17 at 18:55
  • @Hamish Thanks I thought it was gonna be introduced in Swift 4 – Leo Dabus May 05 '17 at 18:56

1 Answers1

3

This line has a problem:

let mystere = trueBinary.count.base64EncodedString(
              options: .lineLength76Characters)

The problem is that trueBinary is a Data, and trueBinary.count is an Int, and Int doesn't have a base64EncodedString method. You want this:

let mystere = trueBinary.base64EncodedString(
              options: .lineLength76Characters)

As for ‘the "lineLength" concept’: you don't have to specify a line length option if you don't want to. Arguably I shouldn't have specified one in the answer you referenced in your question, because HTTP requests are not strictly MIME messages and are not subject to the MIME line length limit. You can do this instead:

let mystere = trueBinary.base64EncodedString()
Community
  • 1
  • 1
rob mayoff
  • 375,296
  • 67
  • 796
  • 848