1

I have a URL in the form of

foo://?data:application/x-foo;base64,OjAyMDAwMDA0MDAwMEZBDQo6MTAwMDA...

and now need to extract the base64 data into a Data object.

Unfortunately it seems the Data object does not support this yet as

let data = try Data(contentsOf: url)

returns NSURLConnection finished with error - code -1002 when trying.

While I could decode the URL manually I am wondering if I am missing a simple standard way of doing this. How would you do this?

tcurdt
  • 14,518
  • 10
  • 57
  • 72
  • Possible duplicate of [How to convert base64 into NSDATA in swift](https://stackoverflow.com/questions/39206139/how-to-convert-base64-into-nsdata-in-swift) – Tamás Sengel Sep 26 '17 at 14:40
  • Not really as that is just about base64 conversion, @the4kman – tcurdt Sep 26 '17 at 14:49

2 Answers2

2

Actually you can decode Base64 data from an URL (see for example Base64 Decoding in iOS 7+ where this is demonstrated in Objective-C). The format is a bit different from what you have:

let url = URL(string: "data:application/octet-stream;base64,SGVsbG8gd29ybGQh")!
let data = try! Data(contentsOf: url)

print(String(data: data, encoding: .utf8)!) // Hello world!

(Error checking omitted for brevity.)

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
0

You have to separate the base64 encoded part of the URL from the other parts, decode it, then join the original non-encoded part with the decoded part and get the data from there.

extension URL {
    init?(partialBase64Url: String){
        guard let base64part = base64Url.components(separatedBy: "base64,").last, let base64Data = Data(base64Encoded: base64part), let decodedString = String(data: base64Data, encoding: .utf8) else {
            return nil
        }
        let decodedUrl = base64Url.components(separatedBy: "base64,").dropLast().joined() + decodedString
        self.init(string: decodedUrl)
    }
}

let decodedUrl = URL(partialBase64Url: "foo://?data:application/x-foo;base64,dGVzdFVybFN0cmluZw==")

Value of decodedUrl: "foo://?data:application/x-foo;testUrlString", as expected, since dGVzdFVybFN0cmluZw== is the base64 encoded value of testUrlString.

Dávid Pásztor
  • 51,403
  • 9
  • 85
  • 116
  • So essentially you are saying there is no easier way but doing this manually. (Thanks for the example) – tcurdt Sep 26 '17 at 15:06
  • AFAIK there's not automatic method for downloading data from a partially encoded URL, so yes, you have to do it manually. – Dávid Pásztor Sep 26 '17 at 15:10
  • @tcurdt check my updated answer, I created a failable initializer for URL using the decoding function, this might be more convenient for you. – Dávid Pásztor Sep 26 '17 at 15:16
  • While your code does work fine, too it really is the manual solution. Martin's answer provides the automatic method. Thanks anyway! – tcurdt Sep 26 '17 at 15:54