来自base64编码字符串的Swift NSData返回nil

问题描述 投票:0回答:5

我正在与 Swift 中的服务器通信以检索图像数据。传入的数据被编码为 base64 字符串。我能够正确接收并显示编码的字符串。当我使用

NSData
类将字符串解码回二进制数据并显示时...

println(NSData(base64EncodedString: imageString, options: NSDataBase64DecodingOptions(0)))

输出是

nil
nil
nil
nil
nil
nil

每一张收到的图像。

我也尝试过

println(NSData(base64EncodedString: imageString, options: nil))

和相同的结果。我这一路上有什么遗漏的吗??我会把图像字符串放上去,但它们太长了......

swift base64 nsdata
5个回答
21
投票

对于可能遇到此问题的其他人,请确保您的 Base64 编码字符串的长度可被 4 整除(应使用

=
来填充长度)。

请参阅此处的 StackOverflow 答案:https://stackoverflow.com/a/36366421/330494


11
投票

尝试使用 IgnoreUnknownCharacters 选项。

或者尝试使用 NSDataAdditions

中的 initWithBase64EncodedString

5
投票

根据 Frank Schmitt 和 Barlow Tucker 的答案,我创建了

Data
的扩展,以更好地处理 base64 编码:

extension Data {
    static func decodeUrlSafeBase64(_ value: String) throws -> Data {
        var stringtoDecode: String = value.replacingOccurrences(of: "-", with: "+")
        stringtoDecode = stringtoDecode.replacingOccurrences(of: "_", with: "/")
        switch (stringtoDecode.utf8.count % 4) {
            case 2:
                stringtoDecode += "=="
            case 3:
                stringtoDecode += "="
            default:
                break
        }
        guard let data = Data(base64Encoded: stringtoDecode, options: [.ignoreUnknownCharacters]) else {
            throw NSError(domain: "decodeUrlSafeBase64", code: 1,
                        userInfo: [NSLocalizedDescriptionKey: "Can't decode base64 string"])
        }
        return data
    }
}

所以在你的代码中,你可以像这样使用它:

let baseEncodeText = "(.....)" //your base64 encoded string
let data = try Data.decodeUrlSafeBase64(baseEncodeText)

4
投票

如果输入是所谓的“URL 安全”Base64 数据,也可能发生这种情况。该数据将

+
符号替换为
-
符号,将
/
符号替换为
_
符号。

幸运的是,转换它很简单:

inputString = [[inputString stringByReplacingOccurrencesOfString:@"-" withString:@"+"] stringByReplacingOccurrencesOfString:@"_" withString:@"/"];

维基百科上提供了完整的变体列表。


0
投票

为了确保Base64字符串的长度是4个字符的倍数,请使用以下函数。此函数用“=”字符填充字符串以达到所需的固定长度。建议在解码 Base64 字符串之前应用此方法。

extension String {
    var paddedBase64String: Self {
        let offset = count % 4
        guard offset != 0 else { return self }
        return padding(toLength: count + 4 - offset, withPad: "=", startingAt: 0)
    }
}

使用示例:

// Ensure the Base64 string has a fixed-length format
let paddedBase64String = base64String.paddedBase64String

填充 Base64 字符串后,使用 pusedBase64String 进行解码以确保行为一致。

© www.soinside.com 2019 - 2024. All rights reserved.