I am very confused on this one. I had been thinking it was something wrong with my server, but after testing it seems as though using Data(base64encoded: data) is producing nil even though the data is there and is in fact base64encoded. I have tried everything I can think of and nothing is working. Here is the code I am using and the output...
do {
print("DATA as a string: ", String(data: data!, encoding: .utf8) ?? "NONE AVAILABLE")
let decodedData = Data(base64encoded: data!, options: .ignoreUnknownCharacters)
print("DECODED DATA: ")
print(decodedData as Any)
let apiResponse = try JSONDecoder().decode(ApiConnectionResponse.self, from: decodedData!)
completion(.success(apiResponse))
} catch {
completion(.failure(error))
}
The output from that is...
Data as string: eyJzdWNjZXNzIjoiZmFsc2UiLCJlcnJvciI6Im1vYmlsZV9waW5fY29ubmVjdDogaW52YWxpZCBvciBleHBpcmVkIn0.
DECODED DATA: nil
So the String is a legit base64encoded string, it decodes to
{"success":"false","error":"mobile_pin_connect: invalid or expired"}
However the decoded data is nil. I don't understand, how can it be nil when the string is a base64encoded string and is not nil. I have even tried forcing the string in there like so...
let decodedData = Data(base64encoded: String(data: data!, encoding: .utf8))
Still no luck. It is throwing a fatal error, and I can see in the section at the bottom of Xcode that the data is in fact "(Data?) 92 bytes" What I can't figure out is why it is nil after running through Data()...
Any help would be greatly appreciated, I am really lost and can't figure out why I can make the string, but not the data.
The end result of this is, I need to get JSONDecoder().decode to work with the reply from the server, I think I can get that part done, if I can figure out why it is nil after the data call. Thank you.
You need to check your data length, divide by 3 and in case the result is not zero add one or two bytes (65) =
equal sign for padding your data. Try like this:
let decodedData = Data(base64Encoded: data + .init(repeating: 65, count: data.count % 3))
extension Data {
var base64encodedDataPadded: Data {
let data = last == 46 ? dropLast() : self
return data + .init(repeating: 65, count: data.count % 3)
}
}
Playground testing:
let data = Data("eyJzdWNjZXNzIjoiZmFsc2UiLCJlcnJvciI6Im1vYmlsZV9waW5fY29ubmVjdDogaW52YWxpZCBvciBleHBpcmVkIn0.".utf8)
let decodedData = Data(base64Encoded: data.base64encodedDataPadded)!
print(String(data: decodedData, encoding: .utf8)!) // "{"success":"false","error":"mobile_pin_connect: invalid or expired"}"