Декодирование строки base64 идет не так быстро в Swift - PullRequest
0 голосов
/ 26 августа 2018

Контекст таков: я написал приложение, которое может выбрать изображение из вашей библиотеки, а затем оно конвертирует изображение в строку base64 следующим образом:

    let imageData:NSData = UIImageJPEGRepresentation(self.myImageView.image!, 0.1)! as NSData
    let strBase64 = imageData.base64EncodedString(options: .lineLength64Characters)

Здесь myImageView - это место, где хранится изображение, когда выбирается изображение. Затем я загрузил это в мою локальную базу данных MySQL, где у меня есть столбец типа MEDIUMTEXT. Затем я написал приложение, которое могло бы получить эту строку из базы данных, но когда я захотел декодировать ее и снова сделать ее UIimage, моя программа не удалась. Вот что я попробовал:

    let dataDecoded:NSData = NSData(base64Encoded: tempString64, options: NSData.Base64DecodingOptions(rawValue: 0))!
    let decodedimage:UIImage = UIImage(data: dataDecoded as Data)!

Здесь tempString64 - это строка, которую я получил из базы данных (я также проверил, что она не пустая). Если я запускаю приложение, я получаю сообщение об ошибке, что dataDecoded был равен нулю при попытке развернуть его. Я действительно не понимаю, почему это ноль, в то время как моя tempString действительно там.

Спасибо.

UPDATE: Я перепробовал много вещей, но это не работает! Вот соответствующая часть кода, которую я сейчас использую внутри URLSession:

   if data != nil {
            do {
                let imagesJSON =  try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! NSDictionary
                let images : NSArray = imagesJSON["images"] as! NSArray
                let temp : NSArray = images[0] as! NSArray
                var tempString64 : String = temp[0] as! String
                // I found a question on this site that said that the string should be of length multiple of 4, the following does that.
                let remainder = tempString64.count % 4
                if remainder > 0 {
                    tempString64 = tempString64.padding(toLength: tempString64.count + 4 - remainder,
                                                  withPad: "=",
                                                  startingAt: 0)
                }
                //check if string is not nil
                print(tempString64)

                let dataDecoded = Data(base64Encoded: tempString64)
                let decodedimage = UIImage(data: dataDecoded!)

               DispatchQueue.main.async {
                    self.myImageView.image = decodedimage
                }

            } catch {
                print(error)
            }
        }

Хвост tempString64

wBr9KavclvUrxPlNp6ircQ5qNLTDfe/Sr8Vvj L9KqS0BbEM2AKz2rXmt8j736VRNr/ALX6UJEmcv3qnPSpRZ/N979Kn y8fe/SqKiZhNJV1rP/AGv0pPsf 1 lEkJlFhkYpAoQe9aH2Pj736VE1n/t/pTV7DRXjPzVpL0qGCy5yX/StEW2B979KLFrYzpadafxfhU8ltn L9Kktrbbu b07Uraktn/2Q==

Длина tempString64 составляет 13752

1 Ответ

0 голосов
/ 26 августа 2018

Проблема вызвана опцией lineLength64Characters.Если указана эта опция, вам нужно декодировать данные с помощью опции ignoreUnknownCharacters

let dataDecoded  = Data(base64Encoded: tempString64, options: .ignoreUnknownCharacters)!

Но гораздо проще пропустить все опции.В любом случае, база данных не заботится о хорошем форматировании.

let strBase64 = imageData.base64EncodedString()

...

let dataDecoded  = Data(base64Encoded: tempString64)!

ОБНОВЛЕНИЕ:

Удалите код заполнения и безопасно получите закодированную строку.API обрабатывает заполнение для вас.

Не используйте NSArray и NSDictionary в Swift, используйте безопасные типы нативного типа.И никогда используйте .mutableContainers, в частности, вы присваиваете значение изменяемой константе im .Опция бессмысленна в Swift.

 if let data = data {
    do {
        if let imagesJSON =  try JSONSerialization.jsonObject(with: data) as? [String:Any],
           let images = imagesJSON["images"] as? [Any],
           let temp = images.first as? [String],
           let tempString64 = temp.first {

           print(tempString64)

           let dataDecoded = Data(base64Encoded: tempString64)
           let decodedimage = UIImage(data: dataDecoded!)

           DispatchQueue.main.async {
               self.myImageView.image = decodedimage
           }
       }

    } catch {
        print(error)
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...