Swift解压压缩文件并从Gmail API的base64数据中找到xml文件。

问题描述 投票:2回答:1

这个问题是关于在iOS 13中使用SwiftUI和Gmail API的DMARC报告查看器应用。报告是由google以xml格式邮寄到我们的管理员邮箱id,会被压缩。所以基本上它是一个压缩附件。所以在这里,GMail API被用来访问那些特定的邮件,使用过滤器,并从API中得到所有的base64编码数据。同时也将其解码为数据类型的数据。到此为止就可以了。下一部分是将字节格式的zip文件的数据进行解压,并在里面提取出String类型的xml文件。然后我需要对XML进行解析。我想我可以用XMLParser来解析。

问题:如何将压缩文件解压成字节格式?Data 类型,并从中获取xml文件作为 String 类型?

INPUT: String in Base64 format from GMail API fetch (A zip file attachment with only 1 xml file inside)
OUTPUT: String in XML format
PLATFORM: iOS 13/Swift 5.2/SwiftUI/Xcode 11.4
ACTION: 

(INPUT)
base64: String | Decode -> Data
attachment.zip: Data | Decompress -> [Data]
ListOfFiles: [Data] | FirstIndex -> Data
dmarc.xml: Data | ContentOfXML -> String
(OUTPUT)

更新。 我试了一个叫 邮编 而它也失败了。

let path = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
let url = path.appendingPathComponent(messageId+".zip")
do {
    try data.write(to: url)
} catch {
    print("Error while writing: "+error.localizedDescription)
}
do {
    let unzipDirectory = try Zip.quickUnzipFile(url)
    print(unzipDirectory)
} catch let error as NSError {
    print("Error while unzipping: "+error.localizedDescription)
}

该代码导致以下错误

Error while unzipping: The operation couldn’t be completed. (Zip.ZipError error 1.)
ios swift xml gmail-api unzip
1个回答
0
投票

我终于找到了。正如它提到的 参考文献1.邮件正文是用7位US-ASCII数据编码的。所以这也是为什么base64解码不成功的原因。

正如定义在 rfc1341:

编码类型为7BIT,要求正文已经是7位的邮件就绪表示。这是默认值 -- -- 即 "Content-Transfer-Encoding: 如果Content-Transfer-Encoding头域不存在,则假定为 "7BIT"。

在添加了以下内容后,整个代码就可以工作了。

let edata: String = result.data.replacingOccurrences(of: "-", with: "+").replacingOccurrences(of: "_", with: "/")

正如它在 参考文献2它只需要将'-'替换为'+',将'_'替换为'',就可以从gmail api接收到的base64数据。

func getAttachedData(messageId: String, attachmentId: String) {
    decode(self.urlBase+messageId+"/attachments/"+attachmentId+"?"+self.urlKey) { (result: Attachment) in
        let edata: String = result.data.replacingOccurrences(of: "-", with: "+").replacingOccurrences(of: "_", with: "/")
        if let data = Data(base64Encoded: edata, options: .ignoreUnknownCharacters) {
            let filemanager = FileManager.default
            let path = try! filemanager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
            let url = path.appendingPathComponent(messageId+".zip")
            do {
                try data.write(to: url)
            } catch {
                print("Error while writing: "+error.localizedDescription)
            }
            do {
                let unzipDirectory = try Zip.quickUnzipFile(url)
                print("Unzipped")
                do {
                    let filelist = try filemanager.contentsOfDirectory(at: unzipDirectory, includingPropertiesForKeys: [], options: [])

                    for filename in filelist {
                        print(filename.lastPathComponent)
                        print(filename.relativeString)
                        do {
                            let text = try String(contentsOf: filename, encoding: .utf8)
                            print(text)
                            DispatchQueue.main.async {
                                self.attachments.append(text)
                            }
                        } catch let error as NSError {
                            print("Error: \(error.localizedDescription)")
                        }
                    }
                } catch let error {
                    print("Error: \(error.localizedDescription)")
                }
            } catch let error as NSError {
                print("Error while unzipping: "+error.localizedDescription)
            }
        }
    }
}

参考文献1: https:/stackoverflow.coma585907592382813

参考文献2: https:/stackoverflow.coma249864522382813

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