我正在尝试在 Swift 中实现 NSXMLParserDelegate,但我在某些委托(delegate)方法中使用属性字典时遇到问题。例如,在 parser:didStartElement:
:
func parser(parser: NSXMLParser!, didStartElement elementName: String!, namespaceURI: String!, qualifiedName qName: String!, attributes attributeDict: [NSObject : AnyObject]!) {
尝试访问 attributeDict 值,例如:
if self.feedType == FeedType.RSS {
self.insideLink = true
} else {
if (String(attributeDict["rel"]) == "alternate") && (String(attributeDict["type"]) == "text/html") {
self.link = String(attributeDict["href"])
self.insideLink = false
self.doneWithLink = true
}
}
我收到一条错误消息:“'String' 无法转换为 'FeedType'”。
enum FeedType:String {
case ATOM = "feed"
case RSS = "rss"
}
class FeedParser:NSObject, NSXMLParserDelegate {
var feedType:FeedType?
是一个错误。该主题的其他十几个变体也是如此……有什么见解吗?
我想问题是如何正确使用 attributeDict
中类型为 [NSObject: AnyObject]
的键/值对?
最佳答案
看起来您可能收到虚假错误消息:我建议 filing a bug .
I guess the question is how to properly use the key / value pairs in
attributeDict
which are of type[NSObject: AnyObject]
你是对的:这看起来像是问题的根源。解决方案不是构建 String
从字典查找,但要(有条件地)cast 到 String
.也就是说,而不是尝试创建一个新的 String
来自不确定(和可选)类型的引用,询问 Swift 该引用是否实际上是可以解释为 String
的东西:
let rel = attributeDict["rel"] as? String
这让你成为一个可选的,因为 attributeDict
可能不包含键值 rel
,并且因为条件转换可能会失败( attributeDict["rel"]
可能是不同类型的值)。因为您需要检查两个条件转换及其解包值,所以您最终可能会遇到很多强制解包运算符 ( !
) 或深层嵌套 if-let
block ...那会很快变得丑陋。
相反,您可以利用 Optional
是一个枚举。它的定义看起来像这样:
enum Optional<T> {
case None // aka nil
case Some(T) // what you get when you unwrap a non-nil optional
}
这样,您就可以使用模式匹配来安全简洁地进行查找、转换、解包和测试:
switch (attributeDict["rel"] as? String, attributeDict["type"] as? String) {
case let (.Some(rel), .Some(type)) where rel == "alternate" && type == "text/html":
// harvest link
default:
// no match... fall back to other behavior, log an error, etc
}
请注意,在“收获链接”步骤中,您仍然需要有条件地转换和解包 attributeDict["href"]
抬头。您可以通过嵌套 if-let
来做到这一点在那里 build case
,或通过向 switch
添加第三次查找元组。
顺便说一句,所有self.
在 Swift 中不需要符号(除非您处于闭包中或需要从实例属性中消除方法参数的歧义)。
关于ios - Swift 问题中的 NSXMLDelegate,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25020246/