我可以制作一个Facebook SDK图形请求以获得用户的喜欢,但是我在获取返回的值并将其中一个键存储在一个字符串数组中时遇到了麻烦。请求返回键/值的NSDictionary。然后,使用objectForKey
我可以获得data
键,它返回我想要的内容:"喜欢"的ID和名称。 Facebook上的页面。
数据会返回如下元素:
{
id = 486379781543416;
name = "Star Wars Movies";
},
我特别想要" name"所有这些对象并将它们放入数组[String]
中。我试图遍历对象,但我收到错误ambiguous use of subscript
。这是相关代码:
request.startWithCompletionHandler{(connection:FBSDKGraphRequestConnection!, result:AnyObject!, error:NSError!) -> Void in
let resultdict = result as! NSDictionary
let likes = resultdict.objectForKey("data") as! NSArray
print("Found \(likes.count) likes")
print(likes)
for object in likes{
let name = object["name"] as! String //error: ambiguous use of subsript
print(name)
}
}
在做了一些研究后,看起来问题出在NSArray上,而我应该使用Swift数据类型。我尝试将它转换为Swift数组,但是我遇到了不同的错误。
处理此错误的最佳方法是什么?
谢谢!
更新:这是facebook API请求返回的内容:
{
data = (
{
id = 111276025563005;
name = "Star Wars (film)";
},
{
id = 115061321839188;
name = "Return of the Jedi";
}
);
paging = {
cursors = {
after = MTE1MDYxMzIxODM5MTg4;
before = Mjc0NzYzODk2MTg4NjY5;
};
next = "https://graph.facebook.com/v2.5/10155262562690368/likes?access_token=<redacted>";
};
}
答案 0 :(得分:1)
您应该始终尽可能使用本机Swift集合类型,因为NSArray
和NSDictionary
实际上是类型特定的,因此可以轻松触发“模糊使用下标”错误。
如果您收到格式错误的数据或根本没有数据,您还需要避免强制转发。使用guard
可以更优雅地处理这种情况,以防止崩溃。如果您的程序依赖于强制转发成功,因此应该崩溃 - 那么您始终可以使用描述性错误消息在警卫中调用fatalError
为了帮助您调试问题。
如果我正确理解了您的数据结构,请求将返回一个AnyObject
,它应该是[String:AnyObject]
(任何对象的字符串字典)。对于"data"
键,AnyObject
值为[[String:AnyObject]]
(任意对象的字符串字典数组)。
因此,您需要分两个阶段进行演员表演。首先,在result
上使用条件向下广播将其转换为[String:AnyObject]
。如果失败,那么将执行guard的else子句并返回代码。然后,您需要获取"data"
值(您的“喜欢”数组),并有条件地将其转发为[[String:AnyObject]]
。这两个陈述都将处理resultDict
或resultDict["data"]
为nil
的可能性。
guard let resultDict = result as? [String:AnyObject] else {return}
guard let likes = resultDict["data"] as? [[String:AnyObject]] else {return}
您可以在这些语句的括号中放置您想要的任何错误处理逻辑,以处理结果字典不存在,格式错误或者其中没有“likes”数组的情况。 / p>
然后,您可以使用flatMap
获取一系列“赞”名称。
let likeNames = likes.flatMap{$0["name"] as? String}
这将创建每个字典的相似名称的数组 - 如果相同的名称不存在或不是字符串,则不会添加它们。因为编译器知道某些 likes
是[[String:AnyObject]]
- 所以在订阅其元素时没有歧义。
如果你想要一个更通用的方法,比如你在问题中做的那样,你可以在for循环中使用一个guard语句。
for object in likes {
guard let name = object["name"] as? String else {continue}
print(name)
}
同样,您可以将任何错误处理放在警卫的括号内。