【发布时间】:2017-09-02 09:04:00
【问题描述】:
【问题讨论】:
标签: ios xml swift uiimage base64
【问题讨论】:
标签: ios xml swift uiimage base64
首先您需要解析 XML。在 iOS 上没有 NSXML,因此您需要使用 NSXMLParser,它是一个原始的事件驱动回调解析器(与您可以在 macOS 中使用的复杂树解析器相对)。
让我们定义一些示例数据:
let xmlString =
"<base64Binary xmlns=\"TestTestTest\">"
+ "/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAA0JCgsKCA0LCgsODg0PEyAVExIS"
+ "EyccHhcgLikxMC4pLSwzOko+MzZGNywtQFdBRkxOUlNSMj5aYVpQYEpRUk//"
+ "2wBDAQ4ODhMREyYVFSZPNS01T09PT09PT09PT09PT09PT09PT09PT09PT09P"
+ "T09PT09PT09PT09PT09PT09PT09PT0//wAARCABAABwDASIAAhEBAxEB/8QA"
+ "GgAAAgMBAQAAAAAAAAAAAAAAAwUCBAYAAf/EACwQAAIBAwMCBAUFAAAAAAAA"
+ "AAECAwAEEQUSITFBBiJhcRMUUYGhFSNCkeH/xAAXAQEBAQEAAAAAAAAAAAAA"
+ "AAADAgQA/8QAHREAAgICAwEAAAAAAAAAAAAAAAECERIhAyIxMv/aAAwDAQAC"
+ "EQMRAD8AvWMQkSViFbaRkkZ4+g9aJeJbwMIljJmZN6ozEZHrQI5JYLOL4UbF"
+ "jJlwnHOKSyzXqssLi4AUnDMd+RnPLVlXZWy4RWKbGuzdOUjJQdSM5xRBa4/n"
+ "n3ryxKmzExBy/JzQpZiX8r4FZnJ3oAPO7LYwrErOXGSR0J/yluq6o1rGlogX"
+ "LKN8mOc0y0hwmlQNu3B5n69qz/iONWmYgg4PIBzitS8Rr49xLBl1aOHBMLBw"
+ "duDnaO3vRbdLiSFXlwWPeu0lhc2aI+d6DB+9WN6W5Ma9BRzlTxSAl6TMgt7a"
+ "3gbyg7nH0znmkGqXSSXDq7qiHqc9a0fiNYJLG1eNCFdyntwax8ypIyI0Y3gY"
+ "3Y6U1V6PD50PtIjYQtMysgY5QHrt7E1NkLOSS3Jplo8lvdaahuR+7H5HI4yR"
+ "0P3FW/k7N+cfmpfE27AknYqvJIv0KNpD543O30Oazb2N2WNwhBHOUzzj61qv"
+ "EdlKbyxt3SZkLbpBFFlQPccZ96OYkaN3RSSQdoaEDnHApFBl50kkIfD1yZpZ"
+ "o1cKAg3AnvmmLSOGI+J/RoPh6xayaVb3Tpd85DBgQdqjsefc0+e1swxAtM+u"
+ "7r+a7CTJm7Z//9k="
+ "</base64Binary>"
现在让我们解析一下。因此,我们需要一个原始委托,如下所示:
/// Extracts the content of the first <bas64Binary> tag in the XML
class Base64BinaryExtractor: NSObject, XMLParserDelegate {
private var active: Bool = false
var base64String: String? = nil
func parser (
_ parser: XMLParser,
didStartElement elementName: String,
namespaceURI: String?,
qualifiedName qName: String?,
attributes attributeDict: [String : String] = [:]
)
{
// We must not have a string yet
guard self.base64String == nil else {
// If we do, this is a second <bas64Binary> tag or
// it's a tag within a tag. We ingore both.
self.active = false
return
}
// We only care for "<base64Binary>"
guard elementName == "base64Binary" else { return }
// Time to collect the string
self.active = true
self.base64String = ""
}
func parser (
_ parser: XMLParser,
didEndElement elementName: String,
namespaceURI: String?,
qualifiedName qName: String?
)
{
// No matter what element, no matter if we were active,
// we are not active anymore once any tag ends.
self.active = false
}
func parser (
_ parser: XMLParser,
foundCharacters string: String
)
{
// Ignore everything unless we are active
guard self.active else { return }
self.base64String!.append(string)
}
}
然后实际的解析只是将字符串转换为数据,设置解析器,设置委托并使其运行:
let xmlData = xmlString.data(using: .utf8)
// TODO: Check xmlData being nil and handle that!
let parser = XMLParser(data: xmlData!)
let delegate = Base64BinaryExtractor()
parser.delegate = delegate
let parseOK = parser.parse()
// TODO: Check parseOK and handle if not!
// TODO: Check delegate.base64String being nil and handle!
现在您需要做的就是将 base64 解码为原始数据并从中制作图像:
let rawData = Data(base64Encoded: delegate.base64String!)
// TODO: Check raw data being nil (bad base64!) and hanlde that!
let image = UIImage(data: rawData!)
上面的代码假设rawData包含iOS已知的图像格式的数据(例如PNG、JPEG、TIFF)如果不是这种情况,则需要转换格式,可能使用外部图像库来处理它。
作为奖励,这里有两个关于 StackOverflow 未来问题的宝贵提示:
始终提供示例数据。截图并没有删减它,因为我不能用它来测试示例代码。示例数据对试图帮助您的人有很大帮助,因此您将获得更多、更好的答案,如果您提供示例数据,您将更快地获得答案。
将复杂问题分解为更小的子问题,然后对每个子问题提出一个问题,而不是创建复杂的“涵盖所有内容”的问题,这大大增加了您获得快速准确答复的机会。这也是开发软件的方式:分而治之。把大问题转化为小问题,一次解决一个子问题,如果你把它们都解决了,那么你也把复杂的问题作为一个整体解决了。例如。这个问题可以分解为三个子问题:
【讨论】: