У меня есть приложение iOS, которое получает изображение в виде строки в кодировке base64 из API. (Я знаю, что, возможно, это не лучшее решение, но это не вопрос).
Когда я декодирую эту строку, чтобы создать UIImage со следующим кодом:
// If don't don't append "=" I'll get nil data in the next line: (string.count % 4 == 0) is required
let stringWithEquals:String = getMyString() + "="
let data = Data.init(base64Encoded: stringWithEquals, options: .ignoreUnknownCharacters)!
self.myPicture.image = UIImage(data: data )
Возвращенный изображение обрезано (я добавил красный фон только для развивающих целей):
Как видите, я получаю ошибка, говорящая о том, что «Не удалось преобразовать UIImage в PNG» .
Поэтому в этот момент я начал думать, что, возможно, в моем коде произошла ошибка. Возможно, я получил неполную строку или был какой-то недостающий шаг в декодировании. Поэтому я спросил бэкэнда, и он подтвердил, что строка верна. Также я проверил со своим коллегой, который работает над версией Android, и та же строка правильно работает в его приложении.
Итак, я проверил строку в онлайн-декодере и нашел тот же обрезанный результат использования Safari Версия 13.0.5 (15608.5.11), но полное изображение с использованием Firefox:
WTF !
Я тестировал его с одинаковым результатом на нескольких веб-декодерах:
ОК, поэтому я попытался загрузить изображение с Firefox и попробуй сам кодировать / декодировать, но удиви! Я вижу изображение, но не могу загрузить его полностью на моем Ма c.
Это изображения, загруженные с Firefox в png и jpg
Я пытался найти решение в Google и на нескольких форумах, включая множество вопросов о StackOverflow, но с этим ничего не связано.
Обратите внимание на следующие моменты:
- Возвращенные данные декодирования не равны . Я добавляю символы «=» в конце строки, чтобы длина строки% 4 == 0 . Я нашел много вопросов по этой проблеме, я могу декодировать изображение, но обрезано.
- Я на 100% уверен, что строка завершена, я проверил ее с моим бэкэндом и android коллегами.
- Кажется, проблема связана с в среде Apple я не вижу изображения в своем приложении iOS ни в Safari, но вижу в Firefox, работающем на компьютере Ma c. Также это происходит не только на моем компьютере. Некоторые другие коллеги тестировали в своих iPhone с таким же результатом.
Строка base64 действительно длинная (я вставлю ее ниже). Поэтому я попытался декодировать половину строки, просто чтобы убедиться, что проблема не связана с размером, и я нашел что-то cur ios. Если я декодирую только половину строки, я также получаю обрезанный результат:
let stringWithEquals:String = getMyString().prefix(getMyString().count/2) + "="
Я не знаю, правильное ли это приближение, но Я попробовал.
Я пытался найти решение, используя функцию Objective- C, но результат был таким же:
-(NSData *)base64DataFromString: (NSString *)string{
unsigned long ixtext, lentext;
unsigned char ch, inbuf[4], outbuf[3];
short i, ixinbuf;
Boolean flignore, flendtext = false;
const unsigned char *tempcstring;
NSMutableData *theData;
if (string == nil){
return [NSData data];
}
ixtext = 0;
tempcstring = (const unsigned char *)[string UTF8String];
lentext = [string length];
theData = [NSMutableData dataWithCapacity: lentext];
ixinbuf = 0;
while (true){
if (ixtext >= lentext){
break;
}
ch = tempcstring [ixtext++];
flignore = false;
if ((ch >= 'A') && (ch <= 'Z')){
ch = ch - 'A';
}else if ((ch >= 'a') && (ch <= 'z')){
ch = ch - 'a' + 26;
}else if ((ch >= '0') && (ch <= '9')){
ch = ch - '0' + 52;
}else if (ch == '+'){
ch = 62;
}else if (ch == '='){
flendtext = true;
}else if (ch == '/'){
ch = 63;
}else{
flignore = true;
}
if (!flignore){
short ctcharsinbuf = 3;
Boolean flbreak = false;
if (flendtext){
if (ixinbuf == 0){
break;
}
if ((ixinbuf == 1) || (ixinbuf == 2)){
ctcharsinbuf = 1;
}else{
ctcharsinbuf = 2;
}
ixinbuf = 3;
flbreak = true;
}
inbuf [ixinbuf++] = ch;
if (ixinbuf == 4){
ixinbuf = 0;
outbuf[0] = (inbuf[0] << 2) | ((inbuf[1] & 0x30) >> 4);
outbuf[1] = ((inbuf[1] & 0x0F) << 4) | ((inbuf[2] & 0x3C) >> 2);
outbuf[2] = ((inbuf[2] & 0x03) << 6) | (inbuf[3] & 0x3F);
for (i = 0; i < ctcharsinbuf; i++){
[theData appendBytes: &outbuf[i] length: 1];
}
}
if (flbreak){
break;
}
}
}
return theData;
}
Итак на данный момент я полностью потерян. Почему это происходит?
А вот и дамба base64 Строка
СТРЕЛА ДАММА НА ГИТУБЕ