如何在Swift中将base64字符串转换为字符串?

55

我从webservice响应中获得了一个base64String并将其存储在NSData中,如何在Swift中将该base64String转换为字符串?

    //Code
    var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as! NSDictionary  // Response JSON from webservice
    var base64String : String = ""
    base64String = jsonResult["Base64String"] as! String  // Retrieve base64String as string from json response
    println("Base64String Alone: \(base64String)")

// Code to decode that base64String
let decodedData = NSData(base64EncodedString: base64String, options: NSDataBase64DecodingOptions(rawValue: 0))
                                    println("Decoded:  \(decodedData)")
                                    let decodedString = NSString(data: decodedData!, encoding: NSUTF8StringEncoding)
                                    println(decodedString) // Prints nil

如果一个文件只包含文本,则base64String的编码和解码正常工作,但如果文件包含一些表格格式/图像,则编码和解码都会产生无效的base64String。如何将文件转换为base64String编码,并对文件内容进行编码和解码?

支持的文件格式为doc、docx、pdf、txt。

提前感谢任何帮助!

5个回答

141

试试这个:

let base64Encoded = "YW55IGNhcm5hbCBwbGVhc3VyZS4="

var decodedString = ""
if let decodedData = Data(base64Encoded: base64Encoded) {
    decodedString = String(data: decodedData, encoding: .utf8)!
}

if !decodedString.isEmpty {
    print(decodedString)
} else {
    print("Oops, invalid input format!")
}

确保您的base64编码字符串是有效的。

警告(编辑)

在大多数像Java这样的base64解码实现中,填充字符是不需要的,但如果缺少填充字符,Data(base64Encoded:)会返回nil

Swift 5解决方案; 在执行以下操作后使用String.fromBase64(_:):

extension Data {
    /// Same as ``Data(base64Encoded:)``, but adds padding automatically
    /// (if missing, instead of returning `nil`).
    public static func fromBase64(_ encoded: String) -> Data? {
        // Prefixes padding-character(s) (if needed).
        var encoded = encoded;
        let remainder = encoded.count % 4
        if remainder > 0 {
            encoded = encoded.padding(
                toLength: encoded.count + 4 - remainder,
                withPad: "=", startingAt: 0);
        }

        // Finally, decode.
        return Data(base64Encoded: encoded);
    }
}

extension String {
    public static func fromBase64(_ encoded: String) -> String? {
        if let data = Data.fromBase64(encoded) {
            return String(data: data, encoding: .utf8)
        }
        return nil;
    }
}
如编辑者的个人资料中所述,上述编辑的代码同样允许使用Apache 2.0许可证,无需署名。

11
我尝试了这段代码,但出现以下错误:“fatal error: unexpectedly found nil while unwrapping an Optional value”。如何修复? - Sakthimuthiah
请确保您的 base64Encoded 字符串是有效的,因为问题中的字符串无效。 - nRewik
我有一个包含图像和表格格式数据的Word文档,尝试将该Word文档转换为base64String,编码过程顺利进行,但如果我解码它,会出现“致命错误,发现nil值而无法解包”的错误。在Swift中是否可能对包含图像和表格格式的base64String Word文档进行编码和解码? - Sakthimuthiah
2
@nRewik,请使用 Swift 3。 - Chanchal Raj
此解决方案在末尾添加 = 而不是像注释中那样在前面添加 =。 - coolcool1994

36

Swift扩展非常方便。

extension String {
    func base64Encoded() -> String? {
        return data(using: .utf8)?.base64EncodedString()
    }

    func base64Decoded() -> String? {
        guard let data = Data(base64Encoded: self) else { return nil }
        return String(data: data, encoding: .utf8)
    }
}

"heroes".base64Encoded() // It will return: aGVyb2Vz
"aGVyb2Vz".base64Decoded() // It will return: heroes

15
我已经更新了Ashok Kumar S的回答,当字符串大小不能被4整除时添加填充字符,引发异常并返回nil。
extension String {
func base64Encoded() -> String? {
    return data(using: .utf8)?.base64EncodedString()
}

func base64Decoded() -> String? {
    var st = self;
    if (self.count % 4 <= 2){
        st += String(repeating: "=", count: (self.count % 4))
    }
    guard let data = Data(base64Encoded: st) else { return nil }
    return String(data: data, encoding: .utf8)
}

这就是我需要的! - daxh

7
你可以使用这个扩展来加密/解密base64字符串:
public extension String {


    var base64Decoded: String? {
        guard let decodedData = Data(base64Encoded: self) else { return nil }
        return String(data: decodedData, encoding: .utf8)
    }

    var base64Encoded: String? {
        let plainData = data(using: .utf8)
        return plainData?.base64EncodedString()
    }
}

编码:

"Hello World!".base64Encoded

结果是一个可选字符串:"SGVsbG8gV29ybGQh"

解码方法:

"SGVsbG8gV29ybGQh".base64Decoded

结果是一个可选字符串:"你好,世界!"

来源


5
以上答案是核心内容,但我遇到了以下错误:
fatal error, found nil while unwrapping an optional value

解决方案是添加 options
extension String {
//: ### Base64 encoding a string
    func base64Encoded() -> String? {
        if let data = self.data(using: .utf8) {
            return data.base64EncodedString()
        }
        return nil
    }

//: ### Base64 decoding a string
    func base64Decoded() -> String? {
        if let data = Data(base64Encoded: self, options: .ignoreUnknownCharacters) {
            return String(data: data, encoding: .utf8)
        }
        return nil
    }
}

并安全使用它

var str = "HelloWorld"
if let base64Str = str.base64Encoded() {
    print("Base64 encoded string: \"\(base64Str)\"")
    if let trs = base64Str.base64Decoded() {
        print("Base64 decoded string: \"\(trs)\"")
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接